diff --git a/Framework/API/CMakeLists.txt b/Framework/API/CMakeLists.txt
index bb154bdc59b41abec9ca39a978ec6701695c596a..aabd85cc6cee8326e244834b5f2a4a5de15512d4 100644
--- a/Framework/API/CMakeLists.txt
+++ b/Framework/API/CMakeLists.txt
@@ -88,6 +88,7 @@ set ( SRC_FILES
 	src/LatticeDomain.cpp
 	src/LinearScale.cpp
 	src/LiveListenerFactory.cpp
+	src/LogFilterGenerator.cpp
 	src/LogManager.cpp
 	src/LogarithmScale.cpp
 	src/MDGeometry.cpp
@@ -101,6 +102,7 @@ set ( SRC_FILES
 	src/MultipleExperimentInfos.cpp
 	src/MultipleFileProperty.cpp
 	src/NearestNeighbourInfo.cpp
+	src/NearestNeighbours.cpp
 	src/NotebookBuilder.cpp
 	src/NotebookWriter.cpp
 	src/NullCoordTransform.cpp
@@ -112,6 +114,7 @@ set ( SRC_FILES
 	src/PeakFunctionIntegrator.cpp
 	src/Progress.cpp
 	src/Projection.cpp
+	src/PropertyWithValue.cpp
 	src/RawCountValidator.cpp
 	src/RefAxis.cpp
 	src/RemoteJobManagerFactory.cpp
@@ -271,6 +274,7 @@ set ( INC_FILES
 	inc/MantidAPI/LatticeDomain.h
 	inc/MantidAPI/LinearScale.h
 	inc/MantidAPI/LiveListenerFactory.h
+	inc/MantidAPI/LogFilterGenerator.h
 	inc/MantidAPI/LogManager.h
 	inc/MantidAPI/LogarithmScale.h
 	inc/MantidAPI/MDGeometry.h
@@ -286,6 +290,7 @@ set ( INC_FILES
 	inc/MantidAPI/MultipleExperimentInfos.h
 	inc/MantidAPI/MultipleFileProperty.h
 	inc/MantidAPI/NearestNeighbourInfo.h
+        inc/MantidAPI/NearestNeighbours.h
 	inc/MantidAPI/NotebookBuilder.h
 	inc/MantidAPI/NotebookWriter.h
 	inc/MantidAPI/NullCoordTransform.h
@@ -326,6 +331,7 @@ set ( INC_FILES
 	inc/MantidAPI/WorkspaceHistory.h
 	inc/MantidAPI/WorkspaceOpOverloads.h
 	inc/MantidAPI/WorkspaceProperty.h
+	inc/MantidAPI/WorkspaceProperty.tcc
 	inc/MantidAPI/WorkspaceUnitValidator.h
 	inc/MantidAPI/Workspace_fwd.h
 )
@@ -388,6 +394,7 @@ set ( TEST_FILES
 	InstrumentValidatorTest.h
 	LatticeDomainTest.h
 	LiveListenerFactoryTest.h
+	LogFilterGeneratorTest.h
 	LogManagerTest.h
 	MDGeometryTest.h
 	MatrixWorkspaceMDIteratorTest.h
@@ -399,6 +406,7 @@ set ( TEST_FILES
 	MultipleExperimentInfosTest.h
 	MultipleFilePropertyTest.h
 	NearestNeighbourInfoTest.h
+	NearestNeighboursTest.h
 	NotebookBuilderTest.h
 	NotebookWriterTest.h
 	NumericAxisTest.h
diff --git a/Framework/API/inc/MantidAPI/DetectorInfo.h b/Framework/API/inc/MantidAPI/DetectorInfo.h
index 850eb4e37fd11ac0d880c5551f5dcf79e637d64e..1a949421085e4f2568831ce2c2dd122c0c0d3b59 100644
--- a/Framework/API/inc/MantidAPI/DetectorInfo.h
+++ b/Framework/API/inc/MantidAPI/DetectorInfo.h
@@ -13,6 +13,9 @@
 
 namespace Mantid {
 using detid_t = int32_t;
+namespace Beamline {
+class DetectorInfo;
+}
 namespace Geometry {
 class IComponent;
 class IDetector;
@@ -30,8 +33,10 @@ class SpectrumInfo;
   DetectorInfo provides easy access to commonly used parameters of individual
   detectors, such as mask and monitor flags, L1, L2, and 2-theta.
 
-  This class is thread safe with OpenMP BUT NOT WITH ANY OTHER THREADING LIBRARY
-  such as Poco threads or Intel TBB.
+  This class is thread safe for read operations (const access) with OpenMP BUT
+  NOT WITH ANY OTHER THREADING LIBRARY such as Poco threads or Intel TBB. There
+  are no thread-safety guarantees for write operations (non-const access). Reads
+  concurrent with writes or concurrent writes are not allowed.
 
 
   @author Simon Heybrock
@@ -60,9 +65,14 @@ class SpectrumInfo;
 */
 class MANTID_API_DLL DetectorInfo {
 public:
-  DetectorInfo(boost::shared_ptr<const Geometry::Instrument> instrument,
+  DetectorInfo(Beamline::DetectorInfo &detectorInfo,
+               boost::shared_ptr<const Geometry::Instrument> instrument,
                Geometry::ParameterMap *pmap = nullptr);
 
+  DetectorInfo &operator=(const DetectorInfo &rhs);
+
+  size_t size() const;
+
   bool isMonitor(const size_t index) const;
   bool isMasked(const size_t index) const;
   double l2(const size_t index) const;
@@ -71,12 +81,17 @@ public:
   Kernel::V3D position(const size_t index) const;
   Kernel::Quat rotation(const size_t index) const;
 
+  void setMasked(const size_t index, bool masked);
+  void clearMaskFlags();
+
   void setPosition(const size_t index, const Kernel::V3D &position);
   void setRotation(const size_t index, const Kernel::Quat &rotation);
 
   void setPosition(const Geometry::IComponent &comp, const Kernel::V3D &pos);
   void setRotation(const Geometry::IComponent &comp, const Kernel::Quat &rot);
 
+  const Geometry::IDetector &detector(const size_t index) const;
+
   // This does not really belong into DetectorInfo, but it seems to be useful
   // while Instrument-2.0 does not exist.
   Kernel::V3D sourcePosition() const;
@@ -85,6 +100,7 @@ public:
 
   const std::vector<detid_t> &detectorIDs() const;
   /// Returns the index of the detector with the given detector ID.
+  /// This will throw an out of range exception if the detector does not exist.
   size_t indexOf(const detid_t id) const { return m_detIDToIndex.at(id); }
 
   friend class SpectrumInfo;
@@ -108,6 +124,9 @@ private:
   void doCacheSample() const;
   void cacheL1() const;
 
+  /// Reference to the actual DetectorInfo object (non-wrapping part).
+  Beamline::DetectorInfo &m_detectorInfo;
+
   Geometry::ParameterMap *m_pmap;
   boost::shared_ptr<const Geometry::Instrument> m_instrument;
   std::vector<detid_t> m_detectorIDs;
diff --git a/Framework/API/inc/MantidAPI/ExperimentInfo.h b/Framework/API/inc/MantidAPI/ExperimentInfo.h
index cd7a85e8171a4775e000dfdb7a625989f830139b..62956b8caca1ff8c58ea2469bc1feb0822f81958 100644
--- a/Framework/API/inc/MantidAPI/ExperimentInfo.h
+++ b/Framework/API/inc/MantidAPI/ExperimentInfo.h
@@ -16,6 +16,9 @@ namespace Mantid {
 namespace Kernel {
 class Property;
 }
+namespace Beamline {
+class DetectorInfo;
+}
 namespace Geometry {
 class ParameterMap;
 class XMLInstrumentParameter;
@@ -67,16 +70,13 @@ public:
   // Add parameters to the instrument parameter map
   virtual void populateInstrumentParameters();
 
-  /// Replaces current parameter map with copy of given map
   virtual void replaceInstrumentParameters(const Geometry::ParameterMap &pmap);
-  /// exchange contents of current parameter map with contents of other map)
   virtual void swapInstrumentParameters(Geometry::ParameterMap &pmap);
 
   /// Cache a lookup of grouped detIDs to member IDs
   virtual void cacheDetectorGroupings(const det2group_map &mapping);
   /// Returns the detector IDs that make up the group that this ID is part of
-  virtual const std::vector<detid_t> &
-  getGroupMembers(const detid_t detID) const;
+  virtual const std::set<detid_t> &getGroupMembers(const detid_t detID) const;
   /// Get a detector or detector group from an ID
   virtual Geometry::IDetector_const_sptr
   getDetectorByID(const detid_t detID) const;
@@ -162,6 +162,9 @@ public:
   const DetectorInfo &detectorInfo() const;
   DetectorInfo &mutableDetectorInfo();
 
+  virtual size_t numberOfDetectorGroups() const;
+  virtual const std::set<detid_t> &detectorIDsInGroup(const size_t index) const;
+
 protected:
   /// Called when instrument or parameter map is reset to notify child classes.
   virtual void invalidateInstrumentReferences() const {}
@@ -201,11 +204,16 @@ private:
   // Loads the xml from an instrument file with some basic error handling
   std::string loadInstrumentXML(const std::string &filename);
   /// Detector grouping information
-  det2group_map m_detgroups;
+  mutable std::vector<std::set<detid_t>> m_detgroups;
+  mutable std::unordered_map<detid_t, size_t> m_det2group;
+  void cacheDefaultDetectorGrouping() const; // Not thread-safe
+  mutable std::once_flag m_defaultDetectorGroupingCached;
+
   /// Mutex to protect against cow_ptr copying
   mutable std::recursive_mutex m_mutex;
 
-  mutable std::unique_ptr<DetectorInfo> m_detectorInfo;
+  boost::shared_ptr<Beamline::DetectorInfo> m_detectorInfo;
+  mutable std::unique_ptr<DetectorInfo> m_detectorInfoWrapper;
   mutable std::mutex m_detectorInfoMutex;
 };
 
diff --git a/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h b/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h
index 82e71fb43e54e5c082fe435485756d92558f95b9..764631e3975a7dc04fbd18127a60ad917675d6a2 100644
--- a/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h
+++ b/Framework/API/inc/MantidAPI/FileBackedExperimentInfo.h
@@ -60,8 +60,7 @@ public:
 
   void cacheDetectorGroupings(const det2group_map &mapping) override;
 
-  const std::vector<detid_t> &
-  getGroupMembers(const detid_t detID) const override;
+  const std::set<detid_t> &getGroupMembers(const detid_t detID) const override;
 
   Geometry::IDetector_const_sptr
   getDetectorByID(const detid_t detID) const override;
@@ -97,6 +96,10 @@ public:
 
   void setEFixed(const detid_t detID, const double value) override;
 
+  size_t numberOfDetectorGroups() const override;
+  const std::set<detid_t> &
+  detectorIDsInGroup(const size_t index) const override;
+
 private:
   void populateIfNotLoaded() const;
   void populateFromFile() const;
diff --git a/Framework/API/inc/MantidAPI/FunctionDomain1D.h b/Framework/API/inc/MantidAPI/FunctionDomain1D.h
index 8db1c56b83cb02be26097677633f0b41dd02521d..b1482e0b667f87ea67dff99034c4478c115283ff 100644
--- a/Framework/API/inc/MantidAPI/FunctionDomain1D.h
+++ b/Framework/API/inc/MantidAPI/FunctionDomain1D.h
@@ -59,11 +59,15 @@ public:
   const double *getPointerAt(size_t i) const { return m_data + i; }
   /// Convert to a vector
   std::vector<double> toVector() const;
+  /// Set a peak redius to pass to peak functions.
+  void setPeakRadius(int radius);
+  /// Get the peak radius.
+  int getPeakRadius() const;
 
 protected:
   /// Protected constructor, shouldn't be created directly. Use
   /// FunctionDomain1DView instead.
-  FunctionDomain1D(const double *x, size_t n) : m_data(x), m_n(n) {}
+  FunctionDomain1D(const double *x, size_t n);
   /// Reset the pointer and size of the domain
   void resetData(const double *x, size_t n) {
     m_data = x;
@@ -71,8 +75,12 @@ protected:
   }
 
 private:
-  const double *m_data; ///< pointer to the start of the domain data
-  size_t m_n;           ///< size of the data
+  /// pointer to the start of the domain data
+  const double *m_data;
+  /// size of the data
+  size_t m_n;
+  /// A peak radius that IPeakFunctions should use
+  int m_peakRadius;
 };
 
 /**
diff --git a/Framework/API/inc/MantidAPI/FunctionValues.h b/Framework/API/inc/MantidAPI/FunctionValues.h
index 115645a16a40f4694f739504fdf497b25a77bfbe..de5cbba735743be3297cdbff926b3ff9be951b04 100644
--- a/Framework/API/inc/MantidAPI/FunctionValues.h
+++ b/Framework/API/inc/MantidAPI/FunctionValues.h
@@ -112,11 +112,12 @@ protected:
   /// buffer
   /// @param to :: Pointer to the buffer, it must be large enough
   void multiply(double *to) const;
-
-  std::vector<double> m_calculated; ///< buffer for calculated values
-  std::vector<double> m_data;       ///< buffer for fit data
-  std::vector<double>
-      m_weights; ///< buffer for fitting weights (reciprocal errors)
+  /// buffer for calculated values
+  std::vector<double> m_calculated;
+  /// buffer for fit data
+  std::vector<double> m_data;
+  /// buffer for fitting weights (reciprocal errors)
+  std::vector<double> m_weights;
 };
 
 /// typedef for a shared pointer
diff --git a/Framework/API/inc/MantidAPI/IFunction1D.h b/Framework/API/inc/MantidAPI/IFunction1D.h
index a84af386955e4be6786aff59123697df2afcc19d..e4fb9302f2543e26a71c4d50fbe8cfecb338b0a8 100644
--- a/Framework/API/inc/MantidAPI/IFunction1D.h
+++ b/Framework/API/inc/MantidAPI/IFunction1D.h
@@ -62,11 +62,11 @@ public:
 
   void function(const FunctionDomain &domain,
                 FunctionValues &values) const override;
+  void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override;
+
   virtual void derivative(const FunctionDomain &domain, FunctionValues &values,
                           const size_t order = 1) const;
 
-  void functionDeriv(const FunctionDomain &domain, Jacobian &jacobian) override;
-
   /// Function you want to fit to.
   virtual void function1D(double *out, const double *xValues,
                           const size_t nData) const = 0;
diff --git a/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Framework/API/inc/MantidAPI/IMDWorkspace.h
index c13df5c17cb92d4e2838385941af86f8d9f70f88..c851452446b44da13d4f0c99be444f508a32c747 100644
--- a/Framework/API/inc/MantidAPI/IMDWorkspace.h
+++ b/Framework/API/inc/MantidAPI/IMDWorkspace.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/ITableWorkspace_fwd.h"
 #include "MantidAPI/MDGeometry.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidKernel/SpecialCoordinateSystem.h"
 #include <cstdint>
 #include <vector>
 
diff --git a/Framework/API/inc/MantidAPI/IPeakFunction.h b/Framework/API/inc/MantidAPI/IPeakFunction.h
index c5725c8ce59a44609f1e3f76f6a3d93872a23e2f..3636919b41686ed772c00792659cea37e199d881 100644
--- a/Framework/API/inc/MantidAPI/IPeakFunction.h
+++ b/Framework/API/inc/MantidAPI/IPeakFunction.h
@@ -39,6 +39,10 @@ class MANTID_API_DLL IPeakFunction : public IFunctionWithLocation {
 public:
   /// Constructor
   IPeakFunction();
+
+  void function(const FunctionDomain &domain,
+                FunctionValues &values) const override;
+
   /// Returns the peak FWHM
   virtual double fwhm() const = 0;
 
@@ -57,8 +61,11 @@ public:
   /// General implementation of the method for all peaks.
   void functionDeriv1D(Jacobian *out, const double *xValues,
                        const size_t nData) override;
-  /// Set new peak radius
-  static void setPeakRadius(const int &r = 5);
+
+  /// Get the interval on which the peak has all its values above a certain
+  /// level
+  virtual std::pair<double, double>
+  getDomainInterval(double level = DEFAULT_SEARCH_LEVEL) const;
 
   /// Function evaluation method to be implemented in the inherited classes
   virtual void functionLocal(double *out, const double *xValues,
@@ -83,10 +90,14 @@ public:
         "Generic intensity fixing isn't implemented for this function.");
   }
 
-protected:
+private:
+  /// Set new peak radius
+  void setPeakRadius(int r) const;
   /// Defines the area around the centre where the peak values are to be
   /// calculated (in FWHM).
-  static int s_peakRadius;
+  mutable int m_peakRadius;
+  /// The default level for searching a domain interval (getDomainInterval())
+  static constexpr double DEFAULT_SEARCH_LEVEL = 1e-5;
 };
 
 typedef boost::shared_ptr<IPeakFunction> IPeakFunction_sptr;
diff --git a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
index d9d752943c27d5d35c02bcdcb77ea54b02f8a1a3..c9c0cedae08467bb3d730a42d180f906d6316a1b 100644
--- a/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
+++ b/Framework/API/inc/MantidAPI/IPowderDiffPeakFunction.h
@@ -1,12 +1,10 @@
 #ifndef MANTID_API_IPOWDERDIFFPEAKFUNCTION_H_
 #define MANTID_API_IPOWDERDIFFPEAKFUNCTION_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/ParamFunction.h"
 #include "MantidAPI/IFunction1D.h"
 #include "MantidGeometry/Crystal/UnitCell.h"
+#include <complex>
 
 namespace Mantid {
 namespace API {
diff --git a/Framework/API/inc/MantidAPI/LiveListenerFactory.h b/Framework/API/inc/MantidAPI/LiveListenerFactory.h
index 585c40015e3bcc0d703aa25dca64fca477cd01bf..aab4a9157ab35cf7735562b89bec2da838ab05cf 100644
--- a/Framework/API/inc/MantidAPI/LiveListenerFactory.h
+++ b/Framework/API/inc/MantidAPI/LiveListenerFactory.h
@@ -24,6 +24,7 @@
 #include "MantidKernel/DynamicFactory.h"
 #include "MantidKernel/SingletonHolder.h"
 #include "MantidAPI/ILiveListener.h"
+#include "MantidKernel/LiveListenerInfo.h"
 
 namespace Mantid {
 namespace API {
@@ -51,11 +52,16 @@ class MANTID_API_DLL LiveListenerFactoryImpl
     : public Kernel::DynamicFactory<ILiveListener> {
 public:
   boost::shared_ptr<ILiveListener>
-  create(const std::string &instrumentName, bool connect,
+  create(const std::string &instrumentName, bool connect = false,
+         const Kernel::IPropertyManager *properties = nullptr,
+         const std::string &listenerConnectionName = "") const;
+
+  boost::shared_ptr<ILiveListener>
+  create(const Kernel::LiveListenerInfo &info, bool connect = false,
          const Kernel::IPropertyManager *properties = nullptr) const;
+
   LiveListenerFactoryImpl(const LiveListenerFactoryImpl &) = delete;
   LiveListenerFactoryImpl &operator=(const LiveListenerFactoryImpl &) = delete;
-  bool checkConnection(const std::string &instrumentName) const;
 
 private:
   friend struct Kernel::CreateUsingNew<LiveListenerFactoryImpl>;
diff --git a/Framework/API/inc/MantidAPI/LogFilterGenerator.h b/Framework/API/inc/MantidAPI/LogFilterGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..c96124ff111f7ba7599cdfd1a9c6a532d7cecc85
--- /dev/null
+++ b/Framework/API/inc/MantidAPI/LogFilterGenerator.h
@@ -0,0 +1,72 @@
+#ifndef MANTID_API_LOGFILTERGENERATOR_H_
+#define MANTID_API_LOGFILTERGENERATOR_H_
+
+#include "MantidAPI/DllConfig.h"
+#include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/Run.h"
+#include "MantidKernel/LogFilter.h"
+#include "MantidKernel/Property.h"
+#include <memory>
+
+namespace Mantid {
+namespace API {
+
+/** LogFilterGenerator : utility to generate a LogFilter, to filter by running
+  status or period
+
+  This was refactored out of MantidUI::importNumSeriesLog
+
+  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 MANTID_API_DLL LogFilterGenerator {
+public:
+  /// Types of filter that can be used
+  enum class FilterType { None, Status, Period, StatusAndPeriod };
+
+  /// Constructor taking workspace
+  LogFilterGenerator(const FilterType filterType,
+                     const Mantid::API::MatrixWorkspace_const_sptr &workspace);
+
+  /// Constructor taking run object
+  LogFilterGenerator(const FilterType filterType, const Mantid::API::Run &run);
+
+  /// Generate log filter from given workspace and log name
+  std::unique_ptr<Mantid::Kernel::LogFilter>
+  generateFilter(const std::string &logName) const;
+
+private:
+  /// Filter log by "running" status
+  void filterByStatus(Mantid::Kernel::LogFilter *filter) const;
+  /// Filter log by period
+  void filterByPeriod(Mantid::Kernel::LogFilter *filter) const;
+  /// Get log data from workspace
+  Mantid::Kernel::Property *getLogData(const std::string &logName) const;
+  /// Type of filter
+  const FilterType m_filterType;
+  /// Run object containing logs
+  const Mantid::API::Run m_run;
+};
+
+} // namespace API
+} // namespace Mantid
+
+#endif /* MANTID_API_LOGFILTERGENERATOR_H_ */
\ No newline at end of file
diff --git a/Framework/API/inc/MantidAPI/LogManager.h b/Framework/API/inc/MantidAPI/LogManager.h
index 40dafc25508edfa303a227fd3af62974ce278288..23d3789cef19e4d739e9771ad892f5d446cc1a81 100644
--- a/Framework/API/inc/MantidAPI/LogManager.h
+++ b/Framework/API/inc/MantidAPI/LogManager.h
@@ -2,11 +2,10 @@
 #define MANTID_API_LOGMANAGER_H_
 
 #include "MantidAPI/DllConfig.h"
-#include "MantidKernel/Cache.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/PropertyManager.h"
 #include "MantidKernel/Statistics.h"
-#include "MantidKernel/TimeSplitter.h"
+#include <memory>
 #include <vector>
 
 namespace NeXus {
@@ -15,7 +14,10 @@ class File;
 
 namespace Mantid {
 namespace Kernel {
+template <class KEYTYPE, class VALUETYPE> class Cache;
 template <typename TYPE> class TimeSeriesProperty;
+class SplittingInterval;
+typedef std::vector<SplittingInterval> TimeSplitterType;
 }
 
 namespace API {
@@ -50,9 +52,12 @@ namespace API {
 */
 class MANTID_API_DLL LogManager {
 public:
+  LogManager();
+  LogManager(const LogManager &other);
   /// Destructor. Doesn't need to be virtual as long as nothing inherits from
   /// this class.
-  virtual ~LogManager() = default;
+  virtual ~LogManager();
+  LogManager &operator=(const LogManager &other);
 
   //-------------------------------------------------------------
   /// Set the run start and end
@@ -194,11 +199,10 @@ protected:
   static const char *PROTON_CHARGE_LOG_NAME;
 
 private:
-  /// Cache type for single value logs
-  typedef Kernel::Cache<std::pair<std::string, Kernel::Math::StatisticType>,
-                        double> SingleValueCache;
   /// Cache for the retrieved single values
-  mutable SingleValueCache m_singleValueCache;
+  std::unique_ptr<Kernel::Cache<
+      std::pair<std::string, Kernel::Math::StatisticType>, double>>
+      m_singleValueCache;
 };
 /// shared pointer to the logManager base class
 typedef boost::shared_ptr<LogManager> LogManager_sptr;
diff --git a/Framework/API/inc/MantidAPI/MDGeometry.h b/Framework/API/inc/MantidAPI/MDGeometry.h
index cb11fc65e3758eef7f09503d570178991a5e6e15..f8d15c5cbbcc0d41af92bb62706c3bccf384a964 100644
--- a/Framework/API/inc/MantidAPI/MDGeometry.h
+++ b/Framework/API/inc/MantidAPI/MDGeometry.h
@@ -2,16 +2,22 @@
 #define MANTID_API_MDGEOMETRY_H_
 
 #include "MantidKernel/System.h"
+#include "MantidKernel/Matrix.h"
 #include "MantidKernel/VMD.h"
-#include "MantidGeometry/MDGeometry/IMDDimension.h"
-#include "MantidAPI/AnalysisDataService.h"
-#include <Poco/NObserver.h>
+#include "MantidGeometry/MDGeometry/MDTypes.h"
 #include <boost/shared_ptr.hpp>
 
+#include <memory>
+
 namespace Mantid {
+namespace Geometry {
+class IMDDimension;
+}
 namespace API {
 class CoordTransform;
 class IMDWorkspace;
+class MDGeometryNotificationHelper;
+class Workspace;
 
 /** Describes the geometry (i.e. dimensions) of an IMDWorkspace.
  * This defines the dimensions contained in the workspace.
@@ -48,8 +54,8 @@ public:
   MDGeometry();
   MDGeometry(const MDGeometry &other);
   virtual ~MDGeometry();
-  void
-  initGeometry(std::vector<Mantid::Geometry::IMDDimension_sptr> &dimensions);
+  void initGeometry(
+      std::vector<boost::shared_ptr<Geometry::IMDDimension>> &dimensions);
 
   // --------------------------------------------------------------------------------------------
   // These are the main methods for dimensions, that CAN be overridden (e.g. by
@@ -61,7 +67,7 @@ public:
   getDimensionWithId(std::string id) const;
   size_t getDimensionIndexByName(const std::string &name) const;
   size_t getDimensionIndexById(const std::string &id) const;
-  Mantid::Geometry::VecIMDDimension_const_sptr
+  std::vector<boost::shared_ptr<const Geometry::IMDDimension>>
   getNonIntegratedDimensions() const;
   virtual std::vector<coord_t> estimateResolution() const;
 
@@ -129,13 +135,15 @@ public:
   /// Clear original workspaces
   void clearOriginalWorkspaces();
 
+  friend class MDGeometryNotificationHelper;
+
 protected:
   /// Function called when observer objects recieves a notification
-  void deleteNotificationReceived(
-      Mantid::API::WorkspacePreDeleteNotification_ptr notice);
+  void
+  deleteNotificationReceived(const boost::shared_ptr<const Workspace> &deleted);
 
   /// Vector of the dimensions used, in the order X Y Z t, etc.
-  std::vector<Mantid::Geometry::IMDDimension_sptr> m_dimensions;
+  std::vector<boost::shared_ptr<Geometry::IMDDimension>> m_dimensions;
 
   /// Pointer to the original workspace(s), if this workspace is a coordinate
   /// transformation from an original workspace.
@@ -155,12 +163,8 @@ protected:
   std::vector<boost::shared_ptr<const Mantid::API::CoordTransform>>
       m_transforms_ToOriginal;
 
-  /// Poco delete notification observer object
-  Poco::NObserver<MDGeometry, Mantid::API::WorkspacePreDeleteNotification>
-      m_delete_observer;
-
-  /// Set to True when the m_delete_observer is observing workspace deletions.
-  bool m_observingDelete;
+  /// Helper that deals with notifications and observing the ADS
+  std::unique_ptr<MDGeometryNotificationHelper> m_notificationHelper;
 
   /** the matrix which transforms momentums from orthogonal Q-system to
      Orthogonal HKL or non-orthogonal HKL system alighned WRT to arbitrary
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
index f157e5540a38c32f8a46282d266c7b7d124c898b..fb4a78dc8067e35388c59bba36c5ee470e5ec480 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
@@ -8,11 +8,14 @@
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/ISpectrum.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidKernel/EmptyValues.h"
 
 namespace Mantid {
 
 namespace Indexing {
 class IndexInfo;
+namespace Kernel {
+class DateAndTime;
 }
 
 namespace Geometry {
@@ -434,9 +437,6 @@ public:
   bool isDistribution() const;
   void setDistribution(bool newValue);
 
-  /// Mask a given workspace index, setting the data and error values to zero
-  void maskWorkspaceIndex(const std::size_t index);
-
   // Methods to set and access masked bins
   void maskBin(const size_t &workspaceIndex, const size_t &binIndex,
                const double &weight = 1.0);
@@ -541,6 +541,10 @@ public:
   // End image methods
   //=====================================================================================
 
+  size_t numberOfDetectorGroups() const override;
+  const std::set<detid_t> &
+  detectorIDsInGroup(const size_t index) const override;
+
 protected:
   /// Protected copy constructor. May be used by childs for cloning.
   MatrixWorkspace(const MatrixWorkspace &other);
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
index afa8aca44fbca153bfb90f2a4f8396494fc71a44..9191b13619941a544f8dec5bcfa50ad6c2183b9e 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspaceMDIterator.h
@@ -4,6 +4,7 @@
 #include "MantidKernel/System.h"
 #include "MantidAPI/IMDIterator.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/MDGeometry/MDImplicitFunction.h"
 #include "MantidKernel/cow_ptr.h"
 
@@ -138,6 +139,9 @@ private:
   /// For numeric axes, this is the size of the bin in the vertical direction.
   /// It is 1.0 for spectrum axes
   double m_verticalBinSize;
+
+  /// SpectrumInfo object, used for masking information
+  const SpectrumInfo &m_spectrumInfo;
 };
 
 } // namespace API
diff --git a/Framework/API/inc/MantidAPI/NearestNeighbourInfo.h b/Framework/API/inc/MantidAPI/NearestNeighbourInfo.h
index b184b9e7fff58d67b493084c8d4f3d9ab2ba2e0c..894c8c43e130d3a1b806f36936245fb558966757 100644
--- a/Framework/API/inc/MantidAPI/NearestNeighbourInfo.h
+++ b/Framework/API/inc/MantidAPI/NearestNeighbourInfo.h
@@ -2,12 +2,20 @@
 #define MANTID_API_NEARESTNEIGHBOURINFO_H_
 
 #include "MantidAPI/DllConfig.h"
-#include "MantidGeometry/Instrument/NearestNeighbours.h"
+#include "MantidGeometry/IDTypes.h"
+#include "MantidKernel/V3D.h"
+
+#include <memory>
+#include <map>
 
 namespace Mantid {
+namespace Geometry {
+class IDetector;
+}
 namespace API {
 
 class MatrixWorkspace;
+class NearestNeighbours;
 
 /** NearestNeighbourInfo provides easy access to nearest-neighbour information
   for a workspace.
@@ -38,6 +46,7 @@ public:
   NearestNeighbourInfo(const MatrixWorkspace &workspace,
                        const bool ignoreMaskedDetectors,
                        const int nNeighbours = 8);
+  ~NearestNeighbourInfo();
 
   std::map<specnum_t, Kernel::V3D>
   getNeighbours(const Geometry::IDetector *comp,
@@ -48,7 +57,7 @@ public:
 
 private:
   const MatrixWorkspace &m_workspace;
-  Geometry::NearestNeighbours m_nearestNeighbours;
+  std::unique_ptr<NearestNeighbours> m_nearestNeighbours;
 };
 
 } // namespace API
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/NearestNeighbours.h b/Framework/API/inc/MantidAPI/NearestNeighbours.h
similarity index 74%
rename from Framework/Geometry/inc/MantidGeometry/Instrument/NearestNeighbours.h
rename to Framework/API/inc/MantidAPI/NearestNeighbours.h
index 3527a025c4da602a638d75c605b427878eca720a..cbe5525b5624ae76218e498894b212283735bacf 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/NearestNeighbours.h
+++ b/Framework/API/inc/MantidAPI/NearestNeighbours.h
@@ -1,7 +1,7 @@
 #ifndef MANTID_GEOMETRY_INSTRUMENT_NEARESTNEIGHBOURS
 #define MANTID_GEOMETRY_INSTRUMENT_NEARESTNEIGHBOURS
 
-#include "MantidGeometry/DllConfig.h"
+#include "MantidAPI/DllConfig.h"
 #include "MantidGeometry/IDTypes.h"
 #include "MantidKernel/V3D.h"
 // Boost graphing
@@ -13,14 +13,14 @@
 
 namespace Mantid {
 namespace Geometry {
-
 class Instrument;
 class IDetector;
-
-typedef std::unordered_map<specnum_t, std::set<detid_t>>
-    ISpectrumDetectorMapping;
-
+}
+namespace API {
+class SpectrumInfo;
 /**
+ * This class is not intended for direct use. Use NearestNeighbourInfo instead!
+ *
  * This class is used to find the nearest neighbours of a detector in the
  * instrument geometry. This class can be queried through calls to the
  * getNeighbours() function on a Detector object.
@@ -58,17 +58,10 @@ typedef std::unordered_map<specnum_t, std::set<detid_t>>
  *  File change history is stored at: <https://github.com/mantidproject/mantid>
  *  Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
-class MANTID_GEOMETRY_DLL NearestNeighbours {
+class MANTID_API_DLL NearestNeighbours {
 public:
-  /// Constructor with an instrument and a spectra map
-  NearestNeighbours(boost::shared_ptr<const Instrument> instrument,
-                    const ISpectrumDetectorMapping &spectraMap,
-                    bool ignoreMaskedDetectors = false);
-
-  /// Constructor with an instrument and a spectra map and number of neighbours
-  NearestNeighbours(int nNeighbours,
-                    boost::shared_ptr<const Instrument> instrument,
-                    const ISpectrumDetectorMapping &spectraMap,
+  NearestNeighbours(int nNeighbours, const SpectrumInfo &spectrumInfo,
+                    std::vector<specnum_t> spectrumNumbers,
                     bool ignoreMaskedDetectors = false);
 
   // Neighbouring spectra by radius
@@ -79,17 +72,14 @@ public:
   std::map<specnum_t, Mantid::Kernel::V3D> neighbours(specnum_t spectrum) const;
 
 protected:
-  /// Get the spectra associated with all in the instrument
-  std::map<specnum_t, boost::shared_ptr<const IDetector>>
-  getSpectraDetectors(boost::shared_ptr<const Instrument> instrument,
-                      const ISpectrumDetectorMapping &spectraMap);
-
-  /// A pointer the the instrument
-  boost::shared_ptr<const Instrument> m_instrument;
-  /// A reference to the spectra map
-  const ISpectrumDetectorMapping &m_spectraMap;
+  std::vector<size_t> getSpectraDetectors();
 
 private:
+  /// A reference to the SpectrumInfo
+  const SpectrumInfo &m_spectrumInfo;
+  /// Vector of spectrum numbers
+  const std::vector<specnum_t> m_spectrumNumbers;
+
   /// typedef for Graph object used to hold the calculated information
   typedef boost::adjacency_list<
       boost::vecS, boost::vecS, boost::directedS,
@@ -127,14 +117,7 @@ private:
   bool m_bIgnoreMaskedDetectors;
 };
 
-/// Typedef for shared pointer to the NearestNeighbours class
-typedef boost::shared_ptr<Mantid::Geometry::NearestNeighbours>
-    NearestNeighbours_sptr;
-/// Typedef for constant shared pointer to the NearestNeighbours class
-typedef boost::shared_ptr<const Mantid::Geometry::NearestNeighbours>
-    NearestNeighbours_const_sptr;
-
-} // namespace Geometry
+} // namespace API
 } // namespace Mantid
 
 #endif
diff --git a/Framework/API/inc/MantidAPI/PrecompiledHeader.h b/Framework/API/inc/MantidAPI/PrecompiledHeader.h
index fa64968355765c1e9b938ac562bed81e326ccdc9..4869d894bee622cffb880d4809900bf0d5a8e614 100644
--- a/Framework/API/inc/MantidAPI/PrecompiledHeader.h
+++ b/Framework/API/inc/MantidAPI/PrecompiledHeader.h
@@ -14,7 +14,6 @@
 #include "MantidGeometry/IComponent.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/NearestNeighbours.h"
 
 // STL
 #include <vector>
diff --git a/Framework/API/inc/MantidAPI/Run.h b/Framework/API/inc/MantidAPI/Run.h
index fa919615acc399b65782e3069b0f11f81b141c95..e7112752fe701b7565ba3c51fb9d5cf15a129e36 100644
--- a/Framework/API/inc/MantidAPI/Run.h
+++ b/Framework/API/inc/MantidAPI/Run.h
@@ -3,8 +3,8 @@
 
 #include "MantidAPI/DllConfig.h"
 #include "MantidAPI/LogManager.h"
+#include "MantidKernel/Matrix.h"
 #include "MantidKernel/TimeSplitter.h"
-#include "MantidGeometry/Instrument/Goniometer.h"
 
 #include <vector>
 
@@ -14,6 +14,10 @@ class File;
 
 namespace Mantid {
 
+namespace Geometry {
+class Goniometer;
+}
+
 namespace API {
 
 /**
@@ -46,6 +50,11 @@ namespace API {
 */
 class MANTID_API_DLL Run : public LogManager {
 public:
+  Run();
+  Run(const Run &other);
+  ~Run();
+  Run &operator=(const Run &other);
+
   /// Clone
   boost::shared_ptr<Run> clone();
 
@@ -83,10 +92,10 @@ public:
                      const bool useLogValues);
   /** @return A reference to the const Goniometer object for this run */
   inline const Geometry::Goniometer &getGoniometer() const {
-    return m_goniometer;
+    return *m_goniometer;
   }
   /** @return A reference to the non-const Goniometer object for this run */
-  inline Geometry::Goniometer &mutableGoniometer() { return m_goniometer; }
+  inline Geometry::Goniometer &mutableGoniometer() { return *m_goniometer; }
 
   // Retrieve the goniometer rotation matrix
   const Kernel::DblMatrix &getGoniometerMatrix() const;
@@ -103,7 +112,7 @@ private:
   void calculateGoniometerMatrix();
 
   /// Goniometer for this run
-  Mantid::Geometry::Goniometer m_goniometer;
+  std::unique_ptr<Geometry::Goniometer> m_goniometer;
   /// A set of histograms that can be stored here for future reference
   std::vector<double> m_histoBins;
 
diff --git a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
index a6e1fae0e1c9f9abdaf11da04daf03a7ba2198e7..c21655a2b8c82bb3ec0225a0999aecfa763aea24 100644
--- a/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
+++ b/Framework/API/inc/MantidAPI/SpectraDetectorTypes.h
@@ -5,7 +5,7 @@
 //------------------------------------------------------------------------------
 #include "MantidGeometry/IDTypes.h"
 #include <unordered_map>
-#include <vector>
+#include <set>
 
 namespace Mantid {
 
@@ -14,7 +14,7 @@ typedef std::unordered_map<specnum_t, size_t> spec2index_map;
 /// Map with key = detector ID, value = workspace index
 typedef std::unordered_map<detid_t, size_t> detid2index_map;
 /// Map single det ID of group to its members
-typedef std::unordered_map<detid_t, std::vector<detid_t>> det2group_map;
+typedef std::unordered_map<detid_t, std::set<detid_t>> det2group_map;
 }
 
 #endif // MANTID_API_SPECTRADETECTORMAP_TYPES
diff --git a/Framework/API/inc/MantidAPI/SpectrumInfo.h b/Framework/API/inc/MantidAPI/SpectrumInfo.h
index aed89ecc1015d66abad4250982c34e0301b14669..7e3c2874d4dcfd370e837babca43148a30a5c52a 100644
--- a/Framework/API/inc/MantidAPI/SpectrumInfo.h
+++ b/Framework/API/inc/MantidAPI/SpectrumInfo.h
@@ -18,7 +18,7 @@ class ParameterMap;
 namespace API {
 
 class DetectorInfo;
-class MatrixWorkspace;
+class ExperimentInfo;
 
 /** API::SpectrumInfo is an intermediate step towards a SpectrumInfo that is
   part of Instrument-2.0. The aim is to provide a nearly identical interface
@@ -29,8 +29,10 @@ class MatrixWorkspace;
   spectra (which may correspond to one or more detectors), such as mask and
   monitor flags, L1, L2, and 2-theta.
 
-  This class is thread safe with OpenMP BUT NOT WITH ANY OTHER THREADING LIBRARY
-  such as Poco threads or Intel TBB.
+  This class is thread safe for read operations (const access) with OpenMP BUT
+  NOT WITH ANY OTHER THREADING LIBRARY such as Poco threads or Intel TBB. There
+  are no thread-safety guarantees for write operations (non-const access). Reads
+  concurrent with writes or concurrent writes are not allowed.
 
 
   @author Simon Heybrock
@@ -59,8 +61,8 @@ class MatrixWorkspace;
 */
 class MANTID_API_DLL SpectrumInfo {
 public:
-  SpectrumInfo(const MatrixWorkspace &workspace);
-  SpectrumInfo(MatrixWorkspace &workspace);
+  SpectrumInfo(const ExperimentInfo &experimentInfo);
+  SpectrumInfo(ExperimentInfo &experimentInfo);
   ~SpectrumInfo();
 
   bool isMonitor(const size_t index) const;
@@ -72,6 +74,8 @@ public:
   bool hasDetectors(const size_t index) const;
   bool hasUniqueDetector(const size_t index) const;
 
+  void setMasked(const size_t index, bool masked);
+
   // This is likely to be deprecated/removed with the introduction of
   // Instrument-2.0: The concept of detector groups will probably be dropped so
   // returning a single detector for a spectrum will not be possible anymore.
@@ -88,7 +92,7 @@ private:
   std::vector<boost::shared_ptr<const Geometry::IDetector>>
   getDetectorVector(const size_t index) const;
 
-  const MatrixWorkspace &m_workspace;
+  const ExperimentInfo &m_experimentInfo;
   DetectorInfo *m_mutableDetectorInfo{nullptr};
   const DetectorInfo &m_detectorInfo;
   mutable std::vector<boost::shared_ptr<const Geometry::IDetector>>
diff --git a/Framework/API/inc/MantidAPI/Workspace.h b/Framework/API/inc/MantidAPI/Workspace.h
index e089fb57640b80ad560951268dde19b106a96085..a29543e6757bc7b7a0f0f9997e5fb93f588f64c7 100644
--- a/Framework/API/inc/MantidAPI/Workspace.h
+++ b/Framework/API/inc/MantidAPI/Workspace.h
@@ -1,29 +1,20 @@
 #ifndef MANTID_API_WORKSPACE_H_
 #define MANTID_API_WORKSPACE_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Workspace_fwd.h"
-#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAPI/DllConfig.h"
 #include "MantidKernel/DataItem.h"
 #include "MantidKernel/Exception.h"
 
 namespace Mantid {
 
-//----------------------------------------------------------------------
-// Forward Declaration
-//----------------------------------------------------------------------
 namespace Kernel {
 class Logger;
 }
 
 namespace API {
-//----------------------------------------------------------------------
-// Forward Declaration
-//----------------------------------------------------------------------
 class AnalysisDataServiceImpl;
+class WorkspaceHistory;
 
 /** Base Workspace Abstract Class.
 
@@ -53,7 +44,8 @@ class AnalysisDataServiceImpl;
  */
 class MANTID_API_DLL Workspace : public Kernel::DataItem {
 public:
-  Workspace() = default;
+  Workspace();
+  ~Workspace();
 
   /** Returns a clone (copy) of the workspace with covariant return type in all
    * derived classes.
@@ -99,13 +91,13 @@ public:
   std::string getMemorySizeAsStr() const;
 
   /// Returns a reference to the WorkspaceHistory
-  WorkspaceHistory &history() { return m_history; }
+  WorkspaceHistory &history() { return *m_history; }
   /// Returns a reference to the WorkspaceHistory const
-  const WorkspaceHistory &getHistory() const { return m_history; }
+  const WorkspaceHistory &getHistory() const { return *m_history; }
 
 protected:
   /// Protected copy constructor. May be used by childs for cloning.
-  Workspace(const Workspace &) = default;
+  Workspace(const Workspace &);
 
 private:
   void setName(const std::string &);
@@ -117,7 +109,7 @@ private:
   /// workspace algebra
   std::string m_name;
   /// The history of the workspace, algorithm and environment
-  WorkspaceHistory m_history;
+  std::unique_ptr<WorkspaceHistory> m_history;
 
   /// Virtual clone method. Not implemented to force implementation in childs.
   virtual Workspace *doClone() const = 0;
diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.h b/Framework/API/inc/MantidAPI/WorkspaceProperty.h
index 125b1f1d66cf17c4f86b232a3d79c0548468b737..02dcb9068bd029994858edd3cce12047662044a5 100644
--- a/Framework/API/inc/MantidAPI/WorkspaceProperty.h
+++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.h
@@ -1,15 +1,9 @@
 #ifndef MANTID_API_WORKSPACEPROPERTY_H_
 #define MANTID_API_WORKSPACEPROPERTY_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidKernel/PropertyWithValue.h"
 #include "MantidAPI/IWorkspaceProperty.h"
-#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/Logger.h"
-#include "MantidKernel/Exception.h"
-#include "MantidAPI/WorkspaceGroup.h"
 
 #include <string>
 
@@ -19,6 +13,7 @@ namespace API {
 // Forward decaration
 // -------------------------------------------------------------------------
 class MatrixWorkspace;
+class WorkspaceGroup;
 
 /// Enumeration for a mandatory/optional property
 struct PropertyMode {
@@ -77,430 +72,70 @@ class WorkspaceProperty
     : public Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>,
       public IWorkspaceProperty {
 public:
-  /** Constructor.
-  *  Sets the property and workspace names but initializes the workspace pointer
-  * to null.
-  *  @param name :: The name to assign to the property
-  *  @param wsName :: The name of the workspace
-  *  @param direction :: Whether this is a Direction::Input, Direction::Output
-  * or Direction::InOut (Input & Output) workspace
-  *  @param validator :: The (optional) validator to use for this property
-  *  @throw std::out_of_range if the direction argument is not a member of the
-  * Direction enum (i.e. 0-2)
-  */
   explicit WorkspaceProperty(
       const std::string &name, const std::string &wsName,
       const unsigned int direction,
       Kernel::IValidator_sptr validator =
-          Kernel::IValidator_sptr(new Kernel::NullValidator))
-      : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
-            name, boost::shared_ptr<TYPE>(), validator, direction),
-        m_workspaceName(wsName), m_initialWSName(wsName),
-        m_optional(PropertyMode::Mandatory), m_locking(LockMode::Lock) {}
-
-  /** Constructor.
-  *  Sets the property and workspace names but initialises the workspace pointer
-  * to null.
-  *  @param name :: The name to assign to the property
-  *  @param wsName :: The name of the workspace
-  *  @param direction :: Whether this is a Direction::Input, Direction::Output
-  * or Direction::InOut (Input & Output) workspace
-  *  @param optional :: If true then the property is optional
-  *  @param validator :: The (optional) validator to use for this property
-  *  @throw std::out_of_range if the direction argument is not a member of the
-  * Direction enum (i.e. 0-2)
-  */
+          Kernel::IValidator_sptr(new Kernel::NullValidator));
+
   explicit WorkspaceProperty(
       const std::string &name, const std::string &wsName,
       const unsigned int direction, const PropertyMode::Type optional,
       Kernel::IValidator_sptr validator =
-          Kernel::IValidator_sptr(new Kernel::NullValidator))
-      : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
-            name, boost::shared_ptr<TYPE>(), validator, direction),
-        m_workspaceName(wsName), m_initialWSName(wsName), m_optional(optional),
-        m_locking(LockMode::Lock) {}
-
-  /** Constructor.
-  *  Sets the property and workspace names but initialises the workspace pointer
-  * to null.
-  *  @param name :: The name to assign to the property
-  *  @param wsName :: The name of the workspace
-  *  @param direction :: Whether this is a Direction::Input, Direction::Output
-  * or Direction::InOut (Input & Output) workspace
-  *  @param optional :: A boolean indicating whether the property is mandatory
-  * or not. Only matters
-  *                     for input properties
-  *  @param locking :: A boolean indicating whether the workspace should read or
-  *                    write-locked when an algorithm begins. Default=true.
-  *  @param validator :: The (optional) validator to use for this property
-  *  @throw std::out_of_range if the direction argument is not a member of the
-  * Direction enum (i.e. 0-2)
-  */
+          Kernel::IValidator_sptr(new Kernel::NullValidator));
+
   explicit WorkspaceProperty(
       const std::string &name, const std::string &wsName,
       const unsigned int direction, const PropertyMode::Type optional,
       const LockMode::Type locking,
       Kernel::IValidator_sptr validator =
-          Kernel::IValidator_sptr(new Kernel::NullValidator))
-      : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
-            name, boost::shared_ptr<TYPE>(), validator, direction),
-        m_workspaceName(wsName), m_initialWSName(wsName), m_optional(optional),
-        m_locking(locking) {}
-
-  /// Copy constructor, the default name stored in the new object is the same as
-  /// the default name from the original object
-  WorkspaceProperty(const WorkspaceProperty &right)
-      : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(right),
-        m_workspaceName(right.m_workspaceName),
-        m_initialWSName(right.m_initialWSName), m_optional(right.m_optional),
-        m_locking(right.m_locking) {}
-
-  /// Copy assignment operator. Only copies the value (i.e. the pointer to the
-  /// workspace)
-  WorkspaceProperty &operator=(const WorkspaceProperty &right) {
-    if (&right == this)
-      return *this;
-    Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(right);
-    return *this;
-  }
-
-  /** Bring in the PropertyWithValue assignment operator explicitly (avoids
-   * VSC++ warning)
-   * @param value :: The value to set to
-   * @return assigned PropertyWithValue
-   */
+          Kernel::IValidator_sptr(new Kernel::NullValidator));
+
+  WorkspaceProperty(const WorkspaceProperty &right);
+
+  WorkspaceProperty &operator=(const WorkspaceProperty &right);
+
   boost::shared_ptr<TYPE> &
-  operator=(const boost::shared_ptr<TYPE> &value) override {
-    std::string wsName = value->name();
-    if (this->direction() == Kernel::Direction::Input && !wsName.empty()) {
-      m_workspaceName = wsName;
-    }
-    return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value);
-  }
-
-  //--------------------------------------------------------------------------------------
-  /// Add the value of another property
-  WorkspaceProperty &operator+=(Kernel::Property const *) override {
-    throw Kernel::Exception::NotImplementedError(
-        "+= operator is not implemented for WorkspaceProperty.");
-    return *this;
-  }
-
-  /// 'Virtual copy constructor'
-  WorkspaceProperty<TYPE> *clone() const override {
-    return new WorkspaceProperty<TYPE>(*this);
-  }
-
-  /** Get the name of the workspace
-  *  @return The workspace's name
-  */
-  std::string value() const override { return m_workspaceName; }
-
-  /** Get the value the property was initialised with -its default value
-  *  @return The default value
-  */
-  std::string getDefault() const override { return m_initialWSName; }
-
-  /** Set the name of the workspace.
-  *  Also tries to retrieve it from the AnalysisDataService.
-  *  @param value :: The new name for the workspace
-  *  @return
-  */
-  std::string setValue(const std::string &value) override {
-    m_workspaceName = value;
-    if (Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::autoTrim()) {
-      boost::trim(m_workspaceName);
-    }
-    // Try and get the workspace from the ADS, but don't worry if we can't
-    try {
-      Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
-          AnalysisDataService::Instance().retrieveWS<TYPE>(m_workspaceName);
-    } catch (Kernel::Exception::NotFoundError &) {
-      // Set to null property if not found
-      this->clear();
-      // the workspace name is not reset here, however.
-    }
-
-    return isValid();
-  }
-
-  /** Set a value from a data item
-   *  @param value :: A shared pointer to a DataItem. If it is of the correct
-   *  type it will set validated, if not the property's value will be cleared.
-   *  @return
-   */
+  operator=(const boost::shared_ptr<TYPE> &value) override;
+
+  WorkspaceProperty &operator+=(Kernel::Property const *) override;
+
+  WorkspaceProperty<TYPE> *clone() const override;
+
+  std::string value() const override;
+
+  std::string getDefault() const override;
+
+  std::string setValue(const std::string &value) override;
+
   std::string
-  setDataItem(const boost::shared_ptr<Kernel::DataItem> value) override {
-    boost::shared_ptr<TYPE> typed = boost::dynamic_pointer_cast<TYPE>(value);
-    if (typed) {
-      std::string wsName = typed->name();
-      if (this->direction() == Kernel::Direction::Input && !wsName.empty()) {
-        m_workspaceName = wsName;
-      }
-      Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value = typed;
-    } else {
-      this->clear();
-    }
-    return isValid();
-  }
-
-  /** Checks whether the entered workspace is valid.
-  *  To be valid, in addition to satisfying the conditions of any validators,
-  *  an output property must not have an empty name and an input one must point
-  * to
-  *  a workspace of the correct type.
-  *  @returns A user level description of the problem or "" if it is valid.
-  */
-  std::string isValid() const override {
-    // start with the no error condition
-    std::string error;
-
-    // If an output workspace it must have a name, although it might not exist
-    // in the ADS yet
-    if (this->direction() == Kernel::Direction::Output) {
-      return isValidOutputWs();
-    }
-
-    // If an input (or inout) workspace, must point to something, although it
-    // doesn't have to have a name
-    // unless it's optional
-    if (this->direction() == Kernel::Direction::Input ||
-        this->direction() == Kernel::Direction::InOut) {
-      // Workspace groups will not have a value since they are not of type TYPE
-      if (!Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value) {
-        Mantid::API::Workspace_sptr wksp;
-        // if the workspace name is empty then there is no point asking the ADS
-        if (m_workspaceName.empty())
-          return isOptionalWs();
-
-        try {
-          wksp = AnalysisDataService::Instance().retrieve(m_workspaceName);
-        } catch (Kernel::Exception::NotFoundError &) {
-          // Check to see if the workspace is not logged with the ADS because it
-          // is optional.
-          return isOptionalWs();
-        }
-
-        // At this point we have a valid pointer to a Workspace so we need to
-        // test whether it is a group
-        if (boost::dynamic_pointer_cast<Mantid::API::WorkspaceGroup>(wksp)) {
-          return isValidGroup(
-              boost::dynamic_pointer_cast<Mantid::API::WorkspaceGroup>(wksp));
-        } else {
-          error = "Workspace " + this->value() + " is not of the correct type";
-        }
-        return error;
-      }
-    }
-    // Call superclass method to access any attached validators (which do their
-    // own logging)
-    return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::isValid();
-  }
-
-  /** Indicates if the object is still pointing to the same workspace, using the
-  * workspace name
-  *  @return true if the value is the same as the initial value or false
-  * otherwise
-  */
-  bool isDefault() const override { return m_initialWSName == m_workspaceName; }
-
-  /** Is the workspace property optional
-   * @return true if the workspace can be blank   */
-  bool isOptional() const override {
-    return (m_optional == PropertyMode::Optional);
-  }
-  /** Does the workspace need to be locked before starting an algorithm?
-   * @return true (default) if the workspace will be locked */
-  bool isLocking() const override { return (m_locking == LockMode::Lock); }
-
-  /** Returns the current contents of the AnalysisDataService for input
-   * workspaces.
-   *  For output workspaces, an empty set is returned
-   *  @return set of objects in AnalysisDataService
-   */
-  std::vector<std::string> allowedValues() const override {
-    if (this->direction() == Kernel::Direction::Input ||
-        this->direction() == Kernel::Direction::InOut) {
-      // If an input workspace, get the list of workspaces currently in the ADS
-      auto vals = AnalysisDataService::Instance().getObjectNames(
-          Mantid::Kernel::DataServiceSort::Sorted);
-      if (isOptional()) // Insert an empty option
-      {
-        vals.push_back("");
-      }
-      // Copy-construct a temporary workspace property to test the validity of
-      // each workspace
-      WorkspaceProperty<TYPE> tester(*this);
-
-      // Remove any workspace that's not valid for this algorithm
-      auto eraseIter = remove_if(vals.begin(), vals.end(),
-                                 [&tester](const std::string &wsName) {
-                                   return !tester.setValue(wsName).empty();
-                                 });
-      // Erase everything past returned iterator afterwards for readability
-      vals.erase(eraseIter, vals.end());
-      return vals;
-    } else {
-      // For output workspaces, just return an empty set
-      return std::vector<std::string>();
-    }
-  }
-
-  /// Create a history record
-  /// @return A populated PropertyHistory for this class
-  const Kernel::PropertyHistory createHistory() const override {
-    std::string wsName = m_workspaceName;
-    bool isdefault = this->isDefault();
-
-    if ((wsName.empty() || this->hasTemporaryValue()) && this->operator()()) {
-      // give the property a temporary name in the history
-      std::ostringstream os;
-      os << "__TMP" << this->operator()().get();
-      wsName = os.str();
-      isdefault = false;
-    }
-    return Kernel::PropertyHistory(this->name(), wsName, this->type(),
-                                   isdefault, this->direction());
-  }
-
-  /** If this is an output workspace, store it into the AnalysisDataService
-  *  @return True if the workspace is an output workspace and has been stored
-  *  @throw std::runtime_error if unable to store the workspace successfully
-  */
-  bool store() override {
-    bool result = false;
-    if (!this->operator()() && isOptional())
-      return result;
-    if (this->direction()) // Output or InOut
-    {
-      // Check that workspace exists
-      if (!this->operator()())
-        throw std::runtime_error(
-            "WorkspaceProperty doesn't point to a workspace");
-      // Note use of addOrReplace rather than add
-      API::AnalysisDataService::Instance().addOrReplace(m_workspaceName,
-                                                        this->operator()());
-      result = true;
-    }
-    // always clear the internal pointer after storing
-    clear();
-
-    return result;
-  }
-
-  Workspace_sptr getWorkspace() const override { return this->operator()(); }
+  setDataItem(const boost::shared_ptr<Kernel::DataItem> value) override;
+
+  std::string isValid() const override;
+
+  bool isDefault() const override;
+
+  bool isOptional() const override;
+  bool isLocking() const override;
+
+  std::vector<std::string> allowedValues() const override;
+
+  const Kernel::PropertyHistory createHistory() const override;
+
+  bool store() override;
+
+  Workspace_sptr getWorkspace() const override;
 
 private:
-  /** Checks whether the entered workspace group is valid.
-  *  To be valid *all* members of the group have to be valid.
-  *  @param wsGroup :: the WorkspaceGroup of which to check the validity
-  *  @returns A user level description of the problem or "" if it is valid.
-  */
-  std::string isValidGroup(boost::shared_ptr<WorkspaceGroup> wsGroup) const {
-    g_log.debug() << " Input WorkspaceGroup found \n";
-
-    std::vector<std::string> wsGroupNames = wsGroup->getNames();
-    std::string error;
-
-    // Cycle through each workspace in the group ...
-    for (const auto &memberWsName : wsGroupNames) {
-      boost::shared_ptr<Workspace> memberWs =
-          AnalysisDataService::Instance().retrieve(memberWsName);
-
-      // Table Workspaces are ignored
-      if ("TableWorkspace" == memberWs->id()) {
-        error = "Workspace " + memberWsName + " is of type TableWorkspace and "
-                                              "will therefore be ignored as "
-                                              "part of the GroupedWorkspace.";
-
-        g_log.debug() << error << '\n';
-      } else {
-        // ... and if it is a workspace of incorrect type, exclude the group by
-        // returning an error.
-        if (!boost::dynamic_pointer_cast<TYPE>(memberWs)) {
-          error = "Workspace " + memberWsName + " is not of type " +
-                  Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::type() +
-                  ".";
-
-          g_log.debug() << error << '\n';
-
-          return error;
-        }
-        // If it is of the correct type, it may still be invalid. Check.
-        else {
-          Mantid::API::WorkspaceProperty<TYPE> memberWsProperty(*this);
-          std::string memberError = memberWsProperty.setValue(memberWsName);
-          if (!memberError.empty())
-            return memberError; // Since if this member is invalid, then the
-                                // whole group is invalid.
-        }
-      }
-    }
-
-    return ""; // Since all members of the group are valid.
-  }
-
-  /** Checks whether the entered output workspace is valid.
-  *  To be valid the only thing it needs is a name that is allowed by the ADS,
-  * @see AnalysisDataServiceImpl
-  *  @returns A user level description of the problem or "" if it is valid.
-  */
-  std::string isValidOutputWs() const {
-    std::string error;
-    const std::string value = this->value();
-    if (!value.empty()) {
-      // Will the ADS accept it
-      error = AnalysisDataService::Instance().isValid(value);
-    } else {
-      if (isOptional())
-        error = ""; // Optional ones don't need a name
-      else
-        error = "Enter a name for the Output workspace";
-    }
-    return error;
-  }
-
-  /** Checks whether the entered workspace (that by this point we've found is
-  * not in the ADS)
-  *  is actually an optional workspace and so still valid.
-  *  @returns A user level description of the problem or "" if it is valid.
-  */
-  std::string isOptionalWs() const {
-    std::string error;
-
-    if (m_workspaceName.empty()) {
-      if (isOptional()) {
-        error = "";
-      } else {
-        error = "Enter a name for the Input/InOut workspace";
-      }
-    } else {
-      error = "Workspace \"" + this->value() +
-              "\" was not found in the Analysis Data Service";
-    }
-
-    return error;
-  }
-
-  /// Reset the pointer to the workspace
-  void clear() override {
-    Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
-        boost::shared_ptr<TYPE>();
-  }
-
-  /** Attempts to retreive the data from the ADS
-  *  if the data is not foung the internal pointer is set to null.
-  */
-  void retrieveWorkspaceFromADS() {
-    // Try and get the workspace from the ADS, but don't worry if we can't
-    try {
-      Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
-          AnalysisDataService::Instance().retrieveWS<TYPE>(m_workspaceName);
-    } catch (Kernel::Exception::NotFoundError &) {
-      // Set to null property if not found
-      this->clear();
-    }
-  }
+  std::string isValidGroup(boost::shared_ptr<WorkspaceGroup> wsGroup) const;
+
+  std::string isValidOutputWs() const;
+
+  std::string isOptionalWs() const;
+
+  void clear() override;
+
+  void retrieveWorkspaceFromADS();
 
   /// The name of the workspace (as used by the AnalysisDataService)
   std::string m_workspaceName;
diff --git a/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..5e40d8330821cf38b2c0d22ffcbd7091235e575f
--- /dev/null
+++ b/Framework/API/inc/MantidAPI/WorkspaceProperty.tcc
@@ -0,0 +1,466 @@
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceProperty.h"
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/PropertyHistory.h"
+
+namespace Mantid {
+namespace API {
+
+/** Constructor.
+*  Sets the property and workspace names but initializes the workspace pointer
+* to null.
+*  @param name :: The name to assign to the property
+*  @param wsName :: The name of the workspace
+*  @param direction :: Whether this is a Direction::Input, Direction::Output
+* or Direction::InOut (Input & Output) workspace
+*  @param validator :: The (optional) validator to use for this property
+*  @throw std::out_of_range if the direction argument is not a member of the
+* Direction enum (i.e. 0-2)
+*/
+template <typename TYPE>
+WorkspaceProperty<TYPE>::WorkspaceProperty(const std::string &name,
+                                           const std::string &wsName,
+                                           const unsigned int direction,
+                                           Kernel::IValidator_sptr validator)
+    : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
+          name, boost::shared_ptr<TYPE>(), validator, direction),
+      m_workspaceName(wsName), m_initialWSName(wsName),
+      m_optional(PropertyMode::Mandatory), m_locking(LockMode::Lock) {}
+
+/** Constructor.
+*  Sets the property and workspace names but initialises the workspace pointer
+* to null.
+*  @param name :: The name to assign to the property
+*  @param wsName :: The name of the workspace
+*  @param direction :: Whether this is a Direction::Input, Direction::Output
+* or Direction::InOut (Input & Output) workspace
+*  @param optional :: If true then the property is optional
+*  @param validator :: The (optional) validator to use for this property
+*  @throw std::out_of_range if the direction argument is not a member of the
+* Direction enum (i.e. 0-2)
+*/
+template <typename TYPE>
+WorkspaceProperty<TYPE>::WorkspaceProperty(const std::string &name,
+                                           const std::string &wsName,
+                                           const unsigned int direction,
+                                           const PropertyMode::Type optional,
+                                           Kernel::IValidator_sptr validator)
+    : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
+          name, boost::shared_ptr<TYPE>(), validator, direction),
+      m_workspaceName(wsName), m_initialWSName(wsName), m_optional(optional),
+      m_locking(LockMode::Lock) {}
+
+/** Constructor.
+*  Sets the property and workspace names but initialises the workspace pointer
+* to null.
+*  @param name :: The name to assign to the property
+*  @param wsName :: The name of the workspace
+*  @param direction :: Whether this is a Direction::Input, Direction::Output
+* or Direction::InOut (Input & Output) workspace
+*  @param optional :: A boolean indicating whether the property is mandatory
+* or not. Only matters
+*                     for input properties
+*  @param locking :: A boolean indicating whether the workspace should read or
+*                    write-locked when an algorithm begins. Default=true.
+*  @param validator :: The (optional) validator to use for this property
+*  @throw std::out_of_range if the direction argument is not a member of the
+* Direction enum (i.e. 0-2)
+*/
+template <typename TYPE>
+WorkspaceProperty<TYPE>::WorkspaceProperty(const std::string &name,
+                                           const std::string &wsName,
+                                           const unsigned int direction,
+                                           const PropertyMode::Type optional,
+                                           const LockMode::Type locking,
+                                           Kernel::IValidator_sptr validator)
+    : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(
+          name, boost::shared_ptr<TYPE>(), validator, direction),
+      m_workspaceName(wsName), m_initialWSName(wsName), m_optional(optional),
+      m_locking(locking) {}
+
+/// Copy constructor, the default name stored in the new object is the same as
+/// the default name from the original object
+template <typename TYPE>
+WorkspaceProperty<TYPE>::WorkspaceProperty(const WorkspaceProperty &right)
+    : Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>(right),
+      m_workspaceName(right.m_workspaceName),
+      m_initialWSName(right.m_initialWSName), m_optional(right.m_optional),
+      m_locking(right.m_locking) {}
+
+/// Copy assignment operator. Only copies the value (i.e. the pointer to the
+/// workspace)
+template <typename TYPE>
+WorkspaceProperty<TYPE> &WorkspaceProperty<TYPE>::
+operator=(const WorkspaceProperty &right) {
+  if (&right == this)
+    return *this;
+  Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(right);
+  return *this;
+}
+
+/** Bring in the PropertyWithValue assignment operator explicitly (avoids
+ * VSC++ warning)
+ * @param value :: The value to set to
+ * @return assigned PropertyWithValue
+ */
+template <typename TYPE>
+boost::shared_ptr<TYPE> &WorkspaceProperty<TYPE>::
+operator=(const boost::shared_ptr<TYPE> &value) {
+  std::string wsName = value->name();
+  if (this->direction() == Kernel::Direction::Input && !wsName.empty()) {
+    m_workspaceName = wsName;
+  }
+  return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::operator=(value);
+}
+
+//--------------------------------------------------------------------------------------
+/// Add the value of another property
+template <typename TYPE>
+WorkspaceProperty<TYPE> &WorkspaceProperty<TYPE>::
+operator+=(Kernel::Property const *) {
+  throw Kernel::Exception::NotImplementedError(
+      "+= operator is not implemented for WorkspaceProperty.");
+  return *this;
+}
+
+/// 'Virtual copy constructor'
+template <typename TYPE>
+WorkspaceProperty<TYPE> *WorkspaceProperty<TYPE>::clone() const {
+  return new WorkspaceProperty<TYPE>(*this);
+}
+
+/** Get the name of the workspace
+*  @return The workspace's name
+*/
+template <typename TYPE> std::string WorkspaceProperty<TYPE>::value() const {
+  return m_workspaceName;
+}
+
+/** Get the value the property was initialised with -its default value
+*  @return The default value
+*/
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::getDefault() const {
+  return m_initialWSName;
+}
+
+/** Set the name of the workspace.
+*  Also tries to retrieve it from the AnalysisDataService.
+*  @param value :: The new name for the workspace
+*  @return
+*/
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::setValue(const std::string &value) {
+  m_workspaceName = value;
+  if (Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::autoTrim()) {
+    boost::trim(m_workspaceName);
+  }
+  // Try and get the workspace from the ADS, but don't worry if we can't
+  try {
+    Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
+        AnalysisDataService::Instance().retrieveWS<TYPE>(m_workspaceName);
+  } catch (Kernel::Exception::NotFoundError &) {
+    // Set to null property if not found
+    this->clear();
+    // the workspace name is not reset here, however.
+  }
+
+  return isValid();
+}
+
+/** Set a value from a data item
+ *  @param value :: A shared pointer to a DataItem. If it is of the correct
+ *  type it will set validated, if not the property's value will be cleared.
+ *  @return
+ */
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::setDataItem(
+    const boost::shared_ptr<Kernel::DataItem> value) {
+  boost::shared_ptr<TYPE> typed = boost::dynamic_pointer_cast<TYPE>(value);
+  if (typed) {
+    std::string wsName = typed->name();
+    if (this->direction() == Kernel::Direction::Input && !wsName.empty()) {
+      m_workspaceName = wsName;
+    }
+    Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value = typed;
+  } else {
+    this->clear();
+  }
+  return isValid();
+}
+
+/** Checks whether the entered workspace is valid.
+*  To be valid, in addition to satisfying the conditions of any validators,
+*  an output property must not have an empty name and an input one must point
+* to
+*  a workspace of the correct type.
+*  @returns A user level description of the problem or "" if it is valid.
+*/
+template <typename TYPE> std::string WorkspaceProperty<TYPE>::isValid() const {
+  // start with the no error condition
+  std::string error;
+
+  // If an output workspace it must have a name, although it might not exist
+  // in the ADS yet
+  if (this->direction() == Kernel::Direction::Output) {
+    return isValidOutputWs();
+  }
+
+  // If an input (or inout) workspace, must point to something, although it
+  // doesn't have to have a name
+  // unless it's optional
+  if (this->direction() == Kernel::Direction::Input ||
+      this->direction() == Kernel::Direction::InOut) {
+    // Workspace groups will not have a value since they are not of type TYPE
+    if (!Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value) {
+      Mantid::API::Workspace_sptr wksp;
+      // if the workspace name is empty then there is no point asking the ADS
+      if (m_workspaceName.empty())
+        return isOptionalWs();
+
+      try {
+        wksp = AnalysisDataService::Instance().retrieve(m_workspaceName);
+      } catch (Kernel::Exception::NotFoundError &) {
+        // Check to see if the workspace is not logged with the ADS because it
+        // is optional.
+        return isOptionalWs();
+      }
+
+      // At this point we have a valid pointer to a Workspace so we need to
+      // test whether it is a group
+      if (boost::dynamic_pointer_cast<Mantid::API::WorkspaceGroup>(wksp)) {
+        return isValidGroup(
+            boost::dynamic_pointer_cast<Mantid::API::WorkspaceGroup>(wksp));
+      } else {
+        error = "Workspace " + this->value() + " is not of the correct type";
+      }
+      return error;
+    }
+  }
+  // Call superclass method to access any attached validators (which do their
+  // own logging)
+  return Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::isValid();
+}
+
+/** Indicates if the object is still pointing to the same workspace, using the
+* workspace name
+*  @return true if the value is the same as the initial value or false
+* otherwise
+*/
+template <typename TYPE> bool WorkspaceProperty<TYPE>::isDefault() const {
+  return m_initialWSName == m_workspaceName;
+}
+
+/** Is the workspace property optional
+ * @return true if the workspace can be blank   */
+template <typename TYPE> bool WorkspaceProperty<TYPE>::isOptional() const {
+  return (m_optional == PropertyMode::Optional);
+}
+/** Does the workspace need to be locked before starting an algorithm?
+ * @return true (default) if the workspace will be locked */
+template <typename TYPE> bool WorkspaceProperty<TYPE>::isLocking() const {
+  return (m_locking == LockMode::Lock);
+}
+
+/** Returns the current contents of the AnalysisDataService for input
+ * workspaces.
+ *  For output workspaces, an empty set is returned
+ *  @return set of objects in AnalysisDataService
+ */
+template <typename TYPE>
+std::vector<std::string> WorkspaceProperty<TYPE>::allowedValues() const {
+  if (this->direction() == Kernel::Direction::Input ||
+      this->direction() == Kernel::Direction::InOut) {
+    // If an input workspace, get the list of workspaces currently in the ADS
+    auto vals = AnalysisDataService::Instance().getObjectNames(
+        Mantid::Kernel::DataServiceSort::Sorted);
+    if (isOptional()) // Insert an empty option
+    {
+      vals.push_back("");
+    }
+    // Copy-construct a temporary workspace property to test the validity of
+    // each workspace
+    WorkspaceProperty<TYPE> tester(*this);
+
+    // Remove any workspace that's not valid for this algorithm
+    auto eraseIter = remove_if(vals.begin(), vals.end(),
+                               [&tester](const std::string &wsName) {
+                                 return !tester.setValue(wsName).empty();
+                               });
+    // Erase everything past returned iterator afterwards for readability
+    vals.erase(eraseIter, vals.end());
+    return vals;
+  } else {
+    // For output workspaces, just return an empty set
+    return std::vector<std::string>();
+  }
+}
+
+/// Create a history record
+/// @return A populated PropertyHistory for this class
+template <typename TYPE>
+const Kernel::PropertyHistory WorkspaceProperty<TYPE>::createHistory() const {
+  std::string wsName = m_workspaceName;
+  bool isdefault = this->isDefault();
+
+  if ((wsName.empty() || this->hasTemporaryValue()) && this->operator()()) {
+    // give the property a temporary name in the history
+    std::ostringstream os;
+    os << "__TMP" << this->operator()().get();
+    wsName = os.str();
+    isdefault = false;
+  }
+  return Kernel::PropertyHistory(this->name(), wsName, this->type(), isdefault,
+                                 this->direction());
+}
+
+/** If this is an output workspace, store it into the AnalysisDataService
+*  @return True if the workspace is an output workspace and has been stored
+*  @throw std::runtime_error if unable to store the workspace successfully
+*/
+template <typename TYPE> bool WorkspaceProperty<TYPE>::store() {
+  bool result = false;
+  if (!this->operator()() && isOptional())
+    return result;
+  if (this->direction()) // Output or InOut
+  {
+    // Check that workspace exists
+    if (!this->operator()())
+      throw std::runtime_error(
+          "WorkspaceProperty doesn't point to a workspace");
+    // Note use of addOrReplace rather than add
+    API::AnalysisDataService::Instance().addOrReplace(m_workspaceName,
+                                                      this->operator()());
+    result = true;
+  }
+  // always clear the internal pointer after storing
+  clear();
+
+  return result;
+}
+
+template <typename TYPE>
+Workspace_sptr WorkspaceProperty<TYPE>::getWorkspace() const {
+  return this->operator()();
+}
+
+/** Checks whether the entered workspace group is valid.
+*  To be valid *all* members of the group have to be valid.
+*  @param wsGroup :: the WorkspaceGroup of which to check the validity
+*  @returns A user level description of the problem or "" if it is valid.
+*/
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::isValidGroup(
+    boost::shared_ptr<WorkspaceGroup> wsGroup) const {
+  g_log.debug() << " Input WorkspaceGroup found \n";
+
+  std::vector<std::string> wsGroupNames = wsGroup->getNames();
+  std::string error;
+
+  // Cycle through each workspace in the group ...
+  for (const auto &memberWsName : wsGroupNames) {
+    boost::shared_ptr<Workspace> memberWs =
+        AnalysisDataService::Instance().retrieve(memberWsName);
+
+    // Table Workspaces are ignored
+    if ("TableWorkspace" == memberWs->id()) {
+      error = "Workspace " + memberWsName + " is of type TableWorkspace and "
+                                            "will therefore be ignored as "
+                                            "part of the GroupedWorkspace.";
+
+      g_log.debug() << error << '\n';
+    } else {
+      // ... and if it is a workspace of incorrect type, exclude the group by
+      // returning an error.
+      if (!boost::dynamic_pointer_cast<TYPE>(memberWs)) {
+        error = "Workspace " + memberWsName + " is not of type " +
+                Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::type() +
+                ".";
+
+        g_log.debug() << error << '\n';
+
+        return error;
+      }
+      // If it is of the correct type, it may still be invalid. Check.
+      else {
+        Mantid::API::WorkspaceProperty<TYPE> memberWsProperty(*this);
+        std::string memberError = memberWsProperty.setValue(memberWsName);
+        if (!memberError.empty())
+          return memberError; // Since if this member is invalid, then the
+                              // whole group is invalid.
+      }
+    }
+  }
+
+  return ""; // Since all members of the group are valid.
+}
+
+/** Checks whether the entered output workspace is valid.
+*  To be valid the only thing it needs is a name that is allowed by the ADS,
+* @see AnalysisDataServiceImpl
+*  @returns A user level description of the problem or "" if it is valid.
+*/
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::isValidOutputWs() const {
+  std::string error;
+  const std::string value = this->value();
+  if (!value.empty()) {
+    // Will the ADS accept it
+    error = AnalysisDataService::Instance().isValid(value);
+  } else {
+    if (isOptional())
+      error = ""; // Optional ones don't need a name
+    else
+      error = "Enter a name for the Output workspace";
+  }
+  return error;
+}
+
+/** Checks whether the entered workspace (that by this point we've found is
+* not in the ADS)
+*  is actually an optional workspace and so still valid.
+*  @returns A user level description of the problem or "" if it is valid.
+*/
+template <typename TYPE>
+std::string WorkspaceProperty<TYPE>::isOptionalWs() const {
+  std::string error;
+
+  if (m_workspaceName.empty()) {
+    if (isOptional()) {
+      error = "";
+    } else {
+      error = "Enter a name for the Input/InOut workspace";
+    }
+  } else {
+    error = "Workspace \"" + this->value() +
+            "\" was not found in the Analysis Data Service";
+  }
+
+  return error;
+}
+
+/// Reset the pointer to the workspace
+template <typename TYPE> void WorkspaceProperty<TYPE>::clear() {
+  Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
+      boost::shared_ptr<TYPE>();
+}
+
+/** Attempts to retreive the data from the ADS
+*  if the data is not foung the internal pointer is set to null.
+*/
+template <typename TYPE>
+void WorkspaceProperty<TYPE>::retrieveWorkspaceFromADS() {
+  // Try and get the workspace from the ADS, but don't worry if we can't
+  try {
+    Kernel::PropertyWithValue<boost::shared_ptr<TYPE>>::m_value =
+        AnalysisDataService::Instance().retrieveWS<TYPE>(m_workspaceName);
+  } catch (Kernel::Exception::NotFoundError &) {
+    // Set to null property if not found
+    this->clear();
+  }
+}
+
+} // namespace API
+} // namespace Mantid
diff --git a/Framework/API/src/ADSValidator.cpp b/Framework/API/src/ADSValidator.cpp
index f65fa6980997e00d5629aaed92cadaea44bdbe8a..ae2fa008d214189484b60801e22b9abe7fcc64d6 100644
--- a/Framework/API/src/ADSValidator.cpp
+++ b/Framework/API/src/ADSValidator.cpp
@@ -3,6 +3,7 @@
 #include "MantidKernel/StringTokenizer.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include <boost/make_shared.hpp>
+#include <sstream>
 
 namespace Mantid {
 namespace API {
@@ -40,7 +41,7 @@ void ADSValidator::setOptional(const bool setOptional) {
 */
 std::string
 ADSValidator::checkValidity(const std::vector<std::string> &value) const {
-  if (!m_isOptional && (value.size() == 0))
+  if (!m_isOptional && value.empty())
     return "Select a value";
   if (!m_AllowMultiSelection && (value.size() > 1)) {
     return "Only one workspace was expected.";
diff --git a/Framework/API/src/Algorithm.cpp b/Framework/API/src/Algorithm.cpp
index 06e3b2873308a5ea26382d68905c24e31102f278..72560dacef5b0f54005ec61a0cea7af493dbae30 100644
--- a/Framework/API/src/Algorithm.cpp
+++ b/Framework/API/src/Algorithm.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
 
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/EmptyValues.h"
diff --git a/Framework/API/src/AlgorithmFactory.cpp b/Framework/API/src/AlgorithmFactory.cpp
index 2fbb1e7cb52961923f8fcfb0e8e2e80e2860cf95..75b2e500be7b7579c41315dc271b304f97503ef3 100644
--- a/Framework/API/src/AlgorithmFactory.cpp
+++ b/Framework/API/src/AlgorithmFactory.cpp
@@ -2,6 +2,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include <sstream>
+#include <boost/algorithm/string.hpp>
 #include "MantidAPI/AlgorithmFactory.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidKernel/LibraryManager.h"
diff --git a/Framework/API/src/AlgorithmProxy.cpp b/Framework/API/src/AlgorithmProxy.cpp
index 335a606979c307c4a3638ef0c325882c7d3b3823..b822dcf6a977fb3e5c7e79ca0dd94f15c7e30cf0 100644
--- a/Framework/API/src/AlgorithmProxy.cpp
+++ b/Framework/API/src/AlgorithmProxy.cpp
@@ -1,10 +1,8 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/AlgorithmProxy.h"
 #include "MantidAPI/AlgorithmObserver.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/DeprecatedAlgorithm.h"
+#include <MantidKernel/StringTokenizer.h>
 
 #include <Poco/ActiveMethod.h>
 #include <Poco/ActiveResult.h>
@@ -15,10 +13,6 @@ using namespace Mantid::Kernel;
 namespace Mantid {
 namespace API {
 
-//----------------------------------------------------------------------
-// Public methods
-//----------------------------------------------------------------------
-
 /// Constructor
 AlgorithmProxy::AlgorithmProxy(Algorithm_sptr alg)
     : PropertyManagerOwner(),
diff --git a/Framework/API/src/AnalysisDataService.cpp b/Framework/API/src/AnalysisDataService.cpp
index d88362663d687c9f0c9dceb79e8d59498760b0d5..61350e192a94f657a9fb15f9b0ffab6fed0e255d 100644
--- a/Framework/API/src/AnalysisDataService.cpp
+++ b/Framework/API/src/AnalysisDataService.cpp
@@ -1,5 +1,6 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include <sstream>
 
 namespace Mantid {
 namespace API {
diff --git a/Framework/API/src/CompositeFunction.cpp b/Framework/API/src/CompositeFunction.cpp
index cfadf847862f1dfc070e839fa140bdbe0981866c..d0abd956f0ac8f3411025414936b11b48ca95e5f 100644
--- a/Framework/API/src/CompositeFunction.cpp
+++ b/Framework/API/src/CompositeFunction.cpp
@@ -416,8 +416,11 @@ size_t CompositeFunction::addFunction(IFunction_sptr f) {
  * @param i :: The index of the function to remove
  */
 void CompositeFunction::removeFunction(size_t i) {
-  if (i >= nFunctions())
-    throw std::out_of_range("Function index out of range.");
+  if (i >= nFunctions()) {
+    throw std::out_of_range("Function index (" + std::to_string(i) +
+                            ") out of range (" + std::to_string(nFunctions()) +
+                            ").");
+  }
 
   IFunction_sptr fun = getFunction(i);
 
@@ -477,8 +480,11 @@ void CompositeFunction::replaceFunctionPtr(const IFunction_sptr f_old,
  * @param f :: A pointer to the new function
  */
 void CompositeFunction::replaceFunction(size_t i, IFunction_sptr f) {
-  if (i >= nFunctions())
-    throw std::out_of_range("Function index out of range.");
+  if (i >= nFunctions()) {
+    throw std::out_of_range("Function index (" + std::to_string(i) +
+                            ") out of range (" + std::to_string(nFunctions()) +
+                            ").");
+  }
 
   IFunction_sptr fun = getFunction(i);
   size_t np_old = fun->nParams();
@@ -522,7 +528,9 @@ void CompositeFunction::replaceFunction(size_t i, IFunction_sptr f) {
  */
 IFunction_sptr CompositeFunction::getFunction(std::size_t i) const {
   if (i >= nFunctions()) {
-    throw std::out_of_range("Function index out of range.");
+    throw std::out_of_range("Function index (" + std::to_string(i) +
+                            ") out of range (" + std::to_string(nFunctions()) +
+                            ").");
   }
   return m_functions[i];
 }
@@ -534,7 +542,9 @@ IFunction_sptr CompositeFunction::getFunction(std::size_t i) const {
  */
 size_t CompositeFunction::functionIndex(std::size_t i) const {
   if (i >= nParams()) {
-    throw std::out_of_range("Function parameter index out of range.");
+    throw std::out_of_range("Function parameter index (" + std::to_string(i) +
+                            ") out of range (" + std::to_string(nParams()) +
+                            ").");
   }
   return m_IFunction[i];
 }
diff --git a/Framework/API/src/DataProcessorAlgorithm.cpp b/Framework/API/src/DataProcessorAlgorithm.cpp
index aaafb7ead939b200a967eae837dd21243e37bd47..1e61e78ce112c5048be2eba7f2840447fa7e7f85 100644
--- a/Framework/API/src/DataProcessorAlgorithm.cpp
+++ b/Framework/API/src/DataProcessorAlgorithm.cpp
@@ -236,8 +236,8 @@ Workspace_sptr DataProcessorAlgorithm::assemble(Workspace_sptr partialWS) {
 Workspace_sptr
 DataProcessorAlgorithm::assemble(const std::string &partialWSName,
                                  const std::string &outputWSName) {
-  std::string threadOutput = partialWSName;
 #ifdef MPI_BUILD
+  std::string threadOutput = partialWSName;
   Workspace_sptr partialWS =
       AnalysisDataService::Instance().retrieve(partialWSName);
   IAlgorithm_sptr gatherAlg = createChildAlgorithm("GatherWorkspaces");
@@ -252,6 +252,8 @@ DataProcessorAlgorithm::assemble(const std::string &partialWSName,
     threadOutput = outputWSName;
 #else
   UNUSED_ARG(outputWSName)
+  const std::string &threadOutput = partialWSName;
+
 #endif
   Workspace_sptr outputWS =
       AnalysisDataService::Instance().retrieve(threadOutput);
@@ -272,7 +274,7 @@ void DataProcessorAlgorithm::saveNexus(const std::string &outputWSName,
     saveOutput = false;
 #endif
 
-  if (saveOutput && outputFile.size() > 0) {
+  if (saveOutput && !outputFile.empty()) {
     IAlgorithm_sptr saveAlg = createChildAlgorithm("SaveNexus");
     saveAlg->setPropertyValue("Filename", outputFile);
     saveAlg->setPropertyValue("InputWorkspace", outputWSName);
diff --git a/Framework/API/src/DetectorInfo.cpp b/Framework/API/src/DetectorInfo.cpp
index 90a4ea42ac6bf384ae97a471187d81d0a5fc67ee..131eea5f3fe5265592338531761a2d45da5ce145 100644
--- a/Framework/API/src/DetectorInfo.cpp
+++ b/Framework/API/src/DetectorInfo.cpp
@@ -3,6 +3,7 @@
 #include "MantidGeometry/Instrument/ComponentHelper.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidBeamline/DetectorInfo.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/MultiThreaded.h"
 
@@ -17,9 +18,10 @@ namespace API {
  * `instrument`. Non-const methods of DetectorInfo may only be called if `pmap`
  * is not null. */
 DetectorInfo::DetectorInfo(
+    Beamline::DetectorInfo &detectorInfo,
     boost::shared_ptr<const Geometry::Instrument> instrument,
     Geometry::ParameterMap *pmap)
-    : m_pmap(pmap), m_instrument(instrument),
+    : m_detectorInfo(detectorInfo), m_pmap(pmap), m_instrument(instrument),
       m_lastDetector(PARALLEL_GET_MAX_THREADS),
       m_lastIndex(PARALLEL_GET_MAX_THREADS, -1) {
   // Note: This does not seem possible currently (the instrument objects is
@@ -32,6 +34,22 @@ DetectorInfo::DetectorInfo(
     m_detIDToIndex[m_detectorIDs[i]] = i;
 }
 
+/// Assigns the contents of the non-wrapping part of `rhs` to this.
+DetectorInfo &DetectorInfo::operator=(const DetectorInfo &rhs) {
+  if (detectorIDs() != rhs.detectorIDs())
+    throw std::runtime_error("DetectorInfo::operator=: Detector IDs in "
+                             "assignment do not match. Assignment not "
+                             "possible");
+  // Do NOT assign anything in the "wrapping" part of DetectorInfo. We simply
+  // assign the underlying Beamline::DetectorInfo.
+  m_detectorInfo = rhs.m_detectorInfo;
+  return *this;
+}
+
+/// Returns the size of the DetectorInfo, i.e., the number of detectors in the
+/// instrument.
+size_t DetectorInfo::size() const { return m_detectorIDs.size(); }
+
 /// Returns true if the detector is a monitor.
 bool DetectorInfo::isMonitor(const size_t index) const {
   return getDetector(index).isMonitor();
@@ -93,7 +111,20 @@ Kernel::Quat DetectorInfo::rotation(const size_t index) const {
   return getDetector(index).getRotation();
 }
 
-/// Set the absolute position of the detector with given index.
+/// Set the mask flag of the detector with given index. Not thread safe.
+void DetectorInfo::setMasked(const size_t index, bool masked) {
+  // Note that masking via the ParameterMap is actually thread safe, but it will
+  // not be with upcoming internal changes.
+  m_pmap->addBool(&getDetector(index), "masked", masked);
+}
+
+/** Sets all mask flags to false (unmasked). Not thread safe.
+ *
+ * This method was introduced to help with refactoring and may be removed in the
+ *future. */
+void DetectorInfo::clearMaskFlags() { m_pmap->clearParametersByName("masked"); }
+
+/// Set the absolute position of the detector with given index. Not thread safe.
 void DetectorInfo::setPosition(const size_t index,
                                const Kernel::V3D &position) {
   const auto &det = getDetector(index);
@@ -102,7 +133,7 @@ void DetectorInfo::setPosition(const size_t index,
   moveComponent(det, *m_pmap, position, positionType);
 }
 
-/// Set the absolute rotation of the detector with given index.
+/// Set the absolute rotation of the detector with given index. Not thread safe.
 void DetectorInfo::setRotation(const size_t index,
                                const Kernel::Quat &rotation) {
   const auto &det = getDetector(index);
@@ -111,7 +142,7 @@ void DetectorInfo::setRotation(const size_t index,
   rotateComponent(det, *m_pmap, rotation, rotationType);
 }
 
-/** Set the absolute position of the component `comp`.
+/** Set the absolute position of the component `comp`. Not thread safe.
  *
  * This may or may not be a detector. Even if it is not a detector it will
  * typically still influence detector positions. */
@@ -135,7 +166,7 @@ void DetectorInfo::setPosition(const Geometry::IComponent &comp,
   }
 }
 
-/** Set the absolute rotation of the component `comp`.
+/** Set the absolute rotation of the component `comp`. Not thread safe.
  *
  * This may or may not be a detector. Even if it is not a detector it will
  * typically still influence detector positions rotations. */
@@ -159,6 +190,11 @@ void DetectorInfo::setRotation(const Geometry::IComponent &comp,
   }
 }
 
+/// Return a const reference to the detector with given index.
+const Geometry::IDetector &DetectorInfo::detector(const size_t index) const {
+  return getDetector(index);
+}
+
 /// Returns the source position.
 Kernel::V3D DetectorInfo::sourcePosition() const {
   cacheSource();
diff --git a/Framework/API/src/ExperimentInfo.cpp b/Framework/API/src/ExperimentInfo.cpp
index dadae0f8977e48a052257134636bcd2c745bfcc6..96585529e444f824b4d03bcf607beb75d7c1f6fd 100644
--- a/Framework/API/src/ExperimentInfo.cpp
+++ b/Framework/API/src/ExperimentInfo.cpp
@@ -13,11 +13,15 @@
 #include "MantidGeometry/Instrument/ParComponentFactory.h"
 #include "MantidGeometry/Instrument/XMLInstrumentParameter.h"
 
+#include "MantidBeamline/DetectorInfo.h"
+
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/InstrumentInfo.h"
 #include "MantidKernel/Property.h"
 #include "MantidKernel/Strings.h"
+#include "MantidKernel/StringTokenizer.h"
+#include "MantidKernel/make_unique.h"
 
 #include <boost/algorithm/string.hpp>
 #include <boost/make_shared.hpp>
@@ -25,6 +29,7 @@
 
 #include <Poco/DirectoryIterator.h>
 #include <Poco/Path.h>
+#include <Poco/SAX/Attributes.h>
 #include <Poco/SAX/ContentHandler.h>
 #include <Poco/SAX/SAXParser.h>
 #include <nexus/NeXusException.hpp>
@@ -45,7 +50,8 @@ Kernel::Logger g_log("ExperimentInfo");
 ExperimentInfo::ExperimentInfo()
     : m_moderatorModel(), m_choppers(), m_sample(new Sample()),
       m_run(new Run()), m_parmap(new ParameterMap()),
-      sptr_instrument(new Instrument()) {}
+      sptr_instrument(new Instrument()),
+      m_detectorInfo(boost::make_shared<Beamline::DetectorInfo>(0)) {}
 
 /**
  * Constructs the object from a copy if the input. This leaves the new mutex
@@ -73,6 +79,7 @@ void ExperimentInfo::copyExperimentInfoFrom(const ExperimentInfo *other) {
   for (const auto &chopper : other->m_choppers) {
     m_choppers.push_back(chopper->clone());
   }
+  *m_detectorInfo = *other->m_detectorInfo;
 }
 
 /** Clone this ExperimentInfo class into a new one
@@ -134,12 +141,39 @@ const std::string ExperimentInfo::toString() const {
   return out.str();
 }
 
+// Helpers for setInstrument and getInstrument
+namespace {
+void checkDetectorInfoSize(const Instrument &instr,
+                           const Beamline::DetectorInfo &detInfo) {
+  const auto numDets = instr.getNumberDetectors();
+  if (numDets != detInfo.size())
+    throw std::runtime_error("ExperimentInfo: size mismatch between "
+                             "DetectorInfo and number of detectors in "
+                             "instrument");
+}
+
+std::unique_ptr<Beamline::DetectorInfo>
+makeDetectorInfo(const Instrument &oldInstr, const Instrument &newInstr) {
+  if (newInstr.hasDetectorInfo()) {
+    // We allocate a new DetectorInfo in case there is an Instrument holding a
+    // reference to our current DetectorInfo.
+    const auto &detInfo = newInstr.detectorInfo();
+    checkDetectorInfoSize(oldInstr, detInfo);
+    return Kernel::make_unique<Beamline::DetectorInfo>(detInfo);
+  } else {
+    // If there is no DetectorInfo in the instrument we create a default one.
+    const auto numDets = oldInstr.getNumberDetectors();
+    return Kernel::make_unique<Beamline::DetectorInfo>(numDets);
+  }
+}
+}
+
 /** Set the instrument
 * @param instr :: Shared pointer to an instrument.
 */
 void ExperimentInfo::setInstrument(const Instrument_const_sptr &instr) {
   invalidateInstrumentReferences();
-  m_detectorInfo = nullptr;
+  m_detectorInfoWrapper = nullptr;
   if (instr->isParametrized()) {
     sptr_instrument = instr->baseInstrument();
     m_parmap = instr->getParameterMap();
@@ -147,6 +181,7 @@ void ExperimentInfo::setInstrument(const Instrument_const_sptr &instr) {
     sptr_instrument = instr;
     m_parmap = boost::make_shared<ParameterMap>();
   }
+  m_detectorInfo = makeDetectorInfo(*sptr_instrument, *instr);
 }
 
 /** Get a shared pointer to the parametrized instrument associated with this
@@ -155,8 +190,11 @@ void ExperimentInfo::setInstrument(const Instrument_const_sptr &instr) {
 *  @return The instrument class
 */
 Instrument_const_sptr ExperimentInfo::getInstrument() const {
-  return Geometry::ParComponentFactory::createInstrument(sptr_instrument,
-                                                         m_parmap);
+  checkDetectorInfoSize(*sptr_instrument, *m_detectorInfo);
+  auto instrument = Geometry::ParComponentFactory::createInstrument(
+      sptr_instrument, m_parmap);
+  instrument->setDetectorInfo(m_detectorInfo);
+  return instrument;
 }
 
 /**  Returns a new copy of the instrument parameters
@@ -174,7 +212,7 @@ Geometry::ParameterMap &ExperimentInfo::instrumentParameters() {
     // and dropped reference count since previous check
     if (!m_parmap.unique()) {
       invalidateInstrumentReferences();
-      m_detectorInfo = nullptr;
+      m_detectorInfoWrapper = nullptr;
     }
     if (!m_parmap.unique()) {
       ParameterMap_sptr oldData = m_parmap;
@@ -313,24 +351,28 @@ void ExperimentInfo::populateInstrumentParameters() {
 
 /**
  * Replaces current parameter map with a copy of the given map
+ * Careful: Parameters that are stored in DetectorInfo are not automatically
+ * handled.
  * @ pmap const reference to parameter map whose copy replaces the current
  * parameter map
  */
 void ExperimentInfo::replaceInstrumentParameters(
     const Geometry::ParameterMap &pmap) {
   invalidateInstrumentReferences();
-  m_detectorInfo = nullptr;
+  m_detectorInfoWrapper = nullptr;
   this->m_parmap.reset(new ParameterMap(pmap));
 }
 
 /**
  * exchanges contents of current parameter map with contents of other map)
+ * Careful: Parameters that are stored in DetectorInfo are not automatically
+ * handled.
  * @ pmap reference to parameter map which would exchange its contents with
  * current map
  */
 void ExperimentInfo::swapInstrumentParameters(Geometry::ParameterMap &pmap) {
   invalidateInstrumentReferences();
-  m_detectorInfo = nullptr;
+  m_detectorInfoWrapper = nullptr;
   this->m_parmap->swap(pmap);
 }
 
@@ -342,15 +384,21 @@ void ExperimentInfo::swapInstrumentParameters(Geometry::ParameterMap &pmap) {
  * group.
  */
 void ExperimentInfo::cacheDetectorGroupings(const det2group_map &mapping) {
-  m_detgroups = mapping;
+  m_detgroups.clear();
+  for (const auto &item : mapping) {
+    m_det2group[item.first] = m_detgroups.size();
+    m_detgroups.push_back(item.second);
+  }
+  // Create default grouping if `mapping` is empty.
+  cacheDefaultDetectorGrouping();
 }
 
 /// Returns the detector IDs that make up the group that this ID is part of
-const std::vector<detid_t> &
+const std::set<detid_t> &
 ExperimentInfo::getGroupMembers(const detid_t detID) const {
-  auto iter = m_detgroups.find(detID);
-  if (iter != m_detgroups.end()) {
-    return iter->second;
+  auto iter = m_det2group.find(detID);
+  if (iter != m_det2group.end()) {
+    return m_detgroups[iter->second];
   } else {
     throw std::runtime_error(
         "ExperimentInfo::getGroupMembers - Unable to find ID " +
@@ -369,7 +417,7 @@ ExperimentInfo::getDetectorByID(const detid_t detID) const {
   if (m_detgroups.empty()) {
     return getInstrument()->getDetector(detID);
   } else {
-    const std::vector<detid_t> &ids = this->getGroupMembers(detID);
+    const auto &ids = this->getGroupMembers(detID);
     return getInstrument()->getDetectorG(ids);
   }
 }
@@ -887,12 +935,13 @@ ExperimentInfo::getInstrumentFilename(const std::string &instrumentName,
  * this reference.
  */
 const DetectorInfo &ExperimentInfo::detectorInfo() const {
-  if (!m_detectorInfo) {
+  if (!m_detectorInfoWrapper) {
     std::lock_guard<std::mutex> lock{m_detectorInfoMutex};
-    if (!m_detectorInfo)
-      m_detectorInfo = Kernel::make_unique<DetectorInfo>(getInstrument());
+    if (!m_detectorInfoWrapper)
+      m_detectorInfoWrapper =
+          Kernel::make_unique<DetectorInfo>(*m_detectorInfo, getInstrument());
   }
-  return *m_detectorInfo;
+  return *m_detectorInfoWrapper;
 }
 
 /** Return a non-const reference to the DetectorInfo object. Not thread safe.
@@ -902,18 +951,66 @@ DetectorInfo &ExperimentInfo::mutableDetectorInfo() {
 
   // We get the non-const ParameterMap reference *first* such that no copy is
   // triggered unless really necessary. The call to `instrumentParameters`
-  // releases the old m_detectorInfo to drop the reference count to the
+  // releases the old m_detectorInfoWrapper to drop the reference count to the
   // ParameterMap by 1 (DetectorInfo contains a parameterized Instrument, so the
-  // reference count to the ParameterMap is at least 2 if m_detectorInfo is not
-  // nullptr: 1 from the ExperimentInfo, 1 from DetectorInfo). If then the
-  // ExperimentInfo is not the sole owner of the ParameterMap a copy is
+  // reference count to the ParameterMap is at least 2 if m_detectorInfoWrapper
+  // is not nullptr: 1 from the ExperimentInfo, 1 from DetectorInfo). If then
+  // the ExperimentInfo is not the sole owner of the ParameterMap a copy is
   // triggered.
   auto pmap = &instrumentParameters();
   // Here `getInstrument` creates a parameterized instrument, increasing the
   // reference count to the ParameterMap. This has do be done *after* getting
   // the ParameterMap.
-  m_detectorInfo = Kernel::make_unique<DetectorInfo>(getInstrument(), pmap);
-  return *m_detectorInfo;
+  m_detectorInfoWrapper =
+      Kernel::make_unique<DetectorInfo>(*m_detectorInfo, getInstrument(), pmap);
+  return *m_detectorInfoWrapper;
+}
+
+/** Returns the number of detector groups.
+ *
+ * This is a virtual method. The default implementation returns grouping
+ * information cached in the ExperimentInfo. This is used in MDAlgorithms. The
+ * more common case is handled by the overload of this method in
+ * MatrixWorkspace. The purpose of this method is to be able to construct
+ * SpectrumInfo based on an ExperimentInfo object, including grouping
+ * information. Grouping information can be cached in ExperimentInfo, or can be
+ * obtained from child classes (MatrixWorkspace). */
+size_t ExperimentInfo::numberOfDetectorGroups() const {
+  std::call_once(m_defaultDetectorGroupingCached,
+                 &ExperimentInfo::cacheDefaultDetectorGrouping, this);
+
+  return m_detgroups.size();
+}
+
+/** Returns a set of detector IDs for a group.
+ *
+ * This is a virtual method. The default implementation returns grouping
+ * information cached in the ExperimentInfo. This is used in MDAlgorithms. The
+ * more common case is handled by the overload of this method in
+ * MatrixWorkspace. The purpose of this method is to be able to construct
+ * SpectrumInfo based on an ExperimentInfo object, including grouping
+ * information. Grouping information can be cached in ExperimentInfo, or can be
+ * obtained from child classes (MatrixWorkspace). */
+const std::set<detid_t> &
+ExperimentInfo::detectorIDsInGroup(const size_t index) const {
+  std::call_once(m_defaultDetectorGroupingCached,
+                 &ExperimentInfo::cacheDefaultDetectorGrouping, this);
+
+  return m_detgroups.at(index);
+}
+
+/** Sets up a default detector grouping.
+ *
+ * The purpose of this method is to work around potential issues of MDWorkspaces
+ * that do not have grouping information. In such cases a default 1:1
+ * mapping/grouping is generated by this method. See also issue #18252. */
+void ExperimentInfo::cacheDefaultDetectorGrouping() const {
+  if (!m_detgroups.empty())
+    return;
+  for (const auto detID : sptr_instrument->getDetectorIDs()) {
+    m_det2group[detID] = m_detgroups.size();
+    m_detgroups.push_back({detID});
+  }
 }
 
 /** Save the object to an open NeXus file.
diff --git a/Framework/API/src/FileBackedExperimentInfo.cpp b/Framework/API/src/FileBackedExperimentInfo.cpp
index 6435d659a0185d2583e7e897827364f52af50d4b..e0e587ff7d1032b964bbead09eabb03e0458ae8e 100644
--- a/Framework/API/src/FileBackedExperimentInfo.cpp
+++ b/Framework/API/src/FileBackedExperimentInfo.cpp
@@ -120,7 +120,7 @@ void FileBackedExperimentInfo::cacheDetectorGroupings(
  * Populate the object and returns the members of the group for a given ID
  * @param detID A detector ID to lookup
  */
-const std::vector<detid_t> &
+const std::set<detid_t> &
 FileBackedExperimentInfo::getGroupMembers(const detid_t detID) const {
   populateIfNotLoaded();
   return ExperimentInfo::getGroupMembers(detID);
@@ -277,6 +277,17 @@ void FileBackedExperimentInfo::setEFixed(const detid_t detID,
   ExperimentInfo::setEFixed(detID, value);
 }
 
+size_t FileBackedExperimentInfo::numberOfDetectorGroups() const {
+  populateIfNotLoaded();
+  return ExperimentInfo::numberOfDetectorGroups();
+}
+
+const std::set<detid_t> &
+FileBackedExperimentInfo::detectorIDsInGroup(const size_t index) const {
+  populateIfNotLoaded();
+  return ExperimentInfo::detectorIDsInGroup(index);
+}
+
 //------------------------------------------------------------------------------------------------------
 // Private members
 //------------------------------------------------------------------------------------------------------
diff --git a/Framework/API/src/FileFinder.cpp b/Framework/API/src/FileFinder.cpp
index a9b808e4915382c2a9bb94d01aab57f77112157d..5e6f1f8d668f249a9344a670f41ae0163bb87779 100644
--- a/Framework/API/src/FileFinder.cpp
+++ b/Framework/API/src/FileFinder.cpp
@@ -134,9 +134,8 @@ std::string FileFinderImpl::getFullPath(const std::string &filename,
     if (fName.find("*") != std::string::npos) {
 #endif
       Poco::Path path(searchPath, fName);
-      Poco::Path pathPattern(path);
       std::set<std::string> files;
-      Kernel::Glob::glob(pathPattern, files, m_globOption);
+      Kernel::Glob::glob(path, files, m_globOption);
       if (!files.empty()) {
         Poco::File matchPath(*files.begin());
         if (ignoreDirs && matchPath.isDirectory()) {
diff --git a/Framework/API/src/FileProperty.cpp b/Framework/API/src/FileProperty.cpp
index fd371724aa95a056925cd70392f2cc21c25eaebb..d2bfd6202604789f323e45051589d7af97d98771 100644
--- a/Framework/API/src/FileProperty.cpp
+++ b/Framework/API/src/FileProperty.cpp
@@ -1,6 +1,3 @@
-//-----------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------
 #include "MantidAPI/FileProperty.h"
 
 #include "MantidAPI/FileFinder.h"
@@ -13,6 +10,8 @@
 #include <Poco/File.h>
 #include <Poco/Path.h>
 
+#include <boost/make_shared.hpp>
+
 #include <algorithm>
 #include <cctype>
 
diff --git a/Framework/API/src/FunctionDomain1D.cpp b/Framework/API/src/FunctionDomain1D.cpp
index 36c1871078133f84248007f8106e62fdf35ca0d1..68ea72ce43fd83c81b9ed2e38aea68e41d6c717f 100644
--- a/Framework/API/src/FunctionDomain1D.cpp
+++ b/Framework/API/src/FunctionDomain1D.cpp
@@ -6,6 +6,10 @@
 namespace Mantid {
 namespace API {
 
+/// The constructor
+FunctionDomain1D::FunctionDomain1D(const double *x, size_t n)
+    : m_data(x), m_n(n), m_peakRadius(0) {}
+
 /// Convert to a vector
 std::vector<double> FunctionDomain1D::toVector() const {
   std::vector<double> res;
@@ -15,6 +19,17 @@ std::vector<double> FunctionDomain1D::toVector() const {
   return res;
 }
 
+/**
+ * Set a peak redius to pass to peak functions.
+ * @param radius :: New radius value.
+ */
+void FunctionDomain1D::setPeakRadius(int radius) { m_peakRadius = radius; }
+
+/**
+ * Get the peak radius.
+ */
+int FunctionDomain1D::getPeakRadius() const { return m_peakRadius; }
+
 /**
   * Create a domain from a vector.
   * @param xvalues :: Vector with function arguments to be copied from.
diff --git a/Framework/API/src/IFunction.cpp b/Framework/API/src/IFunction.cpp
index 119b7c04cc74762665b0e1e48f72675ae030e7d3..0496959f6c96281b51815d6e2325e3d750455cf5 100644
--- a/Framework/API/src/IFunction.cpp
+++ b/Framework/API/src/IFunction.cpp
@@ -138,6 +138,7 @@ void IFunction::addTies(const std::string &ties, bool isDefault) {
       }
     }
   }
+  applyTies();
 }
 
 /** Removes the tie off a parameter. The parameter becomes active
diff --git a/Framework/API/src/IMDWorkspace.cpp b/Framework/API/src/IMDWorkspace.cpp
index 3ab3913bd0051b7087ce51f8f2ae2c94fc081b4c..b2701e8a5318c19e86ce0e56aeab1da30e35b4cf 100644
--- a/Framework/API/src/IMDWorkspace.cpp
+++ b/Framework/API/src/IMDWorkspace.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/IMDWorkspace.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/IPropertyManager.h"
 #include "MantidKernel/ConfigService.h"
@@ -94,7 +95,7 @@ const std::string IMDWorkspace::toString() const {
   os << id() << "\n"
      << "Title: " + getTitle() << "\n";
   for (size_t i = 0; i < getNumDims(); i++) {
-    Geometry::IMDDimension_const_sptr dim = getDimension(i);
+    const auto &dim = getDimension(i);
     os << "Dim " << i << ": (" << dim->getName() << ") " << dim->getMinimum()
        << " to " << dim->getMaximum() << " in " << dim->getNBins() << " bins";
     // Also show the dimension ID string, if different than name
diff --git a/Framework/API/src/IPeakFunction.cpp b/Framework/API/src/IPeakFunction.cpp
index 63d4f9b66ce2fd173c72825e0d2ea1627330946e..99541fecf29ceac2357ea28ad76a78bb78057ae3 100644
--- a/Framework/API/src/IPeakFunction.cpp
+++ b/Framework/API/src/IPeakFunction.cpp
@@ -7,15 +7,17 @@
 #include "MantidAPI/PeakFunctionIntegrator.h"
 #include "MantidAPI/FunctionParameterDecorator.h"
 #include "MantidKernel/Exception.h"
-#include "MantidKernel/ConfigService.h"
 
 #include <boost/lexical_cast.hpp>
 #include <boost/make_shared.hpp>
 #include <cmath>
+#include <limits>
 
 namespace Mantid {
 namespace API {
 
+namespace {
+
 /** A Jacobian for individual functions
  */
 class PartialJacobian1 : public Jacobian {
@@ -78,21 +80,24 @@ protected:
   std::vector<double> m_J;
 };
 
-/// Default value for the peak radius
-int IPeakFunction::s_peakRadius = 5;
+/// Tolerance for determining the smallest significant value on the peak
+const double PEAK_TOLERANCE = 1e-14;
+/// "Infinite" value for the peak radius
+const int MAX_PEAK_RADIUS = std::numeric_limits<int>::max();
+
+} // namespace
 
 /**
-  * Constructor. Sets peak radius to the value of curvefitting.peakRadius
- * property
+  * Constructor.
   */
-IPeakFunction::IPeakFunction() {
-  int peakRadius;
-  if (Kernel::ConfigService::Instance().getValue("curvefitting.peakRadius",
-                                                 peakRadius)) {
-    if (peakRadius != s_peakRadius) {
-      setPeakRadius(peakRadius);
-    }
-  }
+IPeakFunction::IPeakFunction() : m_peakRadius(MAX_PEAK_RADIUS) {}
+
+void IPeakFunction::function(const FunctionDomain &domain,
+                             FunctionValues &values) const {
+  auto peakRadius =
+      dynamic_cast<const FunctionDomain1D &>(domain).getPeakRadius();
+  setPeakRadius(peakRadius);
+  IFunction1D::function(domain, values);
 }
 
 /**
@@ -108,7 +113,7 @@ IPeakFunction::IPeakFunction() {
 void IPeakFunction::function1D(double *out, const double *xValues,
                                const size_t nData) const {
   double c = this->centre();
-  double dx = fabs(s_peakRadius * this->fwhm());
+  double dx = fabs(m_peakRadius * this->fwhm());
   int i0 = -1;
   int n = 0;
   for (size_t i = 0; i < nData; ++i) {
@@ -139,7 +144,7 @@ void IPeakFunction::function1D(double *out, const double *xValues,
 void IPeakFunction::functionDeriv1D(Jacobian *out, const double *xValues,
                                     const size_t nData) {
   double c = this->centre();
-  double dx = fabs(s_peakRadius * this->fwhm());
+  double dx = fabs(m_peakRadius * this->fwhm());
   int i0 = -1;
   int n = 0;
   for (size_t i = 0; i < nData; ++i) {
@@ -159,23 +164,22 @@ void IPeakFunction::functionDeriv1D(Jacobian *out, const double *xValues,
   this->functionDerivLocal(&J, xValues + i0, n);
 }
 
-void IPeakFunction::setPeakRadius(const int &r) {
+void IPeakFunction::setPeakRadius(int r) const {
   if (r > 0) {
-    s_peakRadius = r;
-    std::string setting = std::to_string(r);
-    Kernel::ConfigService::Instance().setString("curvefitting.peakRadius",
-                                                setting);
+    m_peakRadius = r;
+  } else if (r == 0) {
+    m_peakRadius = MAX_PEAK_RADIUS;
   }
 }
 
 /// Returns the integral intensity of the peak function, using the peak radius
 /// to determine integration borders.
 double IPeakFunction::intensity() const {
-  double x0 = centre();
-  double dx = fabs(s_peakRadius * fwhm());
+  auto interval = getDomainInterval();
 
   PeakFunctionIntegrator integrator;
-  IntegrationResult result = integrator.integrate(*this, x0 - dx, x0 + dx);
+  IntegrationResult result =
+      integrator.integrate(*this, interval.first, interval.second);
 
   if (!result.success) {
     return 0.0;
@@ -226,5 +230,40 @@ std::string IPeakFunction::getCentreParameterName() const {
   return parameterName(jacobian.maxParam(0));
 }
 
+/// Get the interval on which the peak has all its values above a certain
+/// level. All values outside the interval are below that level.
+/// @param level :: A fraction of the peak height.
+/// @return A pair of doubles giving the bounds of the interval.
+std::pair<double, double> IPeakFunction::getDomainInterval(double level) const {
+  if (level < PEAK_TOLERANCE) {
+    level = PEAK_TOLERANCE;
+  }
+  double left = 0.0;
+  double right = 0.0;
+  auto h = height();
+  auto w = fwhm();
+  auto c = centre();
+  if (h == 0.0 || w == 0.0 || level >= 1.0) {
+    return std::make_pair(c, c);
+  }
+
+  auto findBound = [this, c, h, level](double dx) {
+    for (size_t i = 0; i < 100; ++i) {
+      double x = c + dx;
+      double y = 0.0;
+      this->functionLocal(&y, &x, 1);
+      if (fabs(y / h) < level) {
+        return x;
+      }
+      dx *= 2;
+    }
+    return c + dx;
+  };
+
+  left = findBound(-w);
+  right = findBound(w);
+  return std::make_pair(left, right);
+}
+
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/src/ImplicitFunctionParserFactory.cpp b/Framework/API/src/ImplicitFunctionParserFactory.cpp
index 9a13f894941560ad6e748903857b93a2fa91e4ef..14e1ab5afd4977a6c9b397a19295fa1e9c31d3aa 100644
--- a/Framework/API/src/ImplicitFunctionParserFactory.cpp
+++ b/Framework/API/src/ImplicitFunctionParserFactory.cpp
@@ -18,7 +18,7 @@ ImplicitFunctionParserFactoryImpl::create(const std::string &xmlString) const {
 ImplicitFunctionParser *
 ImplicitFunctionParserFactoryImpl::createImplicitFunctionParserFromXML(
     Poco::XML::Element *functionElement) const {
-  std::string name = functionElement->localName();
+  const std::string &name = functionElement->localName();
   if (name != "Function") {
     throw std::runtime_error(
         "Root node must be a Funtion element. Unable to determine parsers.");
diff --git a/Framework/API/src/LiveListenerFactory.cpp b/Framework/API/src/LiveListenerFactory.cpp
index 05821e0731d84969193df6fce97de8103ec0a4ff..b4803bb15405533c46af736e66e061e54ac61834 100644
--- a/Framework/API/src/LiveListenerFactory.cpp
+++ b/Framework/API/src/LiveListenerFactory.cpp
@@ -13,103 +13,107 @@ namespace {
 Kernel::Logger g_log("LiveListenerFactory");
 }
 
-/** Creates an instance of the appropriate listener for the given instrument,
- * and establishes the
- *  connection to the data acquisition.
- *  @param instrumentName The name of the instrument to 'listen to' (Note that
- * the argument has
- *                        different semantics to the base class create method).
- *  @param connect        Whether to connect the listener to the data stream for
- * the given instrument.
- *  @param properties     Property manager to copy property values to the
- * listener if it has any.
- *  @returns A shared pointer to the created ILiveListener implementation
- *  @throws Exception::NotFoundError If the requested listener is not registered
- *  @throws std::runtime_error If unable to connect to the listener at the
- * configured address
+/**
+ * Creates an instance of the appropriate listener for the given instrument,
+ * and establishes the connection to the data acquisition.
+ *
+ * @param instrumentName The name of the instrument to 'listen to' (Note that
+ *                       the argument has different semantics to the base class
+ *                       create method).
+ * @param connect        Whether to connect the listener to the data stream for
+ *                       the given instrument.
+ * @param properties     Property manager to copy property values to the
+ *                       listener if it has any.
+ * @param listenerConnectionName Name of LiveListenerInfo connection to use.
+ * @return A shared pointer to the created ILiveListener implementation
+ * @throws Exception::NotFoundError If the requested listener is not registered
+ * @throws std::runtime_error If unable to connect to the listener at the
+ *                            configured address.
  */
 boost::shared_ptr<ILiveListener> LiveListenerFactoryImpl::create(
     const std::string &instrumentName, bool connect,
-    const Kernel::IPropertyManager *properties) const {
-  ILiveListener_sptr listener;
-  // See if we know about the instrument with the given name
+    const Kernel::IPropertyManager *properties,
+    const std::string &listenerConnectionName) const {
   try {
-    Kernel::InstrumentInfo inst =
-        Kernel::ConfigService::Instance().getInstrument(instrumentName);
-    listener =
-        Kernel::DynamicFactory<ILiveListener>::create(inst.liveListener());
-    // set the properties
-    if (properties) {
-      listener->updatePropertyValues(*properties);
+    // Look up LiveListenerInfo based on given instrument and listener names
+    auto inst = Kernel::ConfigService::Instance().getInstrument(instrumentName);
+    auto info = inst.liveListenerInfo(listenerConnectionName);
+
+    // Defer creation logic to other create overload
+    return create(info, connect, properties);
+
+  } catch (Kernel::Exception::NotFoundError &) {
+    // Could not determine LiveListenerInfo for instrumentName
+    // Attempt to interpret instrumentName as listener class name instead, to
+    // support legacy usage in unit tests.
+    Kernel::LiveListenerInfo info(instrumentName);
+    return create(info, connect, properties);
+  }
+}
+
+/**
+ * Creates an instance of a specific LiveListener based on the given
+ * LiveListenerInfo instance. The only required data from LiveListenerInfo is
+ * the listener class name. If connect is set to true, a valid address is also
+ * required.
+ *
+ * @param info       LiveListenerInfo based on which to create the LiveListener
+ * @param connect    Whether to connect the listener to the data stream for the
+ *                   given instrument.
+ * @param properties Property manager to copy property values to the listener
+ *                   if it has any.
+ * @return A shared pointer to the created ILiveListener implementation
+ */
+boost::shared_ptr<ILiveListener> LiveListenerFactoryImpl::create(
+    const Kernel::LiveListenerInfo &info, bool connect,
+    const Kernel::IPropertyManager *properties) const {
+
+  ILiveListener_sptr listener =
+      Kernel::DynamicFactory<ILiveListener>::create(info.listener());
+
+  // Give LiveListener additional properties if provided
+  if (properties) {
+    listener->updatePropertyValues(*properties);
+  }
+
+  if (connect) {
+    try {
+      Poco::Net::SocketAddress address;
+
+      // To allow listener::connect to be called even when no address is given
+      if (!info.address().empty())
+        address = Poco::Net::SocketAddress(info.address());
+
+      // If we can't connect, throw an exception to be handled below
+      if (!listener->connect(address)) {
+        throw Poco::Exception("Connection attempt failed.");
+      }
     }
-    if (connect &&
-        !listener->connect(Poco::Net::SocketAddress(inst.liveDataAddress()))) {
-      // If we can't connect, log and throw an exception
+    // The Poco SocketAddress can throw all manner of exceptions if the address
+    // string it gets is badly formed, or it can't successfully look up the
+    // server given, or .......
+    // Just catch the base class exception
+    catch (Poco::Exception &pocoEx) {
       std::stringstream ss;
-      ss << "Unable to connect listener " << listener->name() << " to "
-         << inst.liveDataAddress();
+      ss << "Unable to connect listener [" << info.listener() << "] to ["
+         << info.address() << "]: " << pocoEx.what();
       g_log.debug(ss.str());
       throw std::runtime_error(ss.str());
     }
-  } catch (Kernel::Exception::NotFoundError &) {
-    // If we get to here either we don't know of the instrument name given, or
-    // the the live
-    // listener class given for the instrument is not known.
-    // During development, and for testing, we allow the direct passing in of a
-    // listener name
-    //   - so try to create that. Will throw if it doesn't exist - let that
-    //   exception get out
-    listener = Kernel::DynamicFactory<ILiveListener>::create(instrumentName);
-    if (connect)
-      listener->connect(Poco::Net::SocketAddress()); // Dummy argument for now
-  }
-  // The Poco SocketAddress can throw all manner of exceptions if the address
-  // string it gets is
-  // badly formed, or it can't successfully look up the server given, or .......
-  // Just catch the base class exception
-  catch (Poco::Exception &pocoEx) {
-    std::stringstream ss;
-    ss << "Unable to connect listener " << listener->name() << " to "
-       << instrumentName << ": " << pocoEx.what();
-    g_log.debug(ss.str());
-    throw std::runtime_error(ss.str());
   }
 
   // If we get to here, it's all good!
   return listener;
 }
 
-/** Tries to connect to the named instrument and returns an indicator of success
- * or failure.
- *  Useful for clients that want to just check whether it's possible to connect
- * to a live stream
- *  but not maintain and use the connection (e.g. for enabling or disabling some
- * GUI button).
- *  @param instrumentName The name of the instrument to connect to
- *  @return True if able to connect, false otherwise
- */
-bool LiveListenerFactoryImpl::checkConnection(
-    const std::string &instrumentName) const {
-  try {
-    // Create the live listener (which will try to connect).
-    // Don't capture the returned listener - just let it die.
-    create(instrumentName, true);
-    // If we get to here we have connected successfully.
-    return true;
-  } catch (std::runtime_error &) {
-    // We couldn't connect. Return false.
-    return false;
-  }
-}
-
-/** Override the DynamicFactory::createUnwrapped() method. We don't want it used
- * here.
- *  Making it private will prevent most accidental usage, though of course this
- * could
- *  be called through a DynamicFactory pointer or reference.
- *  @param className Argument that's ignored
- *  @returns Never
- *  @throws Exception::NotImplementedError every time!
+/**
+ * Override the DynamicFactory::createUnwrapped() method. We don't want it used
+ * here. Making it private will prevent most accidental usage, though of course
+ * this could be called through a DynamicFactory pointer or reference.
+ *
+ * @param className Argument that's ignored
+ * @returns Never
+ * @throws Exception::NotImplementedError every time!
  */
 ILiveListener *
 LiveListenerFactoryImpl::createUnwrapped(const std::string &className) const {
@@ -117,5 +121,6 @@ LiveListenerFactoryImpl::createUnwrapped(const std::string &className) const {
   throw Kernel::Exception::NotImplementedError(
       "Don't use this method - use the safe one!!!");
 }
+
 } // namespace Mantid
 } // namespace API
diff --git a/Framework/API/src/LogFilterGenerator.cpp b/Framework/API/src/LogFilterGenerator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..badb1d6af9db53d2f2a6c941a4c5a3a628bcb8a3
--- /dev/null
+++ b/Framework/API/src/LogFilterGenerator.cpp
@@ -0,0 +1,147 @@
+#include "MantidAPI/LogFilterGenerator.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidKernel/Logger.h"
+#include "MantidKernel/make_unique.h"
+#include "MantidKernel/TimeSeriesProperty.h"
+
+using Mantid::Kernel::LogFilter;
+using Mantid::Kernel::TimeSeriesProperty;
+using Mantid::Kernel::Property;
+
+namespace {
+/// static Logger definition
+Mantid::Kernel::Logger g_log("LogFilterGenerator");
+}
+
+namespace Mantid {
+namespace API {
+
+/**
+ * Constructor
+ * @param filterType :: [input] Filter by status, period, both or neither
+ * @param workspace :: [input] Workspace containing log data
+ */
+LogFilterGenerator::LogFilterGenerator(
+    const LogFilterGenerator::FilterType filterType,
+    const Mantid::API::MatrixWorkspace_const_sptr &workspace)
+    : m_filterType(filterType), m_run(workspace->run()) {}
+
+/**
+ * Constructor
+ * @param filterType :: [input] Filter by status, period, both or neither
+ * @param run :: [input] Run containing log data
+ */
+LogFilterGenerator::LogFilterGenerator(
+    const LogFilterGenerator::FilterType filterType,
+    const Mantid::API::Run &run)
+    : m_filterType(filterType), m_run(run) {}
+
+/**
+ * Generate log filter from given workspace and log name
+ * @param logName :: [input] Name of log to generate filter for
+ * @returns :: LogFilter with selected options
+ */
+std::unique_ptr<LogFilter>
+LogFilterGenerator::generateFilter(const std::string &logName) const {
+  const auto *logData = getLogData(logName);
+  if (!logData) {
+    throw std::invalid_argument("Workspace does not contain log " + logName);
+  }
+
+  // This will throw if the log is not a numeric time series.
+  // This behaviour is what we want, so don't catch the exception
+  auto flt = Mantid::Kernel::make_unique<LogFilter>(logData);
+
+  switch (m_filterType) {
+  case FilterType::None:
+    break; // Do nothing
+  case FilterType::Period:
+    filterByPeriod(flt.get());
+    break;
+  case FilterType::Status:
+    filterByStatus(flt.get());
+    break;
+  case FilterType::StatusAndPeriod:
+    filterByPeriod(flt.get());
+    filterByStatus(flt.get());
+    break;
+  default:
+    break;
+  }
+
+  return std::move(flt);
+}
+
+/**
+ * Adds a filter to the given LogFilter based on the "running" status log of the
+ * workspace.
+ * If that log is not present, does nothing.
+ * If the filter records start later than the data, add a value of "not running"
+ * at the start.
+ * @param filter :: [input, output] LogFilter to which filter will be added
+ */
+void LogFilterGenerator::filterByStatus(LogFilter *filter) const {
+  const auto status = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<bool> *>(
+      getLogData("running"));
+  if (!status) {
+    return;
+  }
+  filter->addFilter(*status);
+  const auto &time_value_map = filter->data()->valueAsCorrectMap();
+  const auto &firstTime = time_value_map.begin()->first;
+  // If filter records start later than the data we add a value at the
+  // filter's front
+  if (status->firstTime() > firstTime) {
+    // add a "not running" value to the status filter
+    Mantid::Kernel::TimeSeriesProperty<bool> atStart("tmp");
+    atStart.addValue(firstTime, false);
+    atStart.addValue(status->firstTime(), status->firstValue());
+    filter->addFilter(atStart);
+  }
+}
+
+/**
+ * Adds filters to the given LogFilter based on the first "period *" log in the
+ * workspace.
+ * If no such log is present, does nothing.
+ * @param filter :: [input, output] LogFilter to which filter will be added
+ */
+void LogFilterGenerator::filterByPeriod(LogFilter *filter) const {
+  const auto &logs = m_run.getLogData();
+  for (const auto &log : logs) {
+    if (log->name().find("period ") == 0) {
+      try {
+        const auto periodLog =
+            dynamic_cast<Mantid::Kernel::TimeSeriesProperty<bool> *>(log);
+        if (periodLog) {
+          filter->addFilter(*periodLog);
+        } else {
+          g_log.warning("Could not filter by period");
+          return;
+        }
+      } catch (const std::runtime_error &err) {
+        g_log.warning() << "Could not filter by period: " << err.what();
+        return;
+      }
+      break;
+    }
+  }
+}
+
+/**
+ * Get log data from workspace
+ * @param logName :: [input] Name of log to get
+ * @returns :: Pointer to log, or null if log does not exist in workspace
+ */
+Property *LogFilterGenerator::getLogData(const std::string &logName) const {
+  try {
+    const auto logData = m_run.getLogData(logName);
+    return logData;
+  } catch (const std::runtime_error &) {
+    g_log.warning("Could not find log value " + logName + " in workspace");
+    return nullptr;
+  }
+}
+
+} // namespace API
+} // namespace Mantid
diff --git a/Framework/API/src/LogManager.cpp b/Framework/API/src/LogManager.cpp
index 1bbffa8810d0cafedf603c6eeb89912ea3ef1ade..81780756f18eecf3c85c8c65ad0db5988159f7ad 100644
--- a/Framework/API/src/LogManager.cpp
+++ b/Framework/API/src/LogManager.cpp
@@ -1,11 +1,10 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/LogManager.h"
+#include "MantidKernel/Cache.h"
 #include "MantidKernel/PropertyNexus.h"
-
 #include "MantidKernel/TimeSeriesProperty.h"
 
+#include <nexus/NeXusFile.hpp>
+
 namespace Mantid {
 namespace API {
 
@@ -93,6 +92,27 @@ const char *LogManager::PROTON_CHARGE_LOG_NAME = "gd_prtn_chrg";
 // Public member functions
 //----------------------------------------------------------------------
 
+LogManager::LogManager()
+    : m_singleValueCache(Kernel::make_unique<Kernel::Cache<
+          std::pair<std::string, Kernel::Math::StatisticType>, double>>()) {}
+
+LogManager::LogManager(const LogManager &other)
+    : m_manager(other.m_manager),
+      m_singleValueCache(Kernel::make_unique<Kernel::Cache<
+          std::pair<std::string, Kernel::Math::StatisticType>, double>>(
+          *other.m_singleValueCache)) {}
+
+// Defined as default in source for forward declaration with std::unique_ptr.
+LogManager::~LogManager() = default;
+
+LogManager &LogManager::operator=(const LogManager &other) {
+  m_manager = other.m_manager;
+  m_singleValueCache = Kernel::make_unique<Kernel::Cache<
+      std::pair<std::string, Kernel::Math::StatisticType>, double>>(
+      *other.m_singleValueCache);
+  return *this;
+}
+
 /**
 * Set the run start and end
 * @param start :: The run start
@@ -211,7 +231,7 @@ void LogManager::splitByTime(TimeSplitterType &splitter,
  */
 void LogManager::filterByLog(const Kernel::TimeSeriesProperty<bool> &filter) {
   // This will invalidate the cache
-  m_singleValueCache.clear();
+  m_singleValueCache->clear();
   m_manager.filterByProperty(filter);
 }
 
@@ -260,7 +280,7 @@ bool LogManager::hasProperty(const std::string &name) const {
 void LogManager::removeProperty(const std::string &name, bool delProperty) {
   // Remove any cached entries for this log. Need to make this more general
   for (unsigned int stat = 0; stat < 7; ++stat) {
-    m_singleValueCache.removeCache(
+    m_singleValueCache->removeCache(
         std::make_pair(name, static_cast<Math::StatisticType>(stat)));
   }
   m_manager.removeProperty(name, delProperty);
@@ -329,7 +349,7 @@ double LogManager::getPropertyAsSingleValue(
     const std::string &name, Kernel::Math::StatisticType statistic) const {
   double singleValue(0.0);
   const auto key = std::make_pair(name, statistic);
-  if (!m_singleValueCache.getCache(key, singleValue)) {
+  if (!m_singleValueCache->getCache(key, singleValue)) {
     const Property *log = getProperty(name);
     if (!convertPropertyToDouble(log, singleValue, statistic)) {
       if (const auto stringLog =
@@ -349,7 +369,7 @@ double LogManager::getPropertyAsSingleValue(
       }
     }
     // Put it in the cache
-    m_singleValueCache.setCache(key, singleValue);
+    m_singleValueCache->setCache(key, singleValue);
   }
   return singleValue;
 }
diff --git a/Framework/API/src/MDGeometry.cpp b/Framework/API/src/MDGeometry.cpp
index eff19ac2c119057b26f94fe0a3624032952160f8..4cb8ebc8853db77e316a6d3a6113664223e7bc4c 100644
--- a/Framework/API/src/MDGeometry.cpp
+++ b/Framework/API/src/MDGeometry.cpp
@@ -1,9 +1,12 @@
 #include "MantidAPI/MDGeometry.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/CoordTransform.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
+#include "MantidKernel/make_unique.h"
+#include <Poco/NObserver.h>
 #include <boost/make_shared.hpp>
 
 using namespace Mantid::Kernel;
@@ -13,14 +16,54 @@ using namespace Mantid::Geometry;
 namespace Mantid {
 namespace API {
 
+class MDGeometryNotificationHelper {
+public:
+  explicit MDGeometryNotificationHelper(MDGeometry &parent)
+      : m_parent(parent),
+        m_delete_observer(
+            *this, &MDGeometryNotificationHelper::deleteNotificationReceived) {}
+
+  ~MDGeometryNotificationHelper() {
+    if (m_observingDelete) {
+      // Stop watching once object is deleted
+      API::AnalysisDataService::Instance().notificationCenter.removeObserver(
+          m_delete_observer);
+    }
+  }
+
+  void watchForWorkspaceDeletions() {
+    if (!m_observingDelete) {
+      API::AnalysisDataService::Instance().notificationCenter.addObserver(
+          m_delete_observer);
+      m_observingDelete = true;
+    }
+  }
+
+  void deleteNotificationReceived(
+      Mantid::API::WorkspacePreDeleteNotification_ptr notice) {
+    m_parent.deleteNotificationReceived(notice->object());
+  }
+
+private:
+  MDGeometry &m_parent;
+
+  /// Poco delete notification observer object
+  Poco::NObserver<MDGeometryNotificationHelper, WorkspacePreDeleteNotification>
+      m_delete_observer;
+
+  /// Set to True when the m_delete_observer is observing workspace deletions.
+  bool m_observingDelete{false};
+};
+
 //----------------------------------------------------------------------------------------------
 /** Constructor
  */
 MDGeometry::MDGeometry()
     : m_dimensions(), m_originalWorkspaces(), m_origin(),
       m_transforms_FromOriginal(), m_transforms_ToOriginal(),
-      m_delete_observer(*this, &MDGeometry::deleteNotificationReceived),
-      m_observingDelete(false), m_Wtransf(3, 3, true), m_basisVectors() {}
+      m_notificationHelper(
+          Kernel::make_unique<MDGeometryNotificationHelper>(*this)),
+      m_Wtransf(3, 3, true), m_basisVectors() {}
 
 //----------------------------------------------------------------------------------------------
 /** Copy Constructor
@@ -28,9 +71,9 @@ MDGeometry::MDGeometry()
 MDGeometry::MDGeometry(const MDGeometry &other)
     : m_dimensions(), m_originalWorkspaces(), m_origin(other.m_origin),
       m_transforms_FromOriginal(), m_transforms_ToOriginal(),
-      m_delete_observer(*this, &MDGeometry::deleteNotificationReceived),
-      m_observingDelete(false), m_Wtransf(other.m_Wtransf),
-      m_basisVectors(other.m_basisVectors) {
+      m_notificationHelper(
+          Kernel::make_unique<MDGeometryNotificationHelper>(*this)),
+      m_Wtransf(other.m_Wtransf), m_basisVectors(other.m_basisVectors) {
   // Perform a deep copy of the dimensions
   std::vector<Mantid::Geometry::IMDDimension_sptr> dimensions;
   for (size_t d = 0; d < other.getNumDims(); d++) {
@@ -84,15 +127,7 @@ void MDGeometry::clearOriginalWorkspaces() { m_originalWorkspaces.clear(); }
 //----------------------------------------------------------------------------------------------
 /** Destructor
  */
-MDGeometry::~MDGeometry() {
-
-  if (m_observingDelete) {
-    // Stop watching once object is deleted
-    API::AnalysisDataService::Instance().notificationCenter.removeObserver(
-        m_delete_observer);
-  }
-  m_dimensions.clear();
-}
+MDGeometry::~MDGeometry() { m_dimensions.clear(); }
 
 //----------------------------------------------------------------------------------------------
 /** Initialize the geometry
@@ -343,12 +378,7 @@ void MDGeometry::setOriginalWorkspace(boost::shared_ptr<Workspace> ws,
   if (index >= m_originalWorkspaces.size())
     m_originalWorkspaces.resize(index + 1);
   m_originalWorkspaces[index] = ws;
-  // Watch for workspace deletions
-  if (!m_observingDelete) {
-    API::AnalysisDataService::Instance().notificationCenter.addObserver(
-        m_delete_observer);
-    m_observingDelete = true;
-  }
+  m_notificationHelper->watchForWorkspaceDeletions();
 }
 
 //---------------------------------------------------------------------------------------------------
@@ -398,14 +428,13 @@ void MDGeometry::transformDimensions(std::vector<double> &scaling,
  * This checks if the "original workspace" in this object is being deleted,
  * and removes the reference to it to allow it to be destructed properly.
  *
- * @param notice :: notification of workspace deletion
+ * @param deleted :: The deleted workspace
  */
 void MDGeometry::deleteNotificationReceived(
-    Mantid::API::WorkspacePreDeleteNotification_ptr notice) {
+    const boost::shared_ptr<const Workspace> &deleted) {
   for (auto &original : m_originalWorkspaces) {
     if (original) {
       // Compare the pointer being deleted to the one stored as the original.
-      Workspace_sptr deleted = notice->object();
       if (original == deleted) {
         // Clear the reference
         original.reset();
diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp
index a01ae3ab1cf23717e549eb2ccdfe74659cee9a64..84fdda8e0e3536a76bb03eba32fe3b51b599d465 100644
--- a/Framework/API/src/MatrixWorkspace.cpp
+++ b/Framework/API/src/MatrixWorkspace.cpp
@@ -14,6 +14,7 @@
 #include "MantidGeometry/MDGeometry/GeneralFrame.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/MDUnit.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidIndexing/IndexInfo.h"
 
@@ -968,35 +969,6 @@ bool MatrixWorkspace::isCommonBins() const {
   return m_isCommonBinsFlag;
 }
 
-/**
-* Mask a given workspace index, setting the data and error values to zero
-* @param index :: The index within the workspace to mask
-*/
-void MatrixWorkspace::maskWorkspaceIndex(const std::size_t index) {
-  if (index >= this->getNumberHistograms()) {
-    throw Kernel::Exception::IndexError(
-        index, this->getNumberHistograms(),
-        "MatrixWorkspace::maskWorkspaceIndex,index");
-  }
-
-  auto &spec = this->getSpectrum(index);
-
-  // Virtual method clears the spectrum as appropriate
-  spec.clearData();
-
-  const auto dets = spec.getDetectorIDs();
-  for (auto detId : dets) {
-    try {
-      if (const Geometry::Detector *det =
-              dynamic_cast<const Geometry::Detector *>(
-                  sptr_instrument->getDetector(detId).get())) {
-        m_parmap->addBool(det, "masked", true); // Thread-safe method
-      }
-    } catch (Kernel::Exception::NotFoundError &) {
-    }
-  }
-}
-
 /** Called by the algorithm MaskBins to mask a single bin for the first time,
 * algorithms that later propagate the
 *  the mask from an input to the output should call flagMasked() instead. Here
@@ -2025,6 +1997,19 @@ MatrixWorkspace::detectorIDs(const size_t index) const {
   return getSpectrum(index).getDetectorIDs();
 }
 
+/// Returns the number of detector groups. This is equal to the number of
+/// spectra.
+size_t MatrixWorkspace::numberOfDetectorGroups() const {
+  return getNumberHistograms();
+}
+
+/// Returns a set of detector IDs for a group. This is equal to the detector IDs
+/// of the spectrum at given index.
+const std::set<detid_t> &
+MatrixWorkspace::detectorIDsInGroup(const size_t index) const {
+  return getSpectrum(index).getDetectorIDs();
+}
+
 } // namespace API
 } // Namespace Mantid
 
diff --git a/Framework/API/src/MatrixWorkspaceMDIterator.cpp b/Framework/API/src/MatrixWorkspaceMDIterator.cpp
index 94894e7efd3494a1827dadc45ac51aea076e2264..a50a0164233f3888baac601a5f1146975b949cc4 100644
--- a/Framework/API/src/MatrixWorkspaceMDIterator.cpp
+++ b/Framework/API/src/MatrixWorkspaceMDIterator.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/MatrixWorkspaceMDIterator.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/VMD.h"
@@ -25,7 +26,7 @@ MatrixWorkspaceMDIterator::MatrixWorkspaceMDIterator(
     Mantid::Geometry::MDImplicitFunction *function, size_t beginWI,
     size_t endWI)
     : m_ws(workspace), m_pos(0), m_max(0), m_function(function),
-      m_errorIsCached(false) {
+      m_errorIsCached(false), m_spectrumInfo(m_ws->spectrumInfo()) {
   if (!m_ws)
     throw std::runtime_error(
         "MatrixWorkspaceMDIterator::ctor() NULL MatrixWorkspace");
@@ -258,14 +259,10 @@ signal_t MatrixWorkspaceMDIterator::getInnerError(size_t /*index*/) const {
  * masked, or if there is no detector at that index.
 */
 bool MatrixWorkspaceMDIterator::getIsMasked() const {
-  Mantid::Geometry::IDetector_const_sptr det =
-      m_ws->getDetector(m_workspaceIndex);
-  if (det != nullptr) {
-    return det->isMasked();
-  } else {
-    return true; // TODO. Check whether it's better to return true or false
-                 // under these circumstances.
+  if (!m_spectrumInfo.hasDetectors(m_workspaceIndex)) {
+    return true;
   }
+  return m_spectrumInfo.isMasked(m_workspaceIndex);
 }
 
 /**
diff --git a/Framework/API/src/MultiPeriodGroupWorker.cpp b/Framework/API/src/MultiPeriodGroupWorker.cpp
index bc9e3e993c07472a0361231894f6c883d0abfb6d..3dd502cb142ffae697cf58403e5461ff1f986524 100644
--- a/Framework/API/src/MultiPeriodGroupWorker.cpp
+++ b/Framework/API/src/MultiPeriodGroupWorker.cpp
@@ -1,10 +1,12 @@
 #include "MantidAPI/MultiPeriodGroupWorker.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/Property.h"
+#include "MantidKernel/Strings.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::Kernel;
 
@@ -94,8 +96,7 @@ MultiPeriodGroupWorker::findMultiPeriodGroups(
     }
   }
 
-  if ((vecMultiPeriodWorkspaceGroups.size() != 0) &&
-      (vecWorkspaceGroups.size() != 0)) {
+  if (!vecMultiPeriodWorkspaceGroups.empty() && !vecWorkspaceGroups.empty()) {
     throw std::invalid_argument(
         "The input contains a mix of multi-period and other workspaces.");
   }
diff --git a/Framework/API/src/MultipleExperimentInfos.cpp b/Framework/API/src/MultipleExperimentInfos.cpp
index 4d2c02a1b56a682adc6fb229796a9378f5d7c560..8838efe6d80c844b59bb3248c1c04629fb2e2b30 100644
--- a/Framework/API/src/MultipleExperimentInfos.cpp
+++ b/Framework/API/src/MultipleExperimentInfos.cpp
@@ -3,6 +3,7 @@
 #include "MantidKernel/System.h"
 
 #include <boost/make_shared.hpp>
+#include <sstream>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/API/src/MultipleFileProperty.cpp b/Framework/API/src/MultipleFileProperty.cpp
index a961771273cf7a3afdb4243b50f47c407e2e7ebf..39a93061dcae90a6b683be5164f770bd56f3c05f 100644
--- a/Framework/API/src/MultipleFileProperty.cpp
+++ b/Framework/API/src/MultipleFileProperty.cpp
@@ -6,6 +6,7 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MultiFileValidator.h"
 #include "MantidKernel/Property.h"
+#include "MantidKernel/PropertyHelper.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/VectorHelper.h"
 
diff --git a/Framework/API/src/NearestNeighbourInfo.cpp b/Framework/API/src/NearestNeighbourInfo.cpp
index ab6832c24f4ba4ab8ff38daeff670c549119939c..7612bddd1e6a909f9af5e9dfe101c98d240b3f6a 100644
--- a/Framework/API/src/NearestNeighbourInfo.cpp
+++ b/Framework/API/src/NearestNeighbourInfo.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/NearestNeighbourInfo.h"
+#include "MantidAPI/NearestNeighbours.h"
 #include "MantidAPI/MatrixWorkspace.h"
-#include "MantidAPI/SpectrumDetectorMapping.h"
+#include "MantidKernel/make_unique.h"
 
 namespace Mantid {
 namespace API {
@@ -15,10 +16,18 @@ namespace API {
 NearestNeighbourInfo::NearestNeighbourInfo(const MatrixWorkspace &workspace,
                                            const bool ignoreMaskedDetectors,
                                            const int nNeighbours)
-    : m_workspace(workspace),
-      m_nearestNeighbours(nNeighbours, workspace.getInstrument(),
-                          SpectrumDetectorMapping(&workspace).getMapping(),
-                          ignoreMaskedDetectors) {}
+    : m_workspace(workspace) {
+  std::vector<specnum_t> spectrumNumbers;
+  for (size_t i = 0; i < m_workspace.getNumberHistograms(); ++i)
+    spectrumNumbers.push_back(m_workspace.getSpectrum(i).getSpectrumNo());
+
+  m_nearestNeighbours = Kernel::make_unique<NearestNeighbours>(
+      nNeighbours, workspace.spectrumInfo(), std::move(spectrumNumbers),
+      ignoreMaskedDetectors);
+}
+
+// Defined as default in source for forward declaration with std::unique_ptr.
+NearestNeighbourInfo::~NearestNeighbourInfo() = default;
 
 /** Queries the NearestNeighbours object for the selected detector.
 * NOTE! getNeighbours(spectrumNumber, radius) is MUCH faster.
@@ -39,7 +48,7 @@ NearestNeighbourInfo::getNeighbours(const Geometry::IDetector *comp,
                                            "detector",
                                            comp->getID());
   }
-  return m_nearestNeighbours.neighboursInRadius(spectra[0], radius);
+  return m_nearestNeighbours->neighboursInRadius(spectra[0], radius);
 }
 
 /** Queries the NearestNeighbours object for the selected spectrum number.
@@ -50,7 +59,7 @@ NearestNeighbourInfo::getNeighbours(const Geometry::IDetector *comp,
 */
 std::map<specnum_t, Kernel::V3D>
 NearestNeighbourInfo::getNeighbours(specnum_t spec, const double radius) const {
-  return m_nearestNeighbours.neighboursInRadius(spec, radius);
+  return m_nearestNeighbours->neighboursInRadius(spec, radius);
 }
 
 /** Queries the NearestNeighbours object for the selected spectrum number.
@@ -60,7 +69,7 @@ NearestNeighbourInfo::getNeighbours(specnum_t spec, const double radius) const {
 */
 std::map<specnum_t, Kernel::V3D>
 NearestNeighbourInfo::getNeighboursExact(specnum_t spec) const {
-  return m_nearestNeighbours.neighbours(spec);
+  return m_nearestNeighbours->neighbours(spec);
 }
 
 } // namespace API
diff --git a/Framework/Geometry/src/Instrument/NearestNeighbours.cpp b/Framework/API/src/NearestNeighbours.cpp
similarity index 71%
rename from Framework/Geometry/src/Instrument/NearestNeighbours.cpp
rename to Framework/API/src/NearestNeighbours.cpp
index 212183a65365e2e0c64e26c23a68280dafcd6c14..9f094269ade399b5944cac26ba3f19f0ada12663 100644
--- a/Framework/Geometry/src/Instrument/NearestNeighbours.cpp
+++ b/Framework/API/src/NearestNeighbours.cpp
@@ -1,44 +1,35 @@
-#include "MantidGeometry/Instrument/NearestNeighbours.h"
+#include "MantidAPI/NearestNeighbours.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 // Nearest neighbours library
 #include "MantidKernel/ANN/ANN.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Timer.h"
 
 namespace Mantid {
-namespace Geometry {
+using namespace Geometry;
+namespace API {
 using Mantid::detid_t;
 using Kernel::V3D;
 
-/**
-*Constructor
-*@param instrument :: A shared pointer to Instrument object
-*@param spectraMap :: A reference to the spectra-detector mapping
-*@param ignoreMaskedDetectors :: flag indicating that masked detectors should be
-* ignored.
-*/
-NearestNeighbours::NearestNeighbours(
-    boost::shared_ptr<const Instrument> instrument,
-    const ISpectrumDetectorMapping &spectraMap, bool ignoreMaskedDetectors)
-    : m_instrument(instrument), m_spectraMap(spectraMap), m_noNeighbours(8),
-      m_cutoff(-DBL_MAX), m_radius(0),
-      m_bIgnoreMaskedDetectors(ignoreMaskedDetectors) {
-  this->build(m_noNeighbours);
-}
-
 /**
  * Constructor
  * @param nNeighbours :: Number of neighbours to use
- * @param instrument :: A shared pointer to Instrument object
- * @param spectraMap :: A reference to the spectra-detector mapping
+ * @param spectrumInfo :: Reference to the SpectrumInfo of the underlying
+ * workspace
+ * @param spectrumNumbers :: Vector of spectrum numbers, defining the ordering
+ * of spectra
  * @param ignoreMaskedDetectors :: flag indicating that masked detectors should
  * be ignored.
  */
-NearestNeighbours::NearestNeighbours(
-    int nNeighbours, boost::shared_ptr<const Instrument> instrument,
-    const ISpectrumDetectorMapping &spectraMap, bool ignoreMaskedDetectors)
-    : m_instrument(instrument), m_spectraMap(spectraMap),
+NearestNeighbours::NearestNeighbours(int nNeighbours,
+                                     const SpectrumInfo &spectrumInfo,
+                                     std::vector<specnum_t> spectrumNumbers,
+                                     bool ignoreMaskedDetectors)
+    : m_spectrumInfo(spectrumInfo),
+      m_spectrumNumbers(std::move(spectrumNumbers)),
       m_noNeighbours(nNeighbours), m_cutoff(-DBL_MAX), m_radius(0),
       m_bIgnoreMaskedDetectors(ignoreMaskedDetectors) {
   this->build(m_noNeighbours);
@@ -119,14 +110,13 @@ NearestNeighbours::neighboursInRadius(const specnum_t spectrum,
  * the graph
  */
 void NearestNeighbours::build(const int noNeighbours) {
-  std::map<specnum_t, IDetector_const_sptr> spectraDets =
-      getSpectraDetectors(m_instrument, m_spectraMap);
-  if (spectraDets.empty()) {
+  const auto indices = getSpectraDetectors();
+  if (indices.empty()) {
     throw std::runtime_error(
         "NearestNeighbours::build - Cannot find any spectra");
   }
   const int nspectra =
-      static_cast<int>(spectraDets.size()); // ANN only deals with integers
+      static_cast<int>(indices.size()); // ANN only deals with integers
   if (noNeighbours >= nspectra) {
     throw std::invalid_argument(
         "NearestNeighbours::build - Invalid number of neighbours");
@@ -140,18 +130,16 @@ void NearestNeighbours::build(const int noNeighbours) {
   BoundingBox bbox;
   // Base the scaling on the first detector, should be adequate but we can look
   // at this
-  IDetector_const_sptr firstDet = (*spectraDets.begin()).second;
-  firstDet->getBoundingBox(bbox);
+  const auto &firstDet = m_spectrumInfo.detector(indices.front());
+  firstDet.getBoundingBox(bbox);
   m_scale = V3D(bbox.width());
   ANNpointArray dataPoints = annAllocPts(nspectra, 3);
   MapIV pointNoToVertex;
 
-  std::map<specnum_t, IDetector_const_sptr>::const_iterator detIt;
   int pointNo = 0;
-  for (detIt = spectraDets.begin(); detIt != spectraDets.end(); ++detIt) {
-    IDetector_const_sptr detector = detIt->second;
-    const specnum_t spectrum = detIt->first;
-    V3D pos = detector->getPos() / m_scale;
+  for (const auto i : indices) {
+    const specnum_t spectrum = m_spectrumNumbers[i];
+    V3D pos = m_spectrumInfo.position(i) / m_scale;
     dataPoints[pointNo][0] = pos.X();
     dataPoints[pointNo][1] = pos.Y();
     dataPoints[pointNo][2] = pos.Z();
@@ -167,7 +155,7 @@ void NearestNeighbours::build(const int noNeighbours) {
   auto nnIndexList = new ANNidx[m_noNeighbours];
   auto nnDistList = new ANNdist[m_noNeighbours];
 
-  for (detIt = spectraDets.begin(); detIt != spectraDets.end(); ++detIt) {
+  for (const auto idx : indices) {
     ANNpoint scaledPos = dataPoints[pointNo];
     annTree->annkSearch(scaledPos,      // Point to search nearest neighbours of
                         m_noNeighbours, // Number of neighbours to find (8)
@@ -185,8 +173,8 @@ void NearestNeighbours::build(const int noNeighbours) {
                       m_scale;
       V3D distance = neighbour - realPos;
       double separation = distance.norm();
-      boost::add_edge(m_specToVertex[detIt->first], // from
-                      pointNoToVertex[index],       // to
+      boost::add_edge(m_specToVertex[m_spectrumNumbers[idx]], // from
+                      pointNoToVertex[index],                 // to
                       distance, m_graph);
       if (separation > m_cutoff) {
         m_cutoff = separation;
@@ -235,30 +223,17 @@ NearestNeighbours::defaultNeighbours(const specnum_t spectrum) const {
   }
 }
 
-/**
- * Get the list of detectors associated with a spectra
- * @param instrument :: A pointer to the instrument
- * @param spectraMap :: A reference to the spectra map
- * @returns A map of spectra number to detector pointer
- */
-std::map<specnum_t, IDetector_const_sptr>
-NearestNeighbours::getSpectraDetectors(
-    boost::shared_ptr<const Instrument> instrument,
-    const ISpectrumDetectorMapping &spectraMap) {
-  std::map<specnum_t, IDetector_const_sptr> spectra;
-  if (spectraMap.empty())
-    return spectra;
-  auto cend = spectraMap.cend();
-  for (auto citr = spectraMap.cbegin(); citr != cend; ++citr) {
-    const std::vector<detid_t> detIDs(citr->second.begin(), citr->second.end());
-    IDetector_const_sptr det = instrument->getDetectorG(detIDs);
+/// Returns the list of valid spectrum indices
+std::vector<size_t> NearestNeighbours::getSpectraDetectors() {
+  std::vector<size_t> indices;
+  for (size_t i = 0; i < m_spectrumNumbers.size(); ++i) {
     // Always ignore monitors and ignore masked detectors if requested.
-    bool heedMasking = m_bIgnoreMaskedDetectors && det->isMasked();
-    if (!det->isMonitor() && !heedMasking) {
-      spectra.emplace(citr->first, det);
+    bool heedMasking = m_bIgnoreMaskedDetectors && m_spectrumInfo.isMasked(i);
+    if (!m_spectrumInfo.isMonitor(i) && !heedMasking) {
+      indices.push_back(i);
     }
   }
-  return spectra;
+  return indices;
 }
 }
 }
diff --git a/Framework/API/src/Progress.cpp b/Framework/API/src/Progress.cpp
index 9e6964bced0cd05c97282e08a3cd7031b27ee9bf..03a976199c1686b9aa22fb051b60d3692805f396 100644
--- a/Framework/API/src/Progress.cpp
+++ b/Framework/API/src/Progress.cpp
@@ -53,8 +53,8 @@ void Progress::doReport(const std::string &msg) {
     p = m_end;
   if (!m_alg)
     return;
-
-  m_alg->progress(p, msg, this->getEstimatedTime(),
+  // progress must be between 0 and 1
+  m_alg->progress(p / (m_end - m_start), msg, this->getEstimatedTime(),
                   this->m_notifyStepPrecision);
   m_alg->interruption_point();
 }
diff --git a/Framework/API/src/PropertyWithValue.cpp b/Framework/API/src/PropertyWithValue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0b8b9ba36f1aae87fcd4de1310d04da7936265b8
--- /dev/null
+++ b/Framework/API/src/PropertyWithValue.cpp
@@ -0,0 +1,56 @@
+#include "MantidKernel/PropertyWithValue.h"
+#include "MantidAPI/DllConfig.h"
+#include "MantidAPI/ExperimentInfo.h"
+#include "MantidAPI/IAlgorithm.h"
+#include "MantidAPI/IEventWorkspace.h"
+#include "MantidAPI/IFunction.h"
+#include "MantidAPI/IMaskWorkspace.h"
+#include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/IMDHistoWorkspace.h"
+#include "MantidAPI/IMDWorkspace.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidAPI/ISplittersWorkspace.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/Workspace.h"
+
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
+namespace Mantid {
+namespace Kernel {
+
+/// @cond
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IAlgorithm>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IEventWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IFunction>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IMaskWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IMDEventWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IMDHistoWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IMDWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::IPeaksWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::ISplittersWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::ITableWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::MatrixWorkspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::Workspace>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::WorkspaceGroup>>;
+template class MANTID_API_DLL
+    PropertyWithValue<boost::shared_ptr<API::ExperimentInfo>>;
+/// @endcond
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Framework/API/src/Run.cpp b/Framework/API/src/Run.cpp
index 0e256285d942737f7b5d98d3cbfb0aff0d1b0ce3..cba9f55cf7458af81edb42dcd4855b30ad00e715 100644
--- a/Framework/API/src/Run.cpp
+++ b/Framework/API/src/Run.cpp
@@ -1,10 +1,9 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Run.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/VectorHelper.h"
+#include "MantidKernel/make_unique.h"
 
 #include <nexus/NeXusFile.hpp>
 
@@ -38,16 +37,30 @@ const char *OUTER_BKG_RADIUS_GROUP = "outer_bkg_radius";
 Kernel::Logger g_log("Run");
 }
 
-//----------------------------------------------------------------------
-// Public member functions
-//----------------------------------------------------------------------
+Run::Run() : m_goniometer(Kernel::make_unique<Geometry::Goniometer>()) {}
+
+Run::Run(const Run &other)
+    : LogManager(other), m_goniometer(Kernel::make_unique<Geometry::Goniometer>(
+                             *other.m_goniometer)),
+      m_histoBins(other.m_histoBins) {}
+
+// Defined as default in source for forward declaration with std::unique_ptr.
+Run::~Run() = default;
+
+Run &Run::operator=(const Run &other) {
+  LogManager::operator=(other);
+  m_goniometer = Kernel::make_unique<Geometry::Goniometer>(*other.m_goniometer);
+  m_histoBins = other.m_histoBins;
+  return *this;
+}
 
 boost::shared_ptr<Run> Run::clone() {
   auto clone = boost::make_shared<Run>();
   for (auto property : this->m_manager.getProperties()) {
     clone->addProperty(property->clone());
   }
-  clone->m_goniometer = this->m_goniometer;
+  clone->m_goniometer =
+      Kernel::make_unique<Geometry::Goniometer>(*this->m_goniometer);
   clone->m_histoBins = this->m_histoBins;
   return clone;
 }
@@ -184,7 +197,7 @@ void Run::integrateProtonCharge(const std::string &logname) const {
   if (log) {
     const std::vector<double> logValues = log->valuesAsVector();
     double total = std::accumulate(logValues.begin(), logValues.end(), 0.0);
-    std::string unit = log->units();
+    const std::string &unit = log->units();
     // Do we need to take account of a unit
     if (unit.find("picoCoulomb") != std::string::npos) {
       /// Conversion factor between picoColumbs and microAmp*hours
@@ -280,7 +293,7 @@ std::vector<double> Run::getBinBoundaries() const {
  */
 size_t Run::getMemorySize() const {
   size_t total = LogManager::getMemorySize();
-  total += sizeof(m_goniometer);
+  total += sizeof(*m_goniometer);
   total += m_histoBins.size() * sizeof(double);
   return total;
 }
@@ -294,13 +307,13 @@ size_t Run::getMemorySize() const {
  */
 void Run::setGoniometer(const Geometry::Goniometer &goniometer,
                         const bool useLogValues) {
-  Geometry::Goniometer old = m_goniometer;
+  auto old = std::move(m_goniometer);
   try {
-    m_goniometer = goniometer; // copy it in
+    m_goniometer = Kernel::make_unique<Geometry::Goniometer>(goniometer);
     if (useLogValues)
       calculateGoniometerMatrix();
   } catch (std::runtime_error &) {
-    m_goniometer = old;
+    m_goniometer = std::move(old);
     throw;
   }
 }
@@ -314,7 +327,7 @@ void Run::setGoniometer(const Geometry::Goniometer &goniometer,
  * @return 3x3 double rotation matrix
  */
 const Mantid::Kernel::DblMatrix &Run::getGoniometerMatrix() const {
-  return m_goniometer.getR();
+  return m_goniometer->getR();
 }
 
 //--------------------------------------------------------------------------------------------
@@ -328,7 +341,7 @@ void Run::saveNexus(::NeXus::File *file, const std::string &group,
   LogManager::saveNexus(file, group, true);
 
   // write the goniometer
-  m_goniometer.saveNexus(file, GONIOMETER_LOG_NAME);
+  m_goniometer->saveNexus(file, GONIOMETER_LOG_NAME);
 
   // write the histogram bins, if there are any
   if (!m_histoBins.empty()) {
@@ -381,7 +394,7 @@ void Run::loadNexus(::NeXus::File *file, const std::string &group,
   for (const auto &name_class : entries) {
     if (name_class.second == "NXpositioner") {
       // Goniometer class
-      m_goniometer.loadNexus(file, name_class.first);
+      m_goniometer->loadNexus(file, name_class.first);
     } else if (name_class.first == HISTO_BINS_LOG_NAME) {
       file->openGroup(name_class.first, "NXdata");
       file->readData("value", m_histoBins);
@@ -435,8 +448,8 @@ void Run::loadNexus(::NeXus::File *file, const std::string &group,
  * Calculate the goniometer matrix
  */
 void Run::calculateGoniometerMatrix() {
-  for (size_t i = 0; i < m_goniometer.getNumberAxes(); ++i) {
-    const std::string axisName = m_goniometer.getAxis(i).name;
+  for (size_t i = 0; i < m_goniometer->getNumberAxes(); ++i) {
+    const std::string axisName = m_goniometer->getAxis(i).name;
     const double minAngle =
         getLogAsSingleValue(axisName, Kernel::Math::Minimum);
     const double maxAngle =
@@ -471,7 +484,7 @@ void Run::calculateGoniometerMatrix() {
                       "1\',Axis1='chi,0,0,1,1',Axis2='phi,0,1,0,1')");
       }
     }
-    m_goniometer.setRotationAngle(i, angle);
+    m_goniometer->setRotationAngle(i, angle);
   }
 }
 
diff --git a/Framework/API/src/SpectrumInfo.cpp b/Framework/API/src/SpectrumInfo.cpp
index 5bab2300f110883b6e0a17d3db731197412e315a..83aa58c461d3a9e365905fdf9abadc20229db90e 100644
--- a/Framework/API/src/SpectrumInfo.cpp
+++ b/Framework/API/src/SpectrumInfo.cpp
@@ -1,22 +1,25 @@
 #include "MantidAPI/DetectorInfo.h"
-#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
+#include "MantidKernel/Exception.h"
 #include "MantidKernel/MultiThreaded.h"
 
+#include <boost/make_shared.hpp>
 #include <algorithm>
 
 namespace Mantid {
 namespace API {
 
-SpectrumInfo::SpectrumInfo(const MatrixWorkspace &workspace)
-    : m_workspace(workspace), m_detectorInfo(workspace.detectorInfo()),
+SpectrumInfo::SpectrumInfo(const ExperimentInfo &experimentInfo)
+    : m_experimentInfo(experimentInfo),
+      m_detectorInfo(experimentInfo.detectorInfo()),
       m_lastDetector(PARALLEL_GET_MAX_THREADS),
       m_lastIndex(PARALLEL_GET_MAX_THREADS, -1) {}
 
-SpectrumInfo::SpectrumInfo(MatrixWorkspace &workspace)
-    : m_workspace(workspace),
-      m_mutableDetectorInfo(&workspace.mutableDetectorInfo()),
+SpectrumInfo::SpectrumInfo(ExperimentInfo &experimentInfo)
+    : m_experimentInfo(experimentInfo),
+      m_mutableDetectorInfo(&experimentInfo.mutableDetectorInfo()),
       m_detectorInfo(*m_mutableDetectorInfo),
       m_lastDetector(PARALLEL_GET_MAX_THREADS),
       m_lastIndex(PARALLEL_GET_MAX_THREADS, -1) {}
@@ -106,7 +109,7 @@ bool SpectrumInfo::hasDetectors(const size_t index) const {
   // Workspaces can contain invalid detector IDs. Those IDs will be silently
   // ignored here until this is fixed.
   const auto &validDetectorIDs = m_detectorInfo.detectorIDs();
-  for (const auto &id : m_workspace.getSpectrum(index).getDetectorIDs()) {
+  for (const auto &id : m_experimentInfo.detectorIDsInGroup(index)) {
     const auto &it = std::lower_bound(validDetectorIDs.cbegin(),
                                       validDetectorIDs.cend(), id);
     if (it != validDetectorIDs.cend() && *it == id) {
@@ -122,7 +125,7 @@ bool SpectrumInfo::hasUniqueDetector(const size_t index) const {
   // Workspaces can contain invalid detector IDs. Those IDs will be silently
   // ignored here until this is fixed.
   const auto &validDetectorIDs = m_detectorInfo.detectorIDs();
-  for (const auto &id : m_workspace.getSpectrum(index).getDetectorIDs()) {
+  for (const auto &id : m_experimentInfo.detectorIDsInGroup(index)) {
     const auto &it = std::lower_bound(validDetectorIDs.cbegin(),
                                       validDetectorIDs.cend(), id);
     if (it != validDetectorIDs.cend() && *it == id) {
@@ -132,6 +135,17 @@ bool SpectrumInfo::hasUniqueDetector(const size_t index) const {
   return count == 1;
 }
 
+/** Set the mask flag of the spectrum with given index. Not thread safe.
+ *
+ * Currently this simply sets the mask flags for the underlying detectors. */
+void SpectrumInfo::setMasked(const size_t index, bool masked) {
+  for (const auto &det : getDetectorVector(index)) {
+    const auto detIndex = m_detectorInfo.indexOf(det->getID());
+    m_detectorInfo.setCachedDetector(detIndex, det);
+    m_mutableDetectorInfo->setMasked(detIndex, masked);
+  }
+}
+
 /// Return a const reference to the detector or detector group of the spectrum
 /// with given index.
 const Geometry::IDetector &SpectrumInfo::detector(const size_t index) const {
@@ -161,7 +175,7 @@ const Geometry::IDetector &SpectrumInfo::getDetector(const size_t index) const {
   // Note: This function body has big overlap with the method
   // MatrixWorkspace::getDetector(). The plan is to eventually remove the
   // latter, once SpectrumInfo is in widespread use.
-  const auto &dets = m_workspace.getSpectrum(index).getDetectorIDs();
+  const auto &dets = m_experimentInfo.detectorIDsInGroup(index);
   const size_t ndets = dets.size();
   if (ndets == 1) {
     // If only 1 detector for the spectrum number, just return it
@@ -176,8 +190,15 @@ const Geometry::IDetector &SpectrumInfo::getDetector(const size_t index) const {
     // Else need to construct a DetectorGroup and use that
     std::vector<boost::shared_ptr<const Geometry::IDetector>> det_ptrs;
     for (const auto &id : dets) {
-      const auto detIndex = m_detectorInfo.indexOf(id);
-      det_ptrs.push_back(m_detectorInfo.getDetectorPtr(detIndex));
+      try {
+        const auto detIndex = m_detectorInfo.indexOf(id);
+        det_ptrs.push_back(m_detectorInfo.getDetectorPtr(detIndex));
+      } catch (std::out_of_range &) {
+        // Workspaces can contain invalid detector IDs. Those IDs will be
+        // silently ignored here until this is fixed. Some valid IDs will exist
+        // if hasDetectors or hasUniqueDetectors has returned true, but there
+        // could still be invalid IDs.
+      }
     }
     m_lastDetector[thread] =
         boost::make_shared<Geometry::DetectorGroup>(det_ptrs, false);
diff --git a/Framework/API/src/Workspace.cpp b/Framework/API/src/Workspace.cpp
index d6d8f9b830042b6f614f45d8b3c73908139ba922..1db52c7be704f4262b1d900b8376bb67e083c879 100644
--- a/Framework/API/src/Workspace.cpp
+++ b/Framework/API/src/Workspace.cpp
@@ -1,12 +1,24 @@
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/IPropertyManager.h"
 #include "MantidKernel/Memory.h"
+#include "MantidKernel/make_unique.h"
 
 #include <boost/lexical_cast.hpp>
 
 namespace Mantid {
 namespace API {
 
+Workspace::Workspace() : m_history(Kernel::make_unique<WorkspaceHistory>()) {}
+
+// Defined as default in source for forward declaration with std::unique_ptr.
+Workspace::~Workspace() = default;
+
+Workspace::Workspace(const Workspace &other)
+    : Kernel::DataItem(other), m_title(other.m_title),
+      m_comment(other.m_comment), m_name(other.m_name),
+      m_history(Kernel::make_unique<WorkspaceHistory>(other.getHistory())) {}
+
 /** Set the title of the workspace
  *
  *  @param t :: The title
@@ -55,7 +67,7 @@ const std::string &Workspace::getName() const { return m_name; }
  * @param n: number of algorithms defining a clean workspace
  */
 bool Workspace::isDirty(const int n) const {
-  return static_cast<int>(m_history.size()) > n;
+  return static_cast<int>(m_history->size()) > n;
 }
 
 /**
diff --git a/Framework/API/src/WorkspaceGroup.cpp b/Framework/API/src/WorkspaceGroup.cpp
index cf5e9a08a39e170196caeecdd650cec5b301371d..237e621fa60455b67bd48a7afd76714eb5361ab0 100644
--- a/Framework/API/src/WorkspaceGroup.cpp
+++ b/Framework/API/src/WorkspaceGroup.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidKernel/Strings.h"
 
 namespace Mantid {
 namespace API {
diff --git a/Framework/API/src/WorkspaceHistory.cpp b/Framework/API/src/WorkspaceHistory.cpp
index c93483b3666afdc07481d1cca173519a2a8d6ce1..c501aa008a9b9263d4382692491c17dbf854d44c 100644
--- a/Framework/API/src/WorkspaceHistory.cpp
+++ b/Framework/API/src/WorkspaceHistory.cpp
@@ -1,13 +1,12 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmHistory.h"
 #include "MantidAPI/HistoryView.h"
 #include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/EnvironmentHistory.h"
 #include "MantidKernel/Strings.h"
+#include "MantidKernel/StringTokenizer.h"
 
+#include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
 
 #include "Poco/DateTime.h"
diff --git a/Framework/API/src/WorkspaceOpOverloads.cpp b/Framework/API/src/WorkspaceOpOverloads.cpp
index 11e39b61679c4932455daffe1cc58849a3e74e93..de3ccf96377f8e411406415261fb127b0c3811e8 100644
--- a/Framework/API/src/WorkspaceOpOverloads.cpp
+++ b/Framework/API/src/WorkspaceOpOverloads.cpp
@@ -1,18 +1,13 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidKernel/Property.h"
-//#include "MantidKernel/Exception.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidAPI/WorkspaceFactory.h"
-//#include "MantidAPI/SpectraAxis.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <numeric>
 
diff --git a/Framework/API/src/WorkspaceProperty.cpp b/Framework/API/src/WorkspaceProperty.cpp
index 7284be35e7295e92e9817ebe53f17d798499c33a..42bc43201755e39b950833a9b35915de896ae7aa 100644
--- a/Framework/API/src/WorkspaceProperty.cpp
+++ b/Framework/API/src/WorkspaceProperty.cpp
@@ -1,10 +1,15 @@
-#include "MantidAPI/Workspace.h"
-#include "MantidAPI/WorkspaceProperty.h"
-#include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/IMDEventWorkspace.h"
-#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/IMDHistoWorkspace.h"
+#include "MantidAPI/IMDWorkspace.h"
+#include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/ISplittersWorkspace.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/Workspace.h"
+
+// WorkspaceProperty implementation
+#include "MantidAPI/WorkspaceProperty.tcc"
 
 namespace Mantid {
 namespace API {
@@ -15,12 +20,18 @@ template class MANTID_API_DLL
     Mantid::API::WorkspaceProperty<Mantid::API::IEventWorkspace>;
 template class MANTID_API_DLL
     Mantid::API::WorkspaceProperty<Mantid::API::IMDEventWorkspace>;
+template class MANTID_API_DLL
+    Mantid::API::WorkspaceProperty<Mantid::API::IMDHistoWorkspace>;
 template class MANTID_API_DLL
     Mantid::API::WorkspaceProperty<Mantid::API::IMDWorkspace>;
 template class MANTID_API_DLL
     Mantid::API::WorkspaceProperty<Mantid::API::MatrixWorkspace>;
+template class MANTID_API_DLL
+    Mantid::API::WorkspaceProperty<Mantid::API::IPeaksWorkspace>;
 template class MANTID_API_DLL
     Mantid::API::WorkspaceProperty<Mantid::API::ITableWorkspace>;
+template class MANTID_API_DLL
+    Mantid::API::WorkspaceProperty<Mantid::API::WorkspaceGroup>;
 ///@endcond TEMPLATE
 } // namespace API
 } // namespace Mantid
diff --git a/Framework/API/test/AlgorithmManagerTest.h b/Framework/API/test/AlgorithmManagerTest.h
index 741583977f3c061a59bb911a0590b928fb04a700..fcdbcdcb517c2be1450ddaa158082765143d565f 100644
--- a/Framework/API/test/AlgorithmManagerTest.h
+++ b/Framework/API/test/AlgorithmManagerTest.h
@@ -6,6 +6,7 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmProxy.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ConfigService.h"
 #include <stdexcept>
 #include <vector>
diff --git a/Framework/API/test/AlgorithmProxyTest.h b/Framework/API/test/AlgorithmProxyTest.h
index 498e4e0098a64640c55b27e2b04e26335ae69c1b..d8d745c15a792e855eb84fe363c7aff5bc925fab 100644
--- a/Framework/API/test/AlgorithmProxyTest.h
+++ b/Framework/API/test/AlgorithmProxyTest.h
@@ -11,6 +11,8 @@
 #include <Poco/ActiveResult.h>
 #include <Poco/Thread.h>
 
+#include <boost/lexical_cast.hpp>
+
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
 
diff --git a/Framework/API/test/AlgorithmTest.h b/Framework/API/test/AlgorithmTest.h
index 55c704d1deafbffef28effa4c265909e58044211..b9c9e4acdbf8eeddb107da264e45e65ca6d04dac 100644
--- a/Framework/API/test/AlgorithmTest.h
+++ b/Framework/API/test/AlgorithmTest.h
@@ -11,8 +11,10 @@
 #include "MantidKernel/WriteLock.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/RebinParamsValidator.h"
+#include "MantidKernel/Strings.h"
 #include "FakeAlgorithms.h"
 #include "PropertyManagerHelper.h"
 #include <map>
diff --git a/Framework/API/test/CMakeLists.txt b/Framework/API/test/CMakeLists.txt
index 12900c2e766978b5193f83a11863bca68dcad571..9f1fe2a12caa434d73abb6902dcfaefd41c08108 100644
--- a/Framework/API/test/CMakeLists.txt
+++ b/Framework/API/test/CMakeLists.txt
@@ -9,6 +9,7 @@ if ( CXXTEST_FOUND )
                         ../../TestHelpers/src/BoxControllerDummyIO.cpp
                         ../../TestHelpers/src/InstrumentCreationHelper.cpp
                         ../../TestHelpers/src/NexusTestHelper.cpp
+                        ../../TestHelpers/src/FakeObjects.cpp
       )
   cxxtest_add_test ( APITest ${TEST_FILES} ${GMOCK_TEST_FILES})
   target_link_libraries( APITest LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} 
diff --git a/Framework/API/test/DataProcessorAlgorithmTest.h b/Framework/API/test/DataProcessorAlgorithmTest.h
index 3974a38ce2c5c7fc0be4c9c38eae9dedad7c45e7..c01f25a481ad8ed6910da9cce296ab1e1b83b215 100644
--- a/Framework/API/test/DataProcessorAlgorithmTest.h
+++ b/Framework/API/test/DataProcessorAlgorithmTest.h
@@ -4,11 +4,13 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/DataProcessorAlgorithm.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidTestHelpers/FakeObjects.h"
 
 using namespace Mantid;
-using namespace Mantid::API;
+using namespace Mantid::Kernel;
 using namespace Mantid::API;
 
 class DataProcessorAlgorithmTest : public CxxTest::TestSuite {
diff --git a/Framework/API/test/DetectorInfoTest.h b/Framework/API/test/DetectorInfoTest.h
index c776afb80814325be10d0cdd92fba242fd3fe805..e6cafd05d4032282db90977aad8626583b02ae14 100644
--- a/Framework/API/test/DetectorInfoTest.h
+++ b/Framework/API/test/DetectorInfoTest.h
@@ -10,6 +10,7 @@
 
 #include <algorithm>
 
+using namespace Mantid::Kernel;
 using namespace Mantid::Geometry;
 using namespace Mantid::API;
 
@@ -43,6 +44,8 @@ public:
                                  numberOfBins - 1);
   }
 
+  void test_size() { TS_ASSERT_EQUALS(m_workspace.detectorInfo().size(), 5); }
+
   void test_sourcePosition() {
     TS_ASSERT_EQUALS(m_workspace.detectorInfo().sourcePosition(),
                      V3D(0.0, 0.0, -20.0));
@@ -176,6 +179,20 @@ public:
     TS_ASSERT_EQUALS(detectorInfo.rotation(4), Quat(1.0, 0.0, 0.0, 0.0));
   }
 
+  void test_setMasked() {
+    auto &detectorInfo = m_workspace.mutableDetectorInfo();
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(0), true);
+    detectorInfo.setMasked(0, false);
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(0), false);
+    detectorInfo.setMasked(0, true);
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(0), true);
+    // Make sure no other detectors are affected
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(1), false);
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(2), false);
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(3), true);
+    TS_ASSERT_EQUALS(detectorInfo.isMasked(4), false);
+  }
+
   void test_setRotation() {
     V3D e3{0, 0, 1};
     Quat r3(90.0, e3);
@@ -293,6 +310,22 @@ public:
     TS_ASSERT_EQUALS(ids, sorted_ids);
   }
 
+  void test_assignment() {
+    auto ws1 = makeWorkspace(2);
+    auto ws2 = makeWorkspace(2);
+    TS_ASSERT_THROWS_NOTHING(ws2->mutableDetectorInfo() = ws1->detectorInfo());
+    // TODO Beamline::DetectorInfo is currently not containing data, so there is
+    // nothing we can check here. Once the class is getting populated add more
+    // checks here.
+  }
+
+  void test_assignment_mismatch() {
+    auto ws1 = makeWorkspace(1);
+    auto ws2 = makeWorkspace(2);
+    TS_ASSERT_THROWS(ws2->mutableDetectorInfo() = ws1->detectorInfo(),
+                     std::runtime_error);
+  }
+
 private:
   WorkspaceTester m_workspace;
   WorkspaceTester m_workspaceNoInstrument;
@@ -301,13 +334,16 @@ private:
     auto ws = Kernel::make_unique<WorkspaceTester>();
     ws->initialize(numSpectra, 1, 1);
     auto inst = boost::make_shared<Instrument>("TestInstrument");
-    ws->setInstrument(inst);
-    auto &pmap = ws->instrumentParameters();
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
       auto det = new Detector("pixel", static_cast<detid_t>(i), inst.get());
       inst->add(det);
       inst->markAsDetector(det);
+    }
+    ws->setInstrument(inst);
+    auto &pmap = ws->instrumentParameters();
+    for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
       ws->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
+      const auto &det = ws->getDetector(i);
       if (i % 2 == 0)
         pmap.addBool(det->getComponentID(), "masked", true);
     }
diff --git a/Framework/API/test/ExperimentInfoTest.h b/Framework/API/test/ExperimentInfoTest.h
index f73f2f5272ebd125546f2d8ee4145c8a2956d27d..f05fce1079a91b472135b22b77988c662306d5b1 100644
--- a/Framework/API/test/ExperimentInfoTest.h
+++ b/Framework/API/test/ExperimentInfoTest.h
@@ -420,7 +420,7 @@ public:
     TS_ASSERT(det);
 
     // Set a mapping
-    std::vector<Mantid::detid_t> group{1, 2};
+    std::set<Mantid::detid_t> group{1, 2};
     Mantid::det2group_map mapping{{1, group}};
     exptInfo->cacheDetectorGroupings(mapping);
 
@@ -429,6 +429,24 @@ public:
     TS_ASSERT(boost::dynamic_pointer_cast<const DetectorGroup>(det));
   }
 
+  void test_detectorIDsInGroup() {
+    using namespace Mantid;
+    ExperimentInfo_sptr exptInfo(new ExperimentInfo);
+    addInstrumentWithParameter(*exptInfo, "a", "b");
+
+    std::set<detid_t> dets;
+    TS_ASSERT_THROWS_NOTHING(dets = exptInfo->detectorIDsInGroup(0));
+    TS_ASSERT_EQUALS(dets, std::set<detid_t>{1});
+
+    // Set a mapping
+    std::set<detid_t> group{1, 2};
+    Mantid::det2group_map mapping{{1, group}};
+    exptInfo->cacheDetectorGroupings(mapping);
+
+    TS_ASSERT_THROWS_NOTHING(dets = exptInfo->detectorIDsInGroup(0));
+    TS_ASSERT_EQUALS(dets, group);
+  }
+
   void test_Setting_Group_Lookup_To_Empty_Map_Does_Not_Throw() {
     ExperimentInfo expt;
     Mantid::det2group_map mappings;
@@ -446,10 +464,10 @@ public:
   test_Setting_Group_Lookup_To_Non_Empty_Map_Allows_Retrieval_Of_Correct_IDs() {
     ExperimentInfo expt;
     Mantid::det2group_map mappings;
-    mappings.emplace(1, std::vector<Mantid::detid_t>(1, 2));
+    mappings.emplace(1, std::set<Mantid::detid_t>{2});
     expt.cacheDetectorGroupings(mappings);
 
-    std::vector<Mantid::detid_t> ids;
+    std::set<Mantid::detid_t> ids;
     TS_ASSERT_THROWS_NOTHING(ids = expt.getGroupMembers(1));
   }
 
diff --git a/Framework/API/test/FileBackedExperimentInfoTest.h b/Framework/API/test/FileBackedExperimentInfoTest.h
index 9a5b1005b1f0d7c0dec64bceb3f01ca22faac82e..042cf416cff4a71d17aeee344cf540cd45a58ccf 100644
--- a/Framework/API/test/FileBackedExperimentInfoTest.h
+++ b/Framework/API/test/FileBackedExperimentInfoTest.h
@@ -117,8 +117,7 @@ public:
   void test_cacheDetectorGroupings() {
     auto fileBacked = createTestObject();
 
-    std::vector<Mantid::detid_t> group(2, 1);
-    group[1] = 2;
+    std::set<Mantid::detid_t> group{1, 2};
     Mantid::det2group_map mapping;
     mapping.emplace(1, group);
     fileBacked->cacheDetectorGroupings(mapping);
@@ -127,8 +126,7 @@ public:
   void test_getGroupMembers() {
     auto fileBacked = createTestObject();
 
-    std::vector<Mantid::detid_t> group(2, 1);
-    group[1] = 2;
+    std::set<Mantid::detid_t> group{1, 2};
     Mantid::det2group_map mapping;
     mapping.emplace(1, group);
     fileBacked->cacheDetectorGroupings(mapping);
@@ -142,6 +140,12 @@ public:
     TS_ASSERT(fileBacked->getDetectorByID(10100));
   }
 
+  void test_detectorIDsInGroup() {
+    auto fileBacked = createTestObject();
+
+    TS_ASSERT_EQUALS(fileBacked->detectorIDsInGroup(0).size(), 1);
+  }
+
   void test_ModeratorModelMethods() {
     auto fileBacked = createTestObject();
     ModeratorModel *source = new FakeSource;
diff --git a/Framework/API/test/GroupingLoaderTest.h b/Framework/API/test/GroupingLoaderTest.h
index c906f15ac912f299a9a062c879865109803521d9..c6aa0e50d51f0eb689f9b89a80fba6d220d48da5 100644
--- a/Framework/API/test/GroupingLoaderTest.h
+++ b/Framework/API/test/GroupingLoaderTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include <Poco/Path.h>
 #include <Poco/File.h>
+#include "MantidKernel/ConfigService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/GroupingLoader.h"
 
@@ -75,4 +76,4 @@ private:
   std::string m_tmpDir;
 };
 
-#endif /* MANTID_API_GROUPINGLOADERTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_API_GROUPINGLOADERTEST_H_ */
diff --git a/Framework/API/test/InstrumentValidatorTest.h b/Framework/API/test/InstrumentValidatorTest.h
index 3edaddca83aa70324e9fa179fae8492a85d41f67..7c6704f06dd683bfd3b91983812f1459e8bc0a62 100644
--- a/Framework/API/test/InstrumentValidatorTest.h
+++ b/Framework/API/test/InstrumentValidatorTest.h
@@ -8,6 +8,7 @@
 #include "MantidTestHelpers/FakeObjects.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
+using namespace Mantid::Kernel;
 using Mantid::API::InstrumentValidator;
 
 class InstrumentValidatorTest : public CxxTest::TestSuite {
@@ -46,4 +47,4 @@ public:
   }
 };
 
-#endif /* MANTID_API_INSTRUMENTVALIDATORTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_API_INSTRUMENTVALIDATORTEST_H_ */
diff --git a/Framework/API/test/LiveListenerFactoryTest.h b/Framework/API/test/LiveListenerFactoryTest.h
index 3c380de8b18a51e3db257ae3d527864101b6bd3b..e4a5facfd6e0deb76b03e882c8266370981bad5a 100644
--- a/Framework/API/test/LiveListenerFactoryTest.h
+++ b/Framework/API/test/LiveListenerFactoryTest.h
@@ -58,11 +58,6 @@ public:
     TS_ASSERT_THROWS_NOTHING(factory.create("MINITOPAZ", false));
   }
 
-  void test_checkConnection() {
-    TS_ASSERT(factory.checkConnection("MockILiveListener"));
-    TS_ASSERT(!factory.checkConnection("MINITOPAZ"))
-  }
-
   void test_createUnwrapped_throws() {
     // Make sure this method just throws.
     // Note that you can't even access the method unless you assign to a
diff --git a/Framework/API/test/LogFilterGeneratorTest.h b/Framework/API/test/LogFilterGeneratorTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..19b0cbcd92707d0c96489f7006ad73f6d809f811
--- /dev/null
+++ b/Framework/API/test/LogFilterGeneratorTest.h
@@ -0,0 +1,191 @@
+#ifndef MANTID_API_LOGFILTERGENERATORTEST_H_
+#define MANTID_API_LOGFILTERGENERATORTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAPI/LogFilterGenerator.h"
+#include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceFactory.h"
+#include "MantidKernel/DateAndTime.h"
+#include "MantidKernel/make_unique.h"
+#include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidTestHelpers/FakeObjects.h"
+
+#include <numeric>
+
+using Mantid::API::MatrixWorkspace_sptr;
+using Mantid::API::LogFilterGenerator;
+using Mantid::Kernel::DateAndTime;
+using Mantid::Kernel::LogFilter;
+using Mantid::Kernel::TimeSeriesProperty;
+
+class LogFilterGeneratorTest : 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 LogFilterGeneratorTest *createSuite() {
+    return new LogFilterGeneratorTest();
+  }
+  static void destroySuite(LogFilterGeneratorTest *suite) { delete suite; }
+
+  void test_logDoesNotExist_throws() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Status, ws);
+    TS_ASSERT_THROWS(generator.generateFilter("NonExistentLog"),
+                     std::invalid_argument);
+  }
+
+  void test_logExistsButIsNotNumericTimeSeries_throws() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Status, ws);
+    TS_ASSERT_THROWS(generator.generateFilter("BadLog"), std::invalid_argument);
+  }
+
+  void test_typeIsNone_noFilterReturned() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::None, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(!filter->filter());
+  }
+
+  void test_typeIsStatus_noRunningLogPresent_thenNoFilterReturned() {
+    auto ws = createTestWorkspace(false, false, false);
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Status, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(!filter->filter());
+  }
+
+  void test_typeIsStatus() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Status, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(filter->filter());
+    const auto &resultMap = filter->filter()->valueAsCorrectMap();
+    std::map<DateAndTime, bool> expected;
+    expected.emplace(DateAndTime("2007-11-30T16:17:00"), true);
+    expected.emplace(DateAndTime("2007-11-30T16:17:30"), false);
+    expected.emplace(DateAndTime("2007-11-30T16:18:00"), true);
+    TS_ASSERT_EQUALS(resultMap.size(), 3);
+    TS_ASSERT_EQUALS(resultMap, expected);
+  }
+
+  void test_typeIsPeriod_noPeriodLogPresent_thenNoFilterReturned() {
+    auto ws = createTestWorkspace(true, false, false);
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Period, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(!filter->filter());
+  }
+
+  void test_typeIsPeriod() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(LogFilterGenerator::FilterType::Period, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(filter->filter());
+    const auto &values = filter->filter()->valueAsCorrectMap();
+    TS_ASSERT(!values.empty());
+    std::map<DateAndTime, bool> expected;
+    expected.emplace(DateAndTime("2007-11-30T16:18:20"), true);
+    expected.emplace(DateAndTime("2007-11-30T16:18:50"), false);
+    TS_ASSERT_EQUALS(expected, values);
+  }
+
+  void test_typeIsStatusAndPeriod() {
+    auto ws = createTestWorkspace();
+    LogFilterGenerator generator(
+        LogFilterGenerator::FilterType::StatusAndPeriod, ws);
+    std::unique_ptr<LogFilter> filter;
+    TS_ASSERT_THROWS_NOTHING(filter = generator.generateFilter("TestLog"));
+    TS_ASSERT(filter->filter());
+    const auto &values = filter->filter()->valueAsCorrectMap();
+    TS_ASSERT(!values.empty());
+    std::map<DateAndTime, bool> expected;
+    // This is an "intersection" (&&):
+    //   Time    Status   Period   Result
+    // 16:17:00    T        F        F
+    // 16:17:30    F        F        F
+    // 16:18:00    T        F        F
+    // 16:18:20    T        T        T
+    // 16:18:50    T        F        F
+    expected.emplace(DateAndTime("2007-11-30T16:17:00"), false);
+    expected.emplace(DateAndTime("2007-11-30T16:17:30"), false);
+    expected.emplace(DateAndTime("2007-11-30T16:18:00"), false);
+    expected.emplace(DateAndTime("2007-11-30T16:18:20"), true);
+    expected.emplace(DateAndTime("2007-11-30T16:18:50"), false);
+    TS_ASSERT_EQUALS(expected, values);
+  }
+
+private:
+  /**
+   * Generate a test workspace.
+   * @param hasStatusLog :: [input] Whether to include a "running" log
+   * @param hasPeriodLog :: [input] Whether to include a "period 1" log
+   * @param hasBadLog :: [input] Whether to include a log that is not a numeric
+   * TSP
+   * @returns :: Test workspace with required logs
+   */
+  MatrixWorkspace_sptr createTestWorkspace(bool hasStatusLog = true,
+                                           bool hasPeriodLog = true,
+                                           bool hasBadLog = true) {
+    MatrixWorkspace_sptr ws = boost::make_shared<WorkspaceTester>();
+    const std::vector<double> xData{0.0, 1.0}, yCounts{25.0}, errors{5.0};
+    ws->initialize(1, xData.size(), yCounts.size());
+    ws->setBinEdges(0, xData);
+    ws->setCounts(0, yCounts);
+    ws->setCountStandardDeviations(0, errors);
+
+    // Create the log to be filtered
+    auto log =
+        Mantid::Kernel::make_unique<TimeSeriesProperty<double>>("TestLog");
+    constexpr size_t logSize(12);
+    const DateAndTime initialTime("2007-11-30T16:17:00");
+    std::vector<DateAndTime> times;
+    std::vector<double> values;
+    times.reserve(logSize);
+    values.reserve(logSize);
+    constexpr double incrementSecs(10.0);
+    for (size_t i = 0; i < logSize; ++i) {
+      const double val = static_cast<double>(i);
+      times.push_back(initialTime + val * incrementSecs);
+      values.push_back(val);
+    }
+    log->addValues(times, values);
+    ws->mutableRun().addLogData(std::move(log));
+
+    // Status ("running") log
+    if (hasStatusLog) {
+      auto status =
+          Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>("running");
+      status->addValue(initialTime, true);
+      status->addValue(initialTime + 30.0, false);
+      status->addValue(initialTime + 60.0, true);
+      ws->mutableRun().addLogData(std::move(status));
+    }
+
+    // Period log
+    if (hasPeriodLog) {
+      auto period =
+          Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>("period 1");
+      period->addValue(initialTime + 80.0, true);
+      period->addValue(initialTime + 110.0, false);
+      ws->mutableRun().addLogData(std::move(period));
+    }
+
+    // Log that isn't a numeric TSP
+    if (hasBadLog) {
+      auto bad = Mantid::Kernel::make_unique<TimeSeriesProperty<std::string>>(
+          "BadLog");
+      bad->addValue(initialTime + 15.0, "hello");
+      bad->addValue(initialTime + 45.0, "string");
+      ws->mutableRun().addLogData(std::move(bad));
+    }
+
+    return ws;
+  }
+};
+
+#endif /* MANTID_API_LOGFILTERGENERATORTEST_H_ */
diff --git a/Framework/API/test/MDGeometryTest.h b/Framework/API/test/MDGeometryTest.h
index 11be178625bb6d6a3b3dd45ce2e17eb728182610..46d2189176b2b5bbc52f5ee93eb45c10850bfc38 100644
--- a/Framework/API/test/MDGeometryTest.h
+++ b/Framework/API/test/MDGeometryTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_API_MDGEOMETRYTEST_H_
 #define MANTID_API_MDGEOMETRYTEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MDGeometry.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidKernel/System.h"
diff --git a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
index 529f977705a839f4f05b73b8ed14446e989dcd57..0674d7e6dc24a8fc002bfb68ec130ddbe7a8fc03 100644
--- a/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
+++ b/Framework/API/test/MatrixWorkspaceMDIteratorTest.h
@@ -2,6 +2,7 @@
 #define MANTID_API_MATRIXWORKSPACEMDITERATORTEST_H_
 
 #include "MantidAPI/MatrixWorkspaceMDIterator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidTestHelpers/FakeObjects.h"
@@ -32,7 +33,6 @@ public:
       }
     }
     Instrument_sptr inst(new Instrument("TestInstrument"));
-    ws->setInstrument(inst);
     // We get a 1:1 map by default so the detector ID should match the spectrum
     // number
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
@@ -43,6 +43,7 @@ public:
       inst->markAsDetector(det);
       ws->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
     }
+    ws->setInstrument(inst);
     ws->replaceAxis(1, ax1);
 
     return ws;
@@ -120,9 +121,9 @@ public:
   void test_get_is_masked() {
     boost::shared_ptr<MatrixWorkspace> ws = makeFakeWS();
     IMDIterator *it = ws->createIterator(NULL);
+    const auto &spectrumInfo = ws->spectrumInfo();
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
-      Mantid::Geometry::IDetector_const_sptr det = ws->getDetector(i);
-      TS_ASSERT_EQUALS(det->isMasked(), it->getIsMasked());
+      TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), it->getIsMasked());
       it->next();
     }
     delete it;
diff --git a/Framework/API/test/MatrixWorkspaceTest.h b/Framework/API/test/MatrixWorkspaceTest.h
index b417cfc24139969b20c4ac3aad73f2a6b8bbbc33..97d0ceaf3b2354580a4e2e4d93562b865f8e40d1 100644
--- a/Framework/API/test/MatrixWorkspaceTest.h
+++ b/Framework/API/test/MatrixWorkspaceTest.h
@@ -53,7 +53,6 @@ boost::shared_ptr<MatrixWorkspace> makeWorkspaceWithDetectors(size_t numSpectra,
   ws2->initialize(numSpectra, numBins, numBins);
 
   auto inst = boost::make_shared<Instrument>("TestInstrument");
-  ws2->setInstrument(inst);
   // We get a 1:1 map by default so the detector ID should match the spectrum
   // number
   for (size_t i = 0; i < ws2->getNumberHistograms(); ++i) {
@@ -63,6 +62,7 @@ boost::shared_ptr<MatrixWorkspace> makeWorkspaceWithDetectors(size_t numSpectra,
     inst->markAsDetector(det);
     ws2->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
   }
+  ws2->setInstrument(inst);
   return ws2;
 }
 
@@ -343,23 +343,21 @@ public:
         makeWorkspaceWithDetectors(3, 1));
 
     // Initially un masked
+    const auto &spectrumInfo = workspace->spectrumInfo();
     for (int i = 0; i < numHist; ++i) {
       TS_ASSERT_EQUALS(workspace->readY(i)[0], 1.0);
       TS_ASSERT_EQUALS(workspace->readE(i)[0], 1.0);
-
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = workspace->getDetector(i));
-      if (det) {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
-      } else {
-        TS_FAIL("No detector defined");
-      }
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
+      TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
     }
 
     // Mask a spectra
-    workspace->maskWorkspaceIndex(1);
-    workspace->maskWorkspaceIndex(2);
+    workspace->getSpectrum(1).clearData();
+    workspace->getSpectrum(2).clearData();
+    workspace->mutableSpectrumInfo().setMasked(1, true);
+    workspace->mutableSpectrumInfo().setMasked(2, true);
 
+    const auto &spectrumInfo2 = workspace->spectrumInfo();
     for (int i = 0; i < numHist; ++i) {
       double expectedValue(0.0);
       bool expectedMasked(false);
@@ -371,14 +369,8 @@ public:
       }
       TS_ASSERT_EQUALS(workspace->readY(i)[0], expectedValue);
       TS_ASSERT_EQUALS(workspace->readE(i)[0], expectedValue);
-
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = workspace->getDetector(i));
-      if (det) {
-        TS_ASSERT_EQUALS(det->isMasked(), expectedMasked);
-      } else {
-        TS_FAIL("No detector defined");
-      }
+      TS_ASSERT(spectrumInfo2.hasDetectors(i));
+      TS_ASSERT_EQUALS(spectrumInfo2.isMasked(i), expectedMasked);
     }
   }
 
@@ -386,8 +378,10 @@ public:
     // Workspace has 3 spectra, each 1 in length
     const int numHist(3);
     auto workspace = makeWorkspaceWithDetectors(numHist, 1);
-    workspace->maskWorkspaceIndex(1);
-    workspace->maskWorkspaceIndex(2);
+    workspace->getSpectrum(1).clearData();
+    workspace->getSpectrum(2).clearData();
+    workspace->mutableSpectrumInfo().setMasked(1, true);
+    workspace->mutableSpectrumInfo().setMasked(2, true);
 
     const auto &spectrumInfo = workspace->spectrumInfo();
     for (int i = 0; i < numHist; ++i) {
@@ -617,55 +611,6 @@ public:
     TS_ASSERT_THROWS_NOTHING(ws->saveSpectraMapNexus(th.file, spec););
   }
 
-  /** Properly, this tests a method on Instrument, not MatrixWorkspace, but they
-   * are related.
-   */
-  void test_isDetectorMasked() {
-    auto ws = makeWorkspaceWithDetectors(100, 10);
-    Instrument_const_sptr inst = ws->getInstrument();
-    // Make sure the instrument is parametrized so that the test is thorough
-    TS_ASSERT(inst->isParametrized());
-    TS_ASSERT(!inst->isDetectorMasked(1));
-    TS_ASSERT(!inst->isDetectorMasked(19));
-    // Mask then check that it returns as masked
-    TS_ASSERT(ws->getSpectrum(19).hasDetectorID(19));
-    ws->maskWorkspaceIndex(19);
-    TS_ASSERT(inst->isDetectorMasked(19));
-  }
-
-  /** Check if any of a list of detectors are masked */
-  void test_isDetectorMasked_onASet() {
-    auto ws = makeWorkspaceWithDetectors(100, 10);
-    Instrument_const_sptr inst = ws->getInstrument();
-    // Make sure the instrument is parametrized so that the test is thorough
-    TS_ASSERT(inst->isParametrized());
-
-    // Mask detector IDs 8 and 9
-    ws->maskWorkspaceIndex(8);
-    ws->maskWorkspaceIndex(9);
-
-    std::set<detid_t> dets;
-    TSM_ASSERT("No detector IDs = not masked", !inst->isDetectorMasked(dets));
-    dets.insert(6);
-    TSM_ASSERT("Detector is not masked", !inst->isDetectorMasked(dets));
-    dets.insert(7);
-    TSM_ASSERT("Detectors are not masked", !inst->isDetectorMasked(dets));
-    dets.insert(8);
-    TSM_ASSERT("If any detector is not masked, return false",
-               !inst->isDetectorMasked(dets));
-    // Start again
-    dets.clear();
-    dets.insert(8);
-    TSM_ASSERT("If all detectors are not masked, return true",
-               inst->isDetectorMasked(dets));
-    dets.insert(9);
-    TSM_ASSERT("If all detectors are not masked, return true",
-               inst->isDetectorMasked(dets));
-    dets.insert(10);
-    TSM_ASSERT("If any detector is not masked, return false",
-               !inst->isDetectorMasked(dets));
-  }
-
   void test_hasGroupedDetectors() {
     auto ws = makeWorkspaceWithDetectors(5, 1);
     TS_ASSERT_EQUALS(ws->hasGroupedDetectors(), false);
@@ -722,7 +667,6 @@ public:
     // the detector ID
     // is stored in at least 3 places
     auto inst = boost::make_shared<Instrument>("TestInstrument");
-    ws->setInstrument(inst);
     // We get a 1:1 map by default so the detector ID should match the spectrum
     // number
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
@@ -737,6 +681,7 @@ public:
       inst->markAsDetector(det);
       ws->getSpectrum(i).addDetectorID(detid);
     }
+    ws->setInstrument(inst);
     ws->getSpectrum(66).clearDetectorIDs();
 
     TS_ASSERT_THROWS_NOTHING(
diff --git a/Framework/API/test/NearestNeighbourInfoTest.h b/Framework/API/test/NearestNeighbourInfoTest.h
index b53ca21b5e256e3bc255f4a5e39224655ab6191b..f8fa58c3e4d72ae8275216a845528f2a378fe4d9 100644
--- a/Framework/API/test/NearestNeighbourInfoTest.h
+++ b/Framework/API/test/NearestNeighbourInfoTest.h
@@ -6,6 +6,7 @@
 #include "MantidTestHelpers/FakeObjects.h"
 #include "MantidTestHelpers/InstrumentCreationHelper.h"
 #include "MantidAPI/NearestNeighbourInfo.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 using Mantid::API::NearestNeighbourInfo;
 
@@ -23,7 +24,8 @@ public:
     InstrumentCreationHelper::addFullInstrumentToWorkspace(workspace, false,
                                                            false, "");
     workspace.rebuildSpectraMapping();
-    workspace.maskWorkspaceIndex(0);
+    workspace.getSpectrum(0).clearData();
+    workspace.mutableSpectrumInfo().setMasked(0, true);
   }
 
   void test_construct() {
diff --git a/Framework/Geometry/test/NearestNeighboursTest.h b/Framework/API/test/NearestNeighboursTest.h
similarity index 55%
rename from Framework/Geometry/test/NearestNeighboursTest.h
rename to Framework/API/test/NearestNeighboursTest.h
index a5609c0933186f6c67b8752e0a388b674fc42a27..0369aaacabbf069c5fff98582b8e0df241163e7e 100644
--- a/Framework/Geometry/test/NearestNeighboursTest.h
+++ b/Framework/API/test/NearestNeighboursTest.h
@@ -1,71 +1,78 @@
 #ifndef MANTID_TEST_GEOMETRY_NEARESTNEIGHBOURS
 #define MANTID_TEST_GEOMETRY_NEARESTNEIGHBOURS
 
+#include "MantidAPI/NearestNeighbours.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/NearestNeighbours.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
+#include "MantidTestHelpers/FakeObjects.h"
 #include <cxxtest/TestSuite.h>
 #include <map>
 
 using namespace Mantid;
 using namespace Mantid::Geometry;
+using namespace Mantid::API;
 using Mantid::Kernel::V3D;
 
 /**
 * Everything must be in one test or the instrument/detector list goes AWOL.
 */
 
+namespace {
+boost::shared_ptr<MatrixWorkspace> makeWorkspace(const specnum_t start,
+                                                 const specnum_t end) {
+  auto ws = boost::make_shared<WorkspaceTester>();
+  ws->initialize(end - start + 1, 2, 1);
+  for (specnum_t i = start; i <= end; ++i) {
+    ws->getSpectrum(i - start).setSpectrumNo(i);
+    ws->getSpectrum(i - start).setDetectorID(i);
+  }
+  return ws;
+}
+
+std::vector<specnum_t> getSpectrumNumbers(const MatrixWorkspace &workspace) {
+  std::vector<specnum_t> spectrumNumbers;
+  for (size_t i = 0; i < workspace.getNumberHistograms(); ++i)
+    spectrumNumbers.push_back(workspace.getSpectrum(i).getSpectrumNo());
+  return spectrumNumbers;
+}
+}
+
 //=====================================================================================
 // Functional tests
 //=====================================================================================
 class NearestNeighboursTest : public CxxTest::TestSuite {
-public:
-  static ISpectrumDetectorMapping
-  buildSpectrumDetectorMapping(const specnum_t start, const specnum_t end) {
-    std::unordered_map<specnum_t, std::set<detid_t>> map;
-    for (specnum_t i = start; i <= end; ++i) {
-      map[i].insert(i);
-    }
-    return map;
-  }
-
 private:
   /// Helper type giving access to protected methods. Makes testing of NN
   /// internals possible.
-  class ExposedNearestNeighbours : public Mantid::Geometry::NearestNeighbours {
+  class ExposedNearestNeighbours : public Mantid::API::NearestNeighbours {
   public:
-    ExposedNearestNeighbours(boost::shared_ptr<const Instrument> instrument,
-                             const ISpectrumDetectorMapping &spectraMap,
+    ExposedNearestNeighbours(const SpectrumInfo &spectrumInfo,
+                             const std::vector<specnum_t> spectrumNumbers,
                              bool ignoreMasked = false)
-        : NearestNeighbours(instrument, spectraMap, ignoreMasked) {}
+        : NearestNeighbours(8, spectrumInfo, spectrumNumbers, ignoreMasked) {}
 
     // Direct access to intermdiate spectra detectors
-    std::map<specnum_t, IDetector_const_sptr> getSpectraDetectors() {
-      return NearestNeighbours::getSpectraDetectors(m_instrument, m_spectraMap);
+    std::vector<size_t> getSpectraDetectors() {
+      return NearestNeighbours::getSpectraDetectors();
     }
   };
 
 public:
   void doTestWithNeighbourNumbers(int actualNeighboursNumber,
                                   int expectedNeighboursNumber) {
-    // Create Instrument and make it Parameterised
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    const auto ws = makeWorkspace(1, 18);
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        buildSpectrumDetectorMapping(1, 18);
-    TS_ASSERT_EQUALS(spectramap.size(), 18);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
 
     // Create the NearestNeighbours object directly.
-    NearestNeighbours nn(actualNeighboursNumber, m_instrument, spectramap);
+    NearestNeighbours nn(actualNeighboursNumber, ws->spectrumInfo(),
+                         getSpectrumNumbers(*ws));
 
     // Check distances calculated in NearestNeighbours compare with those using
     // getDistance on component
@@ -76,22 +83,15 @@ public:
   }
 
   void testNeighbourFindingWithRadius() {
-    // Create Instrument and make it Parameterised
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    const auto ws = makeWorkspace(1, 18);
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        buildSpectrumDetectorMapping(1, 18);
-    TS_ASSERT_EQUALS(spectramap.size(), 18);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
 
     // Create the NearestNeighbours object directly.
-    NearestNeighbours nn(m_instrument, spectramap);
+    NearestNeighbours nn(8, ws->spectrumInfo(), getSpectrumNumbers(*ws));
 
     detid2det_map m_detectors;
-    m_instrument->getDetectors(m_detectors);
+    ws->getInstrument()->getDetectors(m_detectors);
 
     // Need scaling vector since changes to NN ( 22/12/10 )
     Mantid::Geometry::BoundingBox bbox = Mantid::Geometry::BoundingBox();
@@ -102,8 +102,6 @@ public:
               (bbox.zMax() - bbox.zMin()));
 
     // Check instrument was created to our expectations
-    ParameterMap_sptr p_map;
-    TS_ASSERT_THROWS_NOTHING(p_map = m_instrument->getParameterMap());
     TS_ASSERT_EQUALS(m_detectors.size(), 18);
 
     // Check distances calculated in NearestNeighbours compare with those using
@@ -140,21 +138,15 @@ public:
 
   // Let's try it with a rectangular detector.
   void testNeighbours_RectangularDetector() {
+    const auto ws = makeWorkspace(256, 767);
     // 2 Rectangular detectors, 16x16
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentRectangular(2, 16));
 
-    // Test fails without a parameter map.
-    const ISpectrumDetectorMapping spectramap =
-        buildSpectrumDetectorMapping(256, 767);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
-
     // Create the NearestNeighbours object directly.
-    NearestNeighbours nn(m_instrument, spectramap);
+    NearestNeighbours nn(8, ws->spectrumInfo(), getSpectrumNumbers(*ws));
 
+    const auto &m_instrument = ws->getInstrument();
     // Correct # of detectors
     TS_ASSERT_EQUALS(m_instrument->getDetectorIDs().size(), 512);
 
@@ -177,34 +169,21 @@ public:
   }
 
   void testIgnoreAndApplyMasking() {
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    const auto ws = makeWorkspace(1, 18);
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        buildSpectrumDetectorMapping(1, 18);
-
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-
-    // Mask the first 5 detectors
-    for (Mantid::specnum_t i = 1; i < 3; i++) {
-      if (const Geometry::ComponentID det =
-              instrument->getDetector(*spectramap.at(i).begin())
-                  ->getComponentID()) {
-        pmap->addBool(det, "masked", true);
-      }
-    }
 
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
-
-    IDetector_const_sptr det =
-        m_instrument->getDetector(*spectramap.at(1).begin());
+    // Mask the first 2 detectors
+    auto &spectrumInfo = ws->mutableSpectrumInfo();
+    spectrumInfo.setMasked(0, true);
+    spectrumInfo.setMasked(1, true);
 
     // Create the NearestNeighbours object directly. Ignore any masking.
-    ExposedNearestNeighbours ignoreMaskedNN(m_instrument, spectramap, true);
+    ExposedNearestNeighbours ignoreMaskedNN(ws->spectrumInfo(),
+                                            getSpectrumNumbers(*ws), true);
     // Create the NearestNeighbours object directly. Account for any masking.
-    ExposedNearestNeighbours accountForMaskedNN(m_instrument, spectramap,
-                                                false);
+    ExposedNearestNeighbours accountForMaskedNN(ws->spectrumInfo(),
+                                                getSpectrumNumbers(*ws), false);
 
     size_t sizeWithoutMasked = ignoreMaskedNN.getSpectraDetectors().size();
     size_t sizeWithMasked = accountForMaskedNN.getSpectraDetectors().size();
@@ -225,52 +204,27 @@ class NearestNeighboursTestPerformance : public CxxTest::TestSuite {
 
 public:
   void testUsingRadius() {
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    const auto ws = makeWorkspace(1, 18);
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        NearestNeighboursTest::buildSpectrumDetectorMapping(1, 18);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
 
     // Create the NearestNeighbours object directly.
-    NearestNeighbours nn(m_instrument, spectramap);
+    NearestNeighbours nn(8, ws->spectrumInfo(), getSpectrumNumbers(*ws));
     for (size_t i = 0; i < 2000; i++) {
       nn.neighboursInRadius(1, 5.0);
     }
   }
 
-  void testUsingDefault() {
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
-        ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        NearestNeighboursTest::buildSpectrumDetectorMapping(1, 18);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
-
-    // Create the NearestNeighbours object directly.
-    NearestNeighbours nn(m_instrument, spectramap);
-    for (size_t i = 0; i < 2000; i++) {
-      nn.neighboursInRadius(1, 0.0);
-    }
-  }
-
   void testUsingNumberOfNeighbours() {
-    Instrument_sptr instrument = boost::dynamic_pointer_cast<Instrument>(
+    const auto ws = makeWorkspace(1, 18);
+    ws->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(2));
-    const ISpectrumDetectorMapping spectramap =
-        NearestNeighboursTest::buildSpectrumDetectorMapping(1, 18);
-    // Default parameter map.
-    ParameterMap_sptr pmap(new ParameterMap());
-    // Parameterized instrument
-    Instrument_sptr m_instrument(new Instrument(instrument, pmap));
 
     // Create the NearestNeighbours object directly.
+    const auto &spectrumInfo = ws->spectrumInfo();
+    const auto spectrumNumbers = getSpectrumNumbers(*ws);
     for (size_t i = 0; i < 2000; i++) {
-      NearestNeighbours nn(8, m_instrument, spectramap);
+      NearestNeighbours nn(8, spectrumInfo, spectrumNumbers);
       nn.neighbours(1);
     }
   }
diff --git a/Framework/API/test/NotebookWriterTest.h b/Framework/API/test/NotebookWriterTest.h
index 4e7d46f2eb09d14d7365fb4bfd97c67a77aa0d56..da4a4aa5447846b71434a0376e120db12fe5aeda 100644
--- a/Framework/API/test/NotebookWriterTest.h
+++ b/Framework/API/test/NotebookWriterTest.h
@@ -6,6 +6,9 @@
 #include "MantidAPI/NotebookBuilder.h"
 #include "MantidTestHelpers/FakeObjects.h"
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
 
diff --git a/Framework/API/test/ProjectionTest.h b/Framework/API/test/ProjectionTest.h
index caf9d285263c9a628ad072a7c152c09d10d7edad..7e797e6db8231262662f8f9fcb216b2c64bbc217 100644
--- a/Framework/API/test/ProjectionTest.h
+++ b/Framework/API/test/ProjectionTest.h
@@ -10,6 +10,7 @@
 
 using namespace Mantid;
 using namespace Mantid::API;
+using namespace Mantid::Kernel;
 
 namespace {
 // Provides a table that claims to have the given number of rows and columns.
diff --git a/Framework/API/test/SampleShapeValidatorTest.h b/Framework/API/test/SampleShapeValidatorTest.h
index db0804d3a1c688d9bb89e4a8568b3b1cd0d36637..b33619fd000b6def305515575abed1aa369dbffc 100644
--- a/Framework/API/test/SampleShapeValidatorTest.h
+++ b/Framework/API/test/SampleShapeValidatorTest.h
@@ -10,6 +10,7 @@
 
 #include "boost/make_shared.hpp"
 
+using namespace Mantid::Kernel;
 using Mantid::API::SampleShapeValidator;
 
 class SampleShapeValidatorTest : public CxxTest::TestSuite {
diff --git a/Framework/API/test/SampleValidatorTest.h b/Framework/API/test/SampleValidatorTest.h
index 8d07a5e9fae3eac2db62e46a531b4fdfa23dfeec..6b0a1e92c1b9cec479bb82dc316399406f540787 100644
--- a/Framework/API/test/SampleValidatorTest.h
+++ b/Framework/API/test/SampleValidatorTest.h
@@ -9,6 +9,7 @@
 #include "MantidTestHelpers/FakeObjects.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
+using namespace Mantid::Kernel;
 using Mantid::API::SampleValidator;
 
 class SampleValidatorTest : public CxxTest::TestSuite {
diff --git a/Framework/API/test/SpectrumInfoTest.h b/Framework/API/test/SpectrumInfoTest.h
index e363fe27751a95b8b7268e5843d330eb17a725ae..464e57aa49bbd84b3f0c2e7d6755d6bac7611f16 100644
--- a/Framework/API/test/SpectrumInfoTest.h
+++ b/Framework/API/test/SpectrumInfoTest.h
@@ -14,6 +14,15 @@
 
 using namespace Mantid::Geometry;
 using namespace Mantid::API;
+using namespace Mantid::Kernel;
+
+namespace {
+constexpr size_t GroupOfDets2And3 = 0;
+constexpr size_t GroupOfDets1And2 = 1;
+constexpr size_t GroupOfDets1And4 = 2;
+constexpr size_t GroupOfDets4And5 = 3;
+constexpr size_t GroupOfAllDets = 4;
+}
 
 class SpectrumInfoTest : public CxxTest::TestSuite {
 public:
@@ -30,11 +39,15 @@ public:
                                  numberOfBins);
 
     // Workspace has 5 detectors, 1 and 4 are masked, 4 and 5 are monitors.
-    m_grouped.getSpectrum(0).setDetectorIDs({2, 3}); // no mask
-    m_grouped.getSpectrum(1).setDetectorIDs({1, 2}); // partial mask
-    m_grouped.getSpectrum(2).setDetectorIDs({1, 4}); // masked, partial monitor
-    m_grouped.getSpectrum(3).setDetectorIDs({4, 5}); // full monitor
-    m_grouped.getSpectrum(4).setDetectorIDs({1, 2, 3, 4, 5}); // everything
+    m_grouped.getSpectrum(GroupOfDets2And3).setDetectorIDs({2, 3}); // no mask
+    m_grouped.getSpectrum(GroupOfDets1And2)
+        .setDetectorIDs({1, 2}); // partial mask
+    m_grouped.getSpectrum(GroupOfDets1And4)
+        .setDetectorIDs({1, 4}); // masked, partial monitor
+    m_grouped.getSpectrum(GroupOfDets4And5)
+        .setDetectorIDs({4, 5}); // full monitor
+    m_grouped.getSpectrum(GroupOfAllDets)
+        .setDetectorIDs({1, 2, 3, 4, 5}); // everything
   }
 
   void test_constructor() {
@@ -72,11 +85,11 @@ public:
     // This is adopting the old definition from DetectorGroup: Spectra with at
     // least one non-monitor detector are not monitors. Actually it might make
     // more sense to forbid such a grouping.
-    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(0), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(1), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(2), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(3), true);
-    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(4), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(GroupOfDets2And3), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(GroupOfDets1And2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(GroupOfDets1And4), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(GroupOfDets4And5), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMonitor(GroupOfAllDets), false);
   }
 
   void test_isMasked() {
@@ -90,11 +103,11 @@ public:
 
   void test_grouped_isMasked() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMasked(1), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMasked(2), true);
-    TS_ASSERT_EQUALS(spectrumInfo.isMasked(3), false);
-    TS_ASSERT_EQUALS(spectrumInfo.isMasked(4), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets2And3), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And4), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets4And5), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfAllDets), false);
   }
 
   void test_isMasked_unthreaded() {
@@ -131,9 +144,9 @@ public:
     const auto &spectrumInfo = m_grouped.spectrumInfo();
     double x2 = 5.0 * 5.0;
     double y2 = 2.0 * 2.0 * 0.05 * 0.05;
-    TS_ASSERT_EQUALS(spectrumInfo.l2(0),
+    TS_ASSERT_EQUALS(spectrumInfo.l2(GroupOfDets2And3),
                      (sqrt(x2 + 0 * 0 * y2) + sqrt(x2 + 1 * 1 * y2)) / 2.0);
-    TS_ASSERT_EQUALS(spectrumInfo.l2(1),
+    TS_ASSERT_EQUALS(spectrumInfo.l2(GroupOfDets1And2),
                      (sqrt(x2 + 0 * 0 * y2) + sqrt(x2 + 1 * 1 * y2)) / 2.0);
     // Other lengths are not sensible since the detectors include monitors
   }
@@ -164,8 +177,10 @@ public:
 
   void test_grouped_twoTheta() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT_DELTA(spectrumInfo.twoTheta(0), 0.0199973 / 2.0, 1e-6);
-    TS_ASSERT_DELTA(spectrumInfo.twoTheta(1), 0.0199973 / 2.0, 1e-6);
+    TS_ASSERT_DELTA(spectrumInfo.twoTheta(GroupOfDets2And3), 0.0199973 / 2.0,
+                    1e-6);
+    TS_ASSERT_DELTA(spectrumInfo.twoTheta(GroupOfDets1And2), 0.0199973 / 2.0,
+                    1e-6);
     // Other theta values are not sensible since the detectors include monitors
   }
 
@@ -182,8 +197,8 @@ public:
   // removed at some point.
   void test_grouped_twoThetaLegacy() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    auto det = m_grouped.getDetector(1);
-    TS_ASSERT_EQUALS(spectrumInfo.twoTheta(1),
+    auto det = m_grouped.getDetector(GroupOfDets1And2);
+    TS_ASSERT_EQUALS(spectrumInfo.twoTheta(GroupOfDets1And2),
                      m_grouped.detectorTwoTheta(*det));
   }
 
@@ -199,8 +214,10 @@ public:
 
   void test_grouped_signedTwoTheta() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT_DELTA(spectrumInfo.signedTwoTheta(0), 0.0199973 / 2.0, 1e-6);
-    TS_ASSERT_DELTA(spectrumInfo.signedTwoTheta(1), -0.0199973 / 2.0, 1e-6);
+    TS_ASSERT_DELTA(spectrumInfo.signedTwoTheta(GroupOfDets2And3),
+                    0.0199973 / 2.0, 1e-6);
+    TS_ASSERT_DELTA(spectrumInfo.signedTwoTheta(GroupOfDets1And2),
+                    -0.0199973 / 2.0, 1e-6);
     // Other theta values are not sensible since the detectors include monitors
   }
 
@@ -217,8 +234,8 @@ public:
   // be removed at some point.
   void test_grouped_signedTwoThetaLegacy() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    auto det = m_grouped.getDetector(1);
-    TS_ASSERT_EQUALS(spectrumInfo.signedTwoTheta(1),
+    auto det = m_grouped.getDetector(GroupOfDets1And2);
+    TS_ASSERT_EQUALS(spectrumInfo.signedTwoTheta(GroupOfDets1And2),
                      m_grouped.detectorSignedTwoTheta(*det));
   }
 
@@ -233,18 +250,21 @@ public:
 
   void test_grouped_position() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT_EQUALS(spectrumInfo.position(0), V3D(0.0, 0.1 / 2.0, 5.0));
-    TS_ASSERT_EQUALS(spectrumInfo.position(1), V3D(0.0, -0.1 / 2.0, 5.0));
+    TS_ASSERT_EQUALS(spectrumInfo.position(GroupOfDets2And3),
+                     V3D(0.0, 0.1 / 2.0, 5.0));
+    TS_ASSERT_EQUALS(spectrumInfo.position(GroupOfDets1And2),
+                     V3D(0.0, -0.1 / 2.0, 5.0));
     // Other positions are not sensible since the detectors include monitors
   }
 
   void test_grouped_position_tracks_changes() {
     auto &detectorInfo = m_grouped.mutableDetectorInfo();
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    const auto oldPos = spectrumInfo.position(0);
+    const auto oldPos = detectorInfo.position(1);
     // Change Y pos from 0.0 to -0.1
     detectorInfo.setPosition(1, V3D(0.0, -0.1, 5.0));
-    TS_ASSERT_EQUALS(spectrumInfo.position(0), V3D(0.0, 0.0, 5.0));
+    TS_ASSERT_EQUALS(spectrumInfo.position(GroupOfDets2And3),
+                     V3D(0.0, 0.0, 5.0));
     TS_ASSERT_DELTA(spectrumInfo.twoTheta(0), 0.0199973, 1e-6);
     // Restore old position
     detectorInfo.setPosition(1, oldPos);
@@ -272,11 +292,11 @@ public:
 
   void test_grouped_hasDetectors() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT(spectrumInfo.hasDetectors(0));
-    TS_ASSERT(spectrumInfo.hasDetectors(1));
-    TS_ASSERT(spectrumInfo.hasDetectors(2));
-    TS_ASSERT(spectrumInfo.hasDetectors(3));
-    TS_ASSERT(spectrumInfo.hasDetectors(4));
+    TS_ASSERT(spectrumInfo.hasDetectors(GroupOfDets2And3));
+    TS_ASSERT(spectrumInfo.hasDetectors(GroupOfDets1And2));
+    TS_ASSERT(spectrumInfo.hasDetectors(GroupOfDets1And4));
+    TS_ASSERT(spectrumInfo.hasDetectors(GroupOfDets4And5));
+    TS_ASSERT(spectrumInfo.hasDetectors(GroupOfAllDets));
   }
 
   void test_hasDetectors_ignores_bad_IDs() {
@@ -310,11 +330,11 @@ public:
 
   void test_grouped_hasUniqueDetector() {
     const auto &spectrumInfo = m_grouped.spectrumInfo();
-    TS_ASSERT(!spectrumInfo.hasUniqueDetector(0));
-    TS_ASSERT(!spectrumInfo.hasUniqueDetector(1));
-    TS_ASSERT(!spectrumInfo.hasUniqueDetector(2));
-    TS_ASSERT(!spectrumInfo.hasUniqueDetector(3));
-    TS_ASSERT(!spectrumInfo.hasUniqueDetector(4));
+    TS_ASSERT(!spectrumInfo.hasUniqueDetector(GroupOfDets2And3));
+    TS_ASSERT(!spectrumInfo.hasUniqueDetector(GroupOfDets1And2));
+    TS_ASSERT(!spectrumInfo.hasUniqueDetector(GroupOfDets1And4));
+    TS_ASSERT(!spectrumInfo.hasUniqueDetector(GroupOfDets4And5));
+    TS_ASSERT(!spectrumInfo.hasUniqueDetector(GroupOfAllDets));
   }
 
   void test_hasUniqueDetector_ignores_bad_IDs() {
@@ -326,6 +346,62 @@ public:
     m_workspace.getSpectrum(1).setDetectorID(2);
   }
 
+  void test_setMasked() {
+    auto &spectrumInfo = m_workspace.mutableSpectrumInfo();
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), true);
+    spectrumInfo.setMasked(0, false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), false);
+    spectrumInfo.setMasked(0, true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), true);
+    // Make sure no other detectors are affected
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(1), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(4), false);
+  }
+
+  void test_grouped_setMasked() {
+    auto &spectrumInfo = m_grouped.mutableSpectrumInfo();
+    spectrumInfo.setMasked(GroupOfAllDets, false);
+    // 4 includes all detectors so all other spectra are affected
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets2And3), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And4), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets4And5), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfAllDets), false);
+    spectrumInfo.setMasked(GroupOfDets2And3, true);
+    // Partial masking => false
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets2And3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And4), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets4And5), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfAllDets), false);
+    // Restore initial state
+    spectrumInfo.setMasked(GroupOfAllDets, false);
+    spectrumInfo.setMasked(GroupOfDets1And4, true);
+  }
+
+  void test_grouped_setMasked_reverse_case() {
+    auto &spectrumInfo = m_grouped.mutableSpectrumInfo();
+    spectrumInfo.setMasked(GroupOfAllDets, true);
+    // 4 includes all detectors so all other spectra are affected
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets2And3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And2), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And4), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets4And5), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfAllDets), true);
+    spectrumInfo.setMasked(GroupOfDets2And3, false);
+    // Partial masking => false
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets2And3), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets1And4), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfDets4And5), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(GroupOfAllDets), false);
+    // Restore initial state
+    spectrumInfo.setMasked(GroupOfAllDets, false);
+    spectrumInfo.setMasked(GroupOfDets1And4, true);
+  }
+
   void test_detector() {
     const auto &spectrumInfo = m_workspace.spectrumInfo();
     TS_ASSERT_THROWS_NOTHING(spectrumInfo.detector(0));
@@ -341,6 +417,61 @@ public:
     TS_ASSERT_THROWS(spectrumInfo.detector(0), std::out_of_range);
   }
 
+  void test_ExperimentInfo_basics() {
+    const ExperimentInfo expInfo(m_workspace);
+    const SpectrumInfo spectrumInfo(expInfo);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(1), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(4), false);
+  }
+
+  void test_ExperimentInfo_from_grouped() {
+    const ExperimentInfo expInfo(m_grouped);
+    TS_ASSERT_EQUALS(expInfo.numberOfDetectorGroups(), 5);
+    const SpectrumInfo spectrumInfo(expInfo);
+    // We construct from a grouped workspace, but since that information is lost
+    // when constructing expInfo, so we should just see the masking of the
+    // underlying detectors.
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(1), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(4), false);
+  }
+
+  void test_ExperimentInfo_grouped() {
+    ExperimentInfo expInfo(m_workspace);
+
+    // We cannot really test anything but a single group, since the grouping
+    // mechanism in ExperimentInfo is currently based on std::unordered_map, so
+    // we have no control over the order and thus cannot write asserts.
+    det2group_map mapping{{1, {1, 2}}};
+    expInfo.cacheDetectorGroupings(mapping);
+    const SpectrumInfo spectrumInfo(expInfo);
+    TS_ASSERT_EQUALS(expInfo.numberOfDetectorGroups(), 1);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), false);
+
+    mapping = {{1, {1, 4}}};
+    expInfo.cacheDetectorGroupings(mapping);
+    const SpectrumInfo spectrumInfo2(expInfo);
+    TS_ASSERT_EQUALS(expInfo.numberOfDetectorGroups(), 1);
+    TS_ASSERT_EQUALS(spectrumInfo2.isMasked(0), true);
+  }
+
+  void test_grouping_in_ExperimentInfo_ignored_for_MatrixWorkspace() {
+    det2group_map mapping{{1, {1, 2}}};
+    m_workspace.cacheDetectorGroupings(mapping);
+    TS_ASSERT_EQUALS(m_workspace.numberOfDetectorGroups(), 5);
+    const auto &spectrumInfo = m_workspace.spectrumInfo();
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(0), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(1), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(2), false);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(3), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(4), false);
+  }
+
 private:
   WorkspaceTester m_workspace;
   WorkspaceTester m_workspaceNoInstrument;
@@ -350,16 +481,17 @@ private:
     auto ws = Kernel::make_unique<WorkspaceTester>();
     ws->initialize(numSpectra, 1, 1);
     auto inst = boost::make_shared<Instrument>("TestInstrument");
-    ws->setInstrument(inst);
-    auto &pmap = ws->instrumentParameters();
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
       auto det = new Detector("pixel", static_cast<detid_t>(i), inst.get());
       inst->add(det);
       inst->markAsDetector(det);
       ws->getSpectrum(i).addDetectorID(static_cast<detid_t>(i));
-      if (i % 2 == 0)
-        pmap.addBool(det->getComponentID(), "masked", true);
     }
+    ws->setInstrument(inst);
+    auto &detectorInfo = ws->mutableDetectorInfo();
+    for (size_t i = 0; i < ws->getNumberHistograms(); ++i)
+      if (i % 2 == 0)
+        detectorInfo.setMasked(i, true);
     return std::move(ws);
   }
 
@@ -375,13 +507,9 @@ private:
         ws, includeMonitors, startYNegative, instrumentName);
 
     std::set<int64_t> toMask{0, 3};
-    ParameterMap &pmap = ws.instrumentParameters();
-    for (size_t i = 0; i < ws.getNumberHistograms(); ++i) {
-      if (toMask.find(i) != toMask.end()) {
-        IDetector_const_sptr det = ws.getDetector(i);
-        pmap.addBool(det.get(), "masked", true);
-      }
-    }
+    auto &detectorInfo = ws.mutableDetectorInfo();
+    for (const auto &i : toMask)
+      detectorInfo.setMasked(i, true);
     return ws;
   }
 };
diff --git a/Framework/API/test/WorkspaceGroupTest.h b/Framework/API/test/WorkspaceGroupTest.h
index 8162430c2a77ac9f6d3841cd9a20377831a8e1d1..3ee1ac41f8cf54bdb5d7cf5e8527d151eb3ff69c 100644
--- a/Framework/API/test/WorkspaceGroupTest.h
+++ b/Framework/API/test/WorkspaceGroupTest.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/WarningSuppressions.h"
@@ -18,6 +19,7 @@
 
 using namespace Mantid;
 using namespace Mantid::API;
+using namespace Mantid::Kernel;
 
 class WorkspaceGroupTest_WorkspaceGroupObserver {
   Poco::NObserver<WorkspaceGroupTest_WorkspaceGroupObserver,
diff --git a/Framework/API/test/WorkspacePropertyTest.h b/Framework/API/test/WorkspacePropertyTest.h
index fe3a5c20b647a13fa28bf2a9d6acac132454e7f5..6c64b6c1202b2aa1be14506d377fa40278f549be 100644
--- a/Framework/API/test/WorkspacePropertyTest.h
+++ b/Framework/API/test/WorkspacePropertyTest.h
@@ -8,6 +8,10 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidTestHelpers/FakeObjects.h"
 
+// Property implementations
+#include "MantidKernel/PropertyWithValue.tcc"
+#include "MantidAPI/WorkspaceProperty.tcc"
+
 using Mantid::MantidVec;
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/Algorithms/CMakeLists.txt b/Framework/Algorithms/CMakeLists.txt
index 7389c90741fb6f3cdce35be4edf39540fad0770f..7fc8e0613ae57fcced8196f9b182302a770332e6 100644
--- a/Framework/Algorithms/CMakeLists.txt
+++ b/Framework/Algorithms/CMakeLists.txt
@@ -655,6 +655,7 @@ set ( TEST_FILES
 	CalculateEfficiencyTest.h
 	CalculateFlatBackgroundTest.h
 	CalculateResolutionTest.h
+	CalculateSlitsTest.h
 	CalculateTransmissionBeamSpreaderTest.h
 	CalculateTransmissionTest.h
 	CalculateZscoreTest.h
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
index e05d58cc4bf837a887d56a034ae4fe1e4bedcb84..4c2a6908c231b4ee191e1b140c13885995dde8cb 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/BinaryOperation.h
@@ -3,6 +3,7 @@
 
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/Workspace_fwd.h"
 #include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidDataObjects/EventList.h"
@@ -107,14 +108,11 @@ protected:
   checkSizeCompatibility(const API::MatrixWorkspace_const_sptr lhs,
                          const API::MatrixWorkspace_const_sptr rhs) const;
 
-  /// Checks if the spectra at the given index of either input workspace is
-  /// masked. If so then the output spectra has zeroed data
-  /// and is also masked. The function returns true if further processing is not
-  /// required on the spectra.
-  virtual bool propagateSpectraMask(const API::MatrixWorkspace_const_sptr lhs,
-                                    const API::MatrixWorkspace_const_sptr rhs,
+  virtual bool propagateSpectraMask(const API::SpectrumInfo &lhsSpectrumInfo,
+                                    const API::SpectrumInfo &rhsSpectrumInfo,
                                     const int64_t index,
-                                    API::MatrixWorkspace_sptr out);
+                                    API::MatrixWorkspace &out,
+                                    API::SpectrumInfo &outSpectrumInfo);
 
   /** Carries out the binary operation on a single spectrum, with another
    *spectrum as the right-hand operand.
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/BoostOptionalToAlgorithmProperty.h b/Framework/Algorithms/inc/MantidAlgorithms/BoostOptionalToAlgorithmProperty.h
index 57466da0d2680fa2b3dfcf535d52276d142fe0e3..a4dc11db02f55d3692f4647b4b0a3d4e18284ae1 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/BoostOptionalToAlgorithmProperty.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/BoostOptionalToAlgorithmProperty.h
@@ -58,7 +58,7 @@ T checkForMandatoryInstrumentDefault(
   auto algProperty = alg->getPointerToProperty(propName);
   if (algProperty->isDefault()) {
     auto defaults = instrument->getNumberParameter(idf_name);
-    if (defaults.size() == 0) {
+    if (defaults.empty()) {
       throw std::runtime_error("No data could be retrieved from the parameters "
                                "and argument wasn't provided: " +
                                propName);
@@ -90,7 +90,7 @@ boost::optional<T> checkForOptionalInstrumentDefault(
   auto algProperty = alg->getPointerToProperty(propName);
   if (algProperty->isDefault()) {
     auto defaults = instrument->getNumberParameter(idf_name);
-    if (defaults.size() != 0) {
+    if (!defaults.empty()) {
       return boost::optional<T>(static_cast<T>(defaults[0]));
     } else {
       return boost::optional<T>();
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDetectorPhases.h b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDetectorPhases.h
index 42278b78a13b2f0b2cdcd51d19508f851bdfeae7..967762d40cafe3dec1abe2abc6a75c1189f1dc5f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDetectorPhases.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalMuonDetectorPhases.h
@@ -4,6 +4,7 @@
 #include "MantidAlgorithms/DllConfig.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/ITableWorkspace_fwd.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidGeometry/IDTypes.h"
 
 namespace Mantid {
@@ -104,4 +105,4 @@ private:
 } // namespace Algorithms
 } // namespace Mantid
 
-#endif /* MANTID_ALGORITHMS_CALMUONDETECTORPHASES_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_CALMUONDETECTORPHASES_H_ */
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
index 00ae1ed5d1491eb8a5b7aec8f26467fb70f50a5a..1aac013bd2f13cdfa7ab9bd0ddcb5be3ba3abcd4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CalculateDIFC.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
 
 namespace Mantid {
@@ -46,7 +47,7 @@ private:
   void calculate(API::Progress &progress, API::MatrixWorkspace_sptr &outputWs,
                  DataObjects::OffsetsWorkspace_sptr &offsetsWS, double l1,
                  double beamlineNorm, Kernel::V3D &beamline,
-                 Kernel::V3D &samplePos, detid2det_map &allDetectors);
+                 Kernel::V3D &samplePos, const API::DetectorInfo &detectorInfo);
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertEmptyToTof.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertEmptyToTof.h
index 8422d341ea20d3d4a0b4ce943cb1c6157dca1912..6baaec50d8e0d5696dcf2d28414979992319890a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertEmptyToTof.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertEmptyToTof.h
@@ -2,6 +2,7 @@
 #define MANTID_ALGORITHMS_CONVERTEMPTYTOTOF_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/System.h"
@@ -41,7 +42,8 @@ namespace Algorithms {
  File change history is stored at: <https://github.com/mantidproject/mantid>
  Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
-class DLLExport ConvertEmptyToTof : public API::Algorithm {
+class DLLExport ConvertEmptyToTof : public API::Algorithm,
+                                    public API::DeprecatedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis.h
index 55cb5e2424cefa0440e5ad2d2cba79ca3959d8c0..c74ee93c9b7229f0448776a393122cb88bcdf442 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis.h
@@ -75,7 +75,7 @@ private:
   /// Execution code
   void exec() override;
   /// Getting Efixed
-  double getEfixed(Geometry::IDetector_const_sptr detector,
+  double getEfixed(const Mantid::Geometry::IDetector &detector,
                    API::MatrixWorkspace_const_sptr inputWS, int emode) const;
 };
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
index 631d51c4df0fc314a1e717336bd09d3da743813b..b1b72002f44b7ce2e52155ef135081408d8c8750 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertSpectrumAxis2.h
@@ -83,7 +83,7 @@ private:
   std::multimap<double, size_t> m_indexMap;
 
   /// Getting Efixed
-  double getEfixed(Geometry::IDetector_const_sptr detector,
+  double getEfixed(const Mantid::Geometry::IDetector &detector,
                    API::MatrixWorkspace_const_sptr inputWS, int emode) const;
 };
 
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
index 52ae0fdc3e1314f8190cc14269c65a4973acc6b0..aac896bdafd53216f2d44c6ab89934c0675a045b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnits.h
@@ -3,6 +3,7 @@
 
 #include "MantidAPI/Algorithm.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidKernel/Unit.h"
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnitsUsingDetectorTable.h b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnitsUsingDetectorTable.h
index 495587a2979ce8fa4cb600f0b5be7774ea092dd8..e802704855b98c2fa5114348a1666f7680faad8c 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnitsUsingDetectorTable.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ConvertUnitsUsingDetectorTable.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAlgorithms/ConvertUnits.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidKernel/Unit.h"
 
 namespace Mantid {
@@ -34,7 +35,9 @@ namespace Algorithms {
   File change history is stored at: <https://github.com/mantidproject/mantid>
   Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-class DLLExport ConvertUnitsUsingDetectorTable : public ConvertUnits {
+class DLLExport ConvertUnitsUsingDetectorTable
+    : public ConvertUnits,
+      public API::DeprecatedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CorrectKiKf.h b/Framework/Algorithms/inc/MantidAlgorithms/CorrectKiKf.h
index 6eaba56ab05f3b58b88cdf33dfc9c0bd7b1341ff..03a706a7b80da5e2f72d5ecef2b48059d49a26e7 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CorrectKiKf.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CorrectKiKf.h
@@ -5,6 +5,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -90,6 +91,9 @@ private:
   template <class T>
   void correctKiKfEventHelper(std::vector<T> &wevector, double efixed,
                               const std::string emodeStr);
+  void getEfixedFromParameterMap(double &Efi, int64_t i,
+                                 const Mantid::API::SpectrumInfo &spectrumInfo,
+                                 const Mantid::Geometry::ParameterMap &pmap);
 };
 
 } // namespace Algorithm
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
index c5d1586eb7689779aec6d8ff58bb0eec99e8455a..a941ff75854498d4926e327e1ae987e29224f13a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/CreateSampleWorkspace.h
@@ -6,6 +6,7 @@
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
index 74da621cc14e284a474bd380ffd973fc712fef02..f2dd709945ceaf8d8c641400900b4998fbbef9a9 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/DetectorEfficiencyCor.h
@@ -2,6 +2,7 @@
 #define MANTID_ALGORITHM_DETECTEFFICIENCYCOR_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/V3D.h"
 #include "MantidGeometry/IDetector.h"
 
@@ -102,7 +103,8 @@ private:
   /// Retrieve algorithm properties
   void retrieveProperties();
   /// Correct the given spectra index for efficiency
-  void correctForEfficiency(int64_t spectraIn);
+  void correctForEfficiency(int64_t spectraIn,
+                            const API::SpectrumInfo &spectrumInfo);
   /// Calculate one over the wave vector for 2 bin bounds
   double calculateOneOverK(double loBinBound, double uppBinBound) const;
   /// Sets the detector geometry cache if necessary
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth.h b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth.h
index 54048ffff2dceebb7b989a7a2baefde34e4c748a..3451483bcf804aa5f0e9850687701b3a95cc4401 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/FFTSmooth.h
@@ -5,6 +5,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 
 namespace Mantid {
@@ -35,8 +36,11 @@ namespace Algorithms {
     File change history is stored at: <https://github.com/mantidproject/mantid>
     Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
-class DLLExport FFTSmooth : public API::Algorithm {
+class DLLExport FFTSmooth : public API::Algorithm,
+                            public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  FFTSmooth() { this->useAlgorithm("FFTSmooth", 2); }
   /// Algorithm's name for identification overriding a virtual method
   const std::string name() const override { return "FFTSmooth"; }
   /// Summary of algorithms purpose
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
index ef62ba2d764401a45c6574277ecb017a16903be1..c717122ebd9bc0c80f36732f0e8eaadae56db7ee 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/GetEi2.h
@@ -6,6 +6,7 @@
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/cow_ptr.h"
 #include "MantidKernel/System.h"
 
@@ -87,7 +88,8 @@ private:
   double calculateEi(const double initial_guess);
   /// Get the distance from the source of the detector at the workspace index
   /// given
-  double getDistanceFromSource(const size_t ws_index) const;
+  double getDistanceFromSource(const size_t ws_index,
+                               const API::SpectrumInfo &spectrumInfo) const;
   /// Calculate the peak position within the given window
   double calculatePeakPosition(const size_t ws_index, const double t_min,
                                const double t_max);
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
index 67736bd9213a7b84a626884d2eff51476b0a0908..7e9ba5dd978e243ec82472306669b8f44d09a01f 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/He3TubeEfficiency.h
@@ -2,6 +2,7 @@
 #define MANTID_ALGORITHM_HE3TUBEEFFICIENCY_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/V3D.h"
 #include "MantidGeometry/IDTypes.h"
 
@@ -84,11 +85,11 @@ private:
   void execEvent();
 
   /// Correct the given spectra index for efficiency
-  void correctForEfficiency(std::size_t spectraIndex);
+  void correctForEfficiency(std::size_t spectraIndex,
+                            const API::SpectrumInfo &spectrumInfo);
   /// Sets the detector geometry cache if necessary
-  void
-  getDetectorGeometry(const boost::shared_ptr<const Geometry::IDetector> &det,
-                      double &detRadius, Kernel::V3D &detAxis);
+  void getDetectorGeometry(const Geometry::IDetector &det, double &detRadius,
+                           Kernel::V3D &detAxis);
   /// Computes the distance to the given shape from a starting point
   double distToSurface(const Kernel::V3D start,
                        const Geometry::Object *shape) const;
@@ -99,14 +100,12 @@ private:
   void logErrors() const;
   /// Retrieve the detector parameters from workspace or detector properties
   double getParameter(std::string wsPropName, std::size_t currentIndex,
-                      std::string detPropName,
-                      boost::shared_ptr<const Geometry::IDetector> idet);
+                      std::string detPropName, const Geometry::IDetector &idet);
   /// Helper for event handling
   template <class T> void eventHelper(std::vector<T> &events, double expval);
   /// Function to calculate exponential contribution
-  double
-  calculateExponential(std::size_t spectraIndex,
-                       boost::shared_ptr<const Geometry::IDetector> idet);
+  double calculateExponential(std::size_t spectraIndex,
+                              const Geometry::IDetector &idet);
 
   /// The user selected (input) workspace
   API::MatrixWorkspace_const_sptr inputWS;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/InterpolationOption.h b/Framework/Algorithms/inc/MantidAlgorithms/InterpolationOption.h
index 7d8617863726bf8aa69a33c3c5e449cd394a5441..fcc79d49f8128ae4b592cc2b97ce7fb384737e80 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/InterpolationOption.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/InterpolationOption.h
@@ -3,6 +3,7 @@
 
 #include "MantidAlgorithms/DllConfig.h"
 #include <memory>
+#include <string>
 
 namespace Mantid {
 namespace HistogramData {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
index 824bd04017c71d5267c6b8b3d854e646a1667d36..5e6c3e8e67269b38b34931aad3107ed28748a61d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/MergeRuns.h
@@ -1,14 +1,12 @@
 #ifndef MANTID_ALGORITHMS_MERGERUNS_H_
 #define MANTID_ALGORITHMS_MERGERUNS_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include <list>
 #include <vector>
 #include <boost/shared_ptr.hpp>
 #include <MantidAPI/MatrixWorkspace.h>
 #include "MantidAPI/MultiPeriodGroupAlgorithm.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidKernel/System.h"
 #include <boost/shared_ptr.hpp>
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
index f2db237673529f3326a6e2ba98e1fb1818343be5..de11602a4578e11e7194ac6b698a0e7d3e90f5b4 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/NormaliseToMonitor.h
@@ -1,12 +1,10 @@
 #ifndef MANTID_ALGORITHMS_NORMALISETOMONITOR_H_
 #define MANTID_ALGORITHMS_NORMALISETOMONITOR_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include "MantidKernel/cow_ptr.h"
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidKernel/IPropertySettings.h"
 
 namespace Mantid {
 namespace HistogramData {
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
index 53a79c01f1ee731c165ba0ec9a1680b4334f47fb..5b84f40d83371650a724a21303f6dbd34a8bdb05 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/ReflectometryReductionOneAuto.h
@@ -3,7 +3,7 @@
 
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/DataProcessorAlgorithm.h"
-#include "MantidGeometry/Instrument.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidKernel/System.h"
 
 #include <boost/optional.hpp>
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/IBeamProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/IBeamProfile.h
index a9305fc807b71a2dfcfc0c9007fd6c00e1efda4b..28a969146ad1ca1c4219b10c101375a227f8f856 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/IBeamProfile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/IBeamProfile.h
@@ -2,15 +2,16 @@
 #define MANTID_ALGORITHMS_IBEAMPROFILE_H_
 
 #include "MantidAlgorithms/DllConfig.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/V3D.h"
 
 namespace Mantid {
+namespace API {
+class Sample;
+}
 namespace Kernel {
 class PseudoRandomNumberGenerator;
 }
-namespace Geometry {
-class BoundingBox;
-}
 namespace Algorithms {
 
 /**
@@ -49,6 +50,8 @@ public:
   virtual Ray generatePoint(Kernel::PseudoRandomNumberGenerator &rng) const = 0;
   virtual Ray generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
                             const Geometry::BoundingBox &) const = 0;
+  virtual Geometry::BoundingBox
+  defineActiveRegion(const API::Sample &) const = 0;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
index 0654a72c9d62e0a198655e6453caed28472ee8fc..05533afd2e1011eebe93cf44be17e12fbeef6a4a 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/MCInteractionVolume.h
@@ -2,13 +2,13 @@
 #define MANTID_ALGORITHMS_MCINTERACTIONVOLUME_H_
 
 #include "MantidAlgorithms/DllConfig.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 
 namespace Mantid {
 namespace API {
 class Sample;
 }
 namespace Geometry {
-class BoundingBox;
 class Object;
 class SampleEnvironment;
 }
@@ -17,6 +17,7 @@ class PseudoRandomNumberGenerator;
 class V3D;
 }
 namespace Algorithms {
+class IBeamProfile;
 
 /**
   Defines a volume where interactions of Tracks and Objects can take place.
@@ -46,21 +47,23 @@ namespace Algorithms {
 */
 class MANTID_ALGORITHMS_DLL MCInteractionVolume {
 public:
-  MCInteractionVolume(const API::Sample &sample);
+  MCInteractionVolume(const API::Sample &sample,
+                      const Geometry::BoundingBox &activeRegion);
   // No creation from temporaries as we store a reference to the object in
   // the sample
-  MCInteractionVolume(const API::Sample &&sample) = delete;
+  MCInteractionVolume(const API::Sample &&sample,
+                      const Geometry::BoundingBox &&activeRegion) = delete;
 
   const Geometry::BoundingBox &getBoundingBox() const;
   double calculateAbsorption(Kernel::PseudoRandomNumberGenerator &rng,
                              const Kernel::V3D &startPos,
-                             const Kernel::V3D &direc,
                              const Kernel::V3D &endPos, double lambdaBefore,
                              double lambdaAfter) const;
 
 private:
   const Geometry::Object &m_sample;
   const Geometry::SampleEnvironment *m_env;
+  const Geometry::BoundingBox m_activeRegion;
 };
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h
index f9d9c874561e45ed6ef500d7a71102196acc66bb..567a72db3352d9c17a124397e66fe053710b8310 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h
@@ -49,6 +49,7 @@ public:
   IBeamProfile::Ray
   generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
                 const Geometry::BoundingBox &bounds) const override;
+  Geometry::BoundingBox defineActiveRegion(const API::Sample &) const override;
 
 private:
   const unsigned short m_upIdx;
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
index c05ada0cf5a0aa76410efde2ef38c854458ffcc8..e7a400f89d8bf819c04a151bcff8fa69bd5a4f8d 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/SumSpectra.h
@@ -34,7 +34,7 @@ namespace Algorithms {
     @author Nick Draper, Tessella Support Services plc
     @date 22/01/2009
 
-    Copyright &copy; 2007-2010 ISIS Rutherford Appleton Laboratory, NScD Oak
+    Copyright &copy; 2007-2016 ISIS Rutherford Appleton Laboratory, NScD Oak
    Ridge National Laboratory & European Spallation Source
 
     This file is part of Mantid.
@@ -80,8 +80,7 @@ private:
                         API::Progress &progress, size_t &numSpectra,
                         size_t &numMasked, size_t &numZeros);
   /// Handle logic for Workspace2D workspaces
-  void doWorkspace2D(API::MatrixWorkspace_const_sptr localworkspace,
-                     API::ISpectrum &outSpec, API::Progress &progress,
+  void doWorkspace2D(API::ISpectrum &outSpec, API::Progress &progress,
                      size_t &numSpectra, size_t &numMasked, size_t &numZeros);
 
   // Overridden Algorithm methods
@@ -91,6 +90,9 @@ private:
                  std::set<int> &indices);
   specnum_t getOutputSpecNo(API::MatrixWorkspace_const_sptr localworkspace);
 
+  API::MatrixWorkspace_sptr
+  replaceSpecialValues(API::MatrixWorkspace_sptr inputWs);
+
   /// The output spectrum number
   specnum_t m_outSpecNum;
   /// The spectrum to start the integration from
@@ -99,14 +101,16 @@ private:
   int m_maxWsInd;
   /// Set true to keep monitors
   bool m_keepMonitors;
+  /// Set true to remove special values before processing
+  bool m_replaceSpecialValues;
   /// numberOfSpectra in the input
   int m_numberOfSpectra;
   /// Blocksize of the input workspace
   int m_yLength;
-  /// Set of indicies to sum
+  /// Set of indices to sum
   std::set<int> m_indices;
 
-  // if calculateing additional workspace with specially weighted averages is
+  // if calculating additional workspace with specially weighted averages is
   // necessary
   bool m_calculateWeightedSum;
 };
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
index c28cdd07658cb4de0142cdfa7317d958b45a5821..cac0457fc2891d919ef2e0766ff8c4199a83bc7b 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapMonitor.h
@@ -70,17 +70,17 @@ private:
   void init() override;
   void exec() override;
 
-  const std::vector<int> unwrapX(MantidVec &newX, const int &spectrum,
+  const std::vector<int> unwrapX(std::vector<double> &newX, const int &spectrum,
                                  const double &Ld);
   std::pair<int, int>
   handleFrameOverlapped(const Mantid::HistogramData::HistogramX &xdata,
                         const double &Ld, std::vector<double> &tempX);
   void unwrapYandE(const API::MatrixWorkspace_sptr &tempWS, const int &spectrum,
-                   const std::vector<int> &rangeBounds, MantidVec &newY,
-                   MantidVec &newE);
+                   const std::vector<int> &rangeBounds,
+                   std::vector<double> &newY, std::vector<double> &newE);
   API::MatrixWorkspace_sptr rebin(const API::MatrixWorkspace_sptr &workspace,
                                   const double &min, const double &max,
-                                  const int &numBins);
+                                  const size_t &numBins);
 
   double m_conversionConstant; ///< The constant used in the conversion from TOF
   /// to wavelength
diff --git a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
index cbfc39c88c6770efed6d594be5ccec43d0366e40..5cb54f2160739fc7571f27c6d740417fb9b4b6cd 100644
--- a/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
+++ b/Framework/Algorithms/inc/MantidAlgorithms/UnwrapSNS.h
@@ -68,8 +68,8 @@ private:
   void execEvent();
   void runMaskDetectors();
 
-  int unwrapX(const Mantid::HistogramData::HistogramX &, MantidVec &,
-              const double &Ld);
+  int unwrapX(const Mantid::HistogramData::HistogramX &,
+              std::vector<double> &dataout, const double &Ld);
   void getTofRangeData(const bool);
   double m_conversionConstant; ///< The constant used in the conversion from TOF
   /// to wavelength
diff --git a/Framework/Algorithms/src/AbsorptionCorrection.cpp b/Framework/Algorithms/src/AbsorptionCorrection.cpp
index 66feb650b51dc9c54b35be411b6bd351e9754e21..c34f897cc0e7acf326e42eabb3cf6ccb3f920cac 100644
--- a/Framework/Algorithms/src/AbsorptionCorrection.cpp
+++ b/Framework/Algorithms/src/AbsorptionCorrection.cpp
@@ -7,6 +7,7 @@
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidHistogramData/Interpolate.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
diff --git a/Framework/Algorithms/src/AddLogDerivative.cpp b/Framework/Algorithms/src/AddLogDerivative.cpp
index a7cb098cce813b79aa405ac0aa3039ac4a52f619..f4319c91c251e686895e2b50a6bf7d9efbce2d9f 100644
--- a/Framework/Algorithms/src/AddLogDerivative.cpp
+++ b/Framework/Algorithms/src/AddLogDerivative.cpp
@@ -1,4 +1,5 @@
 #include "MantidAlgorithms/AddLogDerivative.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/Algorithms/src/AddPeak.cpp b/Framework/Algorithms/src/AddPeak.cpp
index 5bfac64cc3ae6120632d295a6abdd7f4de35fb0d..39201982676402f3437ebc15ad550abd4be7f37a 100644
--- a/Framework/Algorithms/src/AddPeak.cpp
+++ b/Framework/Algorithms/src/AddPeak.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidGeometry/Crystal/IPeak.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/System.h"
 
diff --git a/Framework/Algorithms/src/AddSampleLog.cpp b/Framework/Algorithms/src/AddSampleLog.cpp
index 3cd7993d327076fd7e2e07776a022e7d78ffb346..5e3ebedb3e7deae6efe907c3b8ba402521c990af 100644
--- a/Framework/Algorithms/src/AddSampleLog.cpp
+++ b/Framework/Algorithms/src/AddSampleLog.cpp
@@ -1,9 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/AddSampleLog.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/Workspace.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/Algorithms/src/AnyShapeAbsorption.cpp b/Framework/Algorithms/src/AnyShapeAbsorption.cpp
index 11918abc5234e4b1c0ef266e90340fdfcff9b04b..337a58ad4b662a98f70f06053a613c0fc89cf1e4 100644
--- a/Framework/Algorithms/src/AnyShapeAbsorption.cpp
+++ b/Framework/Algorithms/src/AnyShapeAbsorption.cpp
@@ -1,7 +1,9 @@
 #include "MantidAlgorithms/AnyShapeAbsorption.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/BoundedValidator.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/AppendSpectra.cpp b/Framework/Algorithms/src/AppendSpectra.cpp
index 345b2fe2ab00e4083fd3d2aca94875f9ef674487..fd6986a3d3dded2ecd05fdca9ec3af80a6a4caaf 100644
--- a/Framework/Algorithms/src/AppendSpectra.cpp
+++ b/Framework/Algorithms/src/AppendSpectra.cpp
@@ -156,7 +156,7 @@ void AppendSpectra::fixSpectrumNumbers(const MatrixWorkspace &ws1,
       // check if we're outside the spectra of the first workspace
       const std::string inputLabel =
           i < ws1len ? yAxisWS1->label(i) : yAxisWS2->label(i - ws1len);
-      outputTextAxis->setLabel(i, (inputLabel.size() > 0) ? inputLabel : "");
+      outputTextAxis->setLabel(i, !inputLabel.empty() ? inputLabel : "");
 
     } else if (isNumericAxis) {
       // check if we're outside the spectra of the first workspace
diff --git a/Framework/Algorithms/src/BinaryOperation.cpp b/Framework/Algorithms/src/BinaryOperation.cpp
index e6a713f875be5ca11ba6f125f2c8e32b2d0f2e59..2fd86a39f76ea5a4d539ff47b4411920f32964ec 100644
--- a/Framework/Algorithms/src/BinaryOperation.cpp
+++ b/Framework/Algorithms/src/BinaryOperation.cpp
@@ -1,15 +1,16 @@
 #include "MantidAlgorithms/BinaryOperation.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidDataObjects/WorkspaceSingleValue.h"
-#include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidKernel/Timer.h"
+#include "MantidKernel/Unit.h"
 
 #include <boost/make_shared.hpp>
 
@@ -432,31 +433,28 @@ std::string BinaryOperation::checkSizeCompatibility(
  * Checks if the spectra at the given index of either input workspace is masked.
  * If so then the output spectra has zeroed data
  * and is also masked.
- * @param lhs :: A pointer to the left-hand operand
- * @param rhs :: A pointer to the right-hand operand
+ * @param lhsSpectrumInfo :: The LHS spectrum info object
+ * @param rhsSpectrumInfo :: The RHS spectrum info object
  * @param index :: The workspace index to check
  * @param out :: A pointer to the output workspace
+ * @param outSpectrumInfo :: The spectrum info object of `out`
  * @returns True if further processing is not required on the spectra, false if
  * the binary operation should be performed.
  */
-bool BinaryOperation::propagateSpectraMask(
-    const API::MatrixWorkspace_const_sptr lhs,
-    const API::MatrixWorkspace_const_sptr rhs, const int64_t index,
-    API::MatrixWorkspace_sptr out) {
+bool BinaryOperation::propagateSpectraMask(const SpectrumInfo &lhsSpectrumInfo,
+                                           const SpectrumInfo &rhsSpectrumInfo,
+                                           const int64_t index,
+                                           MatrixWorkspace &out,
+                                           SpectrumInfo &outSpectrumInfo) {
   bool continueOp(true);
-  IDetector_const_sptr det_lhs, det_rhs;
-  try {
-    det_lhs = lhs->getDetector(index);
-    det_rhs = rhs->getDetector(index);
-  } catch (std::runtime_error &) {
-  } catch (std::domain_error &) {
-    // try statement will throw a domain_error when the axis is not a spectra
-    // axis.
-    return continueOp;
-  }
-  if ((det_lhs && det_lhs->isMasked()) || (det_rhs && det_rhs->isMasked())) {
+
+  if ((lhsSpectrumInfo.hasDetectors(index) &&
+       lhsSpectrumInfo.isMasked(index)) ||
+      (rhsSpectrumInfo.hasDetectors(index) &&
+       rhsSpectrumInfo.isMasked(index))) {
     continueOp = false;
-    out->maskWorkspaceIndex(index);
+    out.getSpectrum(index).clearData();
+    PARALLEL_CRITICAL(setMasked) { outSpectrumInfo.setMasked(index, true); }
   }
   return continueOp;
 }
@@ -522,6 +520,9 @@ void BinaryOperation::doSingleColumn() {
   // value from each m_rhs 'spectrum'
   // and then calling the virtual function
   const int64_t numHists = m_lhs->getNumberHistograms();
+  auto &outSpectrumInfo = m_out->mutableSpectrumInfo();
+  auto &lhsSpectrumInfo = m_lhs->spectrumInfo();
+  auto &rhsSpectrumInfo = m_rhs->spectrumInfo();
   if (m_eout) {
     // ---- The output is an EventWorkspace ------
     PARALLEL_FOR_IF(Kernel::threadSafe(*m_lhs, *m_rhs, *m_out))
@@ -531,7 +532,8 @@ void BinaryOperation::doSingleColumn() {
       const double rhsE = m_rhs->readE(i)[0];
 
       // m_out->setX(i, m_lhs->refX(i)); //unnecessary - that was copied before.
-      if (propagateSpectraMask(m_lhs, m_rhs, i, m_out)) {
+      if (propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
+                               outSpectrumInfo)) {
         performEventBinaryOperation(m_eout->getSpectrum(i), rhsY, rhsE);
       }
       m_progress->report(this->name());
@@ -547,7 +549,8 @@ void BinaryOperation::doSingleColumn() {
       const double rhsE = m_rhs->readE(i)[0];
 
       m_out->setX(i, m_lhs->refX(i));
-      if (propagateSpectraMask(m_lhs, m_rhs, i, m_out)) {
+      if (propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
+                               outSpectrumInfo)) {
         // Get reference to output vectors here to break any sharing outside the
         // function call below
         // where the order of argument evaluation is not guaranteed (if it's
@@ -671,6 +674,10 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
   // TODO: Check if this works for event workspaces...
   propagateBinMasks(m_rhs, m_out);
 
+  auto &outSpectrumInfo = m_out->mutableSpectrumInfo();
+  auto &lhsSpectrumInfo = m_lhs->spectrumInfo();
+  auto &rhsSpectrumInfo = m_rhs->spectrumInfo();
+
   if (m_eout) {
     // ----------- The output is an EventWorkspace -------------
 
@@ -690,7 +697,8 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
             continue;
         } else {
           // Check for masking except when mismatched sizes
-          if (!propagateSpectraMask(m_lhs, m_rhs, i, m_out))
+          if (!propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
+                                    outSpectrumInfo))
             continue;
         }
         // Reach here? Do the division
@@ -722,7 +730,8 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
             continue;
         } else {
           // Check for masking except when mismatched sizes
-          if (!propagateSpectraMask(m_lhs, m_rhs, i, m_out))
+          if (!propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
+                                    outSpectrumInfo))
             continue;
         }
 
@@ -760,7 +769,8 @@ void BinaryOperation::do2D(bool mismatchedSpectra) {
           continue;
       } else {
         // Check for masking except when mismatched sizes
-        if (!propagateSpectraMask(m_lhs, m_rhs, i, m_out))
+        if (!propagateSpectraMask(lhsSpectrumInfo, rhsSpectrumInfo, i, *m_out,
+                                  outSpectrumInfo))
           continue;
       }
       // Reach here? Do the division
diff --git a/Framework/Algorithms/src/CalMuonDeadTime.cpp b/Framework/Algorithms/src/CalMuonDeadTime.cpp
index 95a7162e9ac7a865ff69b99eea240db943a69e82..281cb8320f51dbb08252d1af0dcab11973f11b48 100644
--- a/Framework/Algorithms/src/CalMuonDeadTime.cpp
+++ b/Framework/Algorithms/src/CalMuonDeadTime.cpp
@@ -1,4 +1,5 @@
 #include "MantidAlgorithms/CalMuonDeadTime.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IFunction.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/Algorithms/src/CalMuonDetectorPhases.cpp b/Framework/Algorithms/src/CalMuonDetectorPhases.cpp
index 00299e8331d88a577ff5bd98ab8c3ef0de5c26f6..869e2d8b5a71d98ea6fbdc3408f3b0aabc168448 100644
--- a/Framework/Algorithms/src/CalMuonDetectorPhases.cpp
+++ b/Framework/Algorithms/src/CalMuonDetectorPhases.cpp
@@ -13,6 +13,7 @@
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/PhysicalConstants.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/CalculateCountRate.cpp b/Framework/Algorithms/src/CalculateCountRate.cpp
index 2f95a7a4bf5a83aeb14b184bf0e5c8eac3a74032..435b111672aafe77e2d639afd322fe3d18f08eac 100644
--- a/Framework/Algorithms/src/CalculateCountRate.cpp
+++ b/Framework/Algorithms/src/CalculateCountRate.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/make_unique.h"
diff --git a/Framework/Algorithms/src/CalculateDIFC.cpp b/Framework/Algorithms/src/CalculateDIFC.cpp
index 9ba0e4d740fbedb1fb121fb9e3dad455396fa9dc..9aeeaecce80eb65034bf7e45d5a57cf5e25912c3 100644
--- a/Framework/Algorithms/src/CalculateDIFC.cpp
+++ b/Framework/Algorithms/src/CalculateDIFC.cpp
@@ -70,21 +70,18 @@ void CalculateDIFC::exec() {
     outputWs->setTitle("DIFC workspace");
   }
 
-  Instrument_const_sptr instrument = inputWs->getInstrument();
-
   double l1;
   Kernel::V3D beamline, samplePos;
   double beamlineNorm;
 
-  instrument->getInstrumentParameters(l1, beamline, beamlineNorm, samplePos);
+  inputWs->getInstrument()->getInstrumentParameters(l1, beamline, beamlineNorm,
+                                                    samplePos);
 
-  // To get all the detector ID's
-  detid2det_map allDetectors;
-  instrument->getDetectors(allDetectors);
+  const auto &detectorInfo = inputWs->detectorInfo();
 
-  API::Progress progress(this, 0, 1, allDetectors.size());
+  API::Progress progress(this, 0, 1, detectorInfo.size());
   calculate(progress, outputWs, offsetsWs, l1, beamlineNorm, beamline,
-            samplePos, allDetectors);
+            samplePos, detectorInfo);
 
   setProperty("OutputWorkspace", outputWs);
 }
@@ -94,24 +91,24 @@ void CalculateDIFC::calculate(API::Progress &progress,
                               DataObjects::OffsetsWorkspace_sptr &offsetsWS,
                               double l1, double beamlineNorm,
                               Kernel::V3D &beamline, Kernel::V3D &samplePos,
-                              detid2det_map &allDetectors) {
+                              const API::DetectorInfo &detectorInfo) {
   SpecialWorkspace2D_sptr localWS =
       boost::dynamic_pointer_cast<SpecialWorkspace2D>(outputWs);
 
+  const auto &detectorIDs = detectorInfo.detectorIDs();
+
   // Now go through all
-  detid2det_map::const_iterator it = allDetectors.begin();
-  for (; it != allDetectors.end(); ++it) {
-    Geometry::IDetector_const_sptr det = it->second;
-    if ((!det->isMasked()) && (!det->isMonitor())) {
-      const detid_t detID = it->first;
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    if ((!detectorInfo.isMasked(i)) && (!detectorInfo.isMonitor(i))) {
       double offset = 0.;
       if (offsetsWS)
-        offset = offsetsWS->getValue(detID, 0.);
+        offset = offsetsWS->getValue(detectorIDs[i], 0.);
 
       double difc = Geometry::Instrument::calcConversion(
-          l1, beamline, beamlineNorm, samplePos, det, offset);
+          l1, beamline, beamlineNorm, samplePos, detectorInfo.position(i),
+          offset);
       difc = 1. / difc; // calcConversion gives 1/DIFC
-      localWS->setValue(detID, difc);
+      localWS->setValue(detectorIDs[i], difc);
     }
 
     progress.report("Calculate DIFC");
diff --git a/Framework/Algorithms/src/CalculateEfficiency.cpp b/Framework/Algorithms/src/CalculateEfficiency.cpp
index 7d07b04b413e556821a6c970df1408d73a194ba7..315d8294f540d93c3eb61ae82794b560a67393ff 100644
--- a/Framework/Algorithms/src/CalculateEfficiency.cpp
+++ b/Framework/Algorithms/src/CalculateEfficiency.cpp
@@ -311,8 +311,11 @@ void CalculateEfficiency::maskComponent(MatrixWorkspace &ws,
       }
     }
     auto indexList = ws.getIndicesFromDetectorIDs(detectorList);
-    for (const auto &idx : indexList)
-      ws.maskWorkspaceIndex(idx);
+    auto &spectrumInfo = ws.mutableSpectrumInfo();
+    for (const auto &idx : indexList) {
+      ws.getSpectrum(idx).clearData();
+      spectrumInfo.setMasked(idx, true);
+    }
   } catch (std::exception &) {
     g_log.warning("Expecting the component " + componentName +
                   " to be a CompAssembly, e.g., a bank. Component not masked!");
diff --git a/Framework/Algorithms/src/CalculateTransmission.cpp b/Framework/Algorithms/src/CalculateTransmission.cpp
index 0afbda643dd0cbbd447bb924c8007ed62e190a4e..cdd86c426b1b401731378b7847f9ec92d47099ae 100644
--- a/Framework/Algorithms/src/CalculateTransmission.cpp
+++ b/Framework/Algorithms/src/CalculateTransmission.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/IFunction.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/Instrument.h"
@@ -492,9 +493,9 @@ void CalculateTransmission::logIfNotMonitor(API::MatrixWorkspace_sptr sampleWS,
                                             size_t index) {
   const std::string message = "The detector at index " + std::to_string(index) +
                               " is not a monitor in the ";
-  if (!sampleWS->getDetector(index)->isMonitor())
+  if (!sampleWS->spectrumInfo().isMonitor(index))
     g_log.information(message + "sample workspace.");
-  if (!directWS->getDetector(index)->isMonitor())
+  if (!directWS->spectrumInfo().isMonitor(index))
     g_log.information(message + "direct workspace.");
 }
 
diff --git a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
index 24569b44a43b8a08bb9a4fc7d3214b844cb9ce17..78f5f0feb6011e1ede4f479f595d22b9107ceef2 100644
--- a/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
+++ b/Framework/Algorithms/src/CalculateTransmissionBeamSpreader.cpp
@@ -4,6 +4,7 @@
 #include "MantidAlgorithms/CalculateTransmissionBeamSpreader.h"
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/HistogramValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
@@ -244,7 +245,7 @@ API::MatrixWorkspace_sptr
 CalculateTransmissionBeamSpreader::extractSpectrum(API::MatrixWorkspace_sptr WS,
                                                    const size_t index) {
   // Check that given spectra are monitors
-  if (!WS->getDetector(index)->isMonitor()) {
+  if (!WS->spectrumInfo().isMonitor(index)) {
     g_log.information(
         "The Incident Beam Monitor UDET provided is not marked as a monitor");
   }
diff --git a/Framework/Algorithms/src/ChopData.cpp b/Framework/Algorithms/src/ChopData.cpp
index 3867c52997728d2e30379965465cbccc5e942216..0190ef65e842379730b9dbeaab8d25953372edbe 100644
--- a/Framework/Algorithms/src/ChopData.cpp
+++ b/Framework/Algorithms/src/ChopData.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/SpectraAxisValidator.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/MultiThreaded.h"
diff --git a/Framework/Algorithms/src/ClearMaskFlag.cpp b/Framework/Algorithms/src/ClearMaskFlag.cpp
index dfa7f3a53e68d50b6c096d9c49fbb7d33b5fdf46..4e9c7fcba0bc913cd5129834133e180db52fad51 100644
--- a/Framework/Algorithms/src/ClearMaskFlag.cpp
+++ b/Framework/Algorithms/src/ClearMaskFlag.cpp
@@ -1,9 +1,8 @@
 #include "MantidAlgorithms/ClearMaskFlag.h"
 
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/MatrixWorkspace.h"
-#include "MantidGeometry/Instrument/ParameterMap.h"
-#include "MantidGeometry/Instrument/Detector.h"
-#include "MantidGeometry/Instrument/Component.h"
+#include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
 
 namespace Mantid {
@@ -16,7 +15,6 @@ using Kernel::Direction;
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(ClearMaskFlag)
 
-//----------------------------------------------------------------------------------------------
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string ClearMaskFlag::name() const { return "ClearMaskFlag"; }
 
@@ -28,7 +26,6 @@ const std::string ClearMaskFlag::category() const {
   return "Transforms\\Masking";
 }
 
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void ClearMaskFlag::init() {
@@ -41,28 +38,22 @@ void ClearMaskFlag::init() {
                   "the whole instrument.");
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void ClearMaskFlag::exec() {
   MatrixWorkspace_sptr ws = getProperty("Workspace");
   std::string componentName = getPropertyValue("ComponentName");
-
-  // Clear the mask flags
-  Geometry::ParameterMap &pmap = ws->instrumentParameters();
+  auto &detectorInfo = ws->mutableDetectorInfo();
 
   if (!componentName.empty()) {
-    auto instrument = ws->getInstrument();
-    auto component = instrument->getComponentByName(componentName);
-    boost::shared_ptr<const Geometry::ICompAssembly> componentAssembly =
-        boost::dynamic_pointer_cast<const Geometry::ICompAssembly>(component);
-    std::vector<Geometry::IComponent_const_sptr> children;
-    componentAssembly->getChildren(children, true);
-    for (auto det : children) {
-      pmap.addBool(det.get(), "masked", false);
+    std::vector<IDetector_const_sptr> detectors;
+    ws->getInstrument()->getDetectorsInBank(detectors, componentName);
+    for (const auto &det : detectors) {
+      auto index = detectorInfo.indexOf(det->getID());
+      detectorInfo.setMasked(index, false);
     }
   } else {
-    pmap.clearParametersByName("masked");
+    detectorInfo.clearMaskFlags();
   }
 }
 
diff --git a/Framework/Algorithms/src/CompareWorkspaces.cpp b/Framework/Algorithms/src/CompareWorkspaces.cpp
index b3b18d6703b369c5901479d1638bc3ea70d63bbf..9b0f7c130f327420b765d22b939da53223cbf88c 100644
--- a/Framework/Algorithms/src/CompareWorkspaces.cpp
+++ b/Framework/Algorithms/src/CompareWorkspaces.cpp
@@ -9,9 +9,11 @@
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidGeometry/Crystal/IPeak.h"
+#include "MantidKernel/Unit.h"
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/ConjoinWorkspaces.cpp b/Framework/Algorithms/src/ConjoinWorkspaces.cpp
index 20af212f7cb187abd3dd70dad71d10c6f801d084..a750c432267993ea500a65e03ddb6009e8a9130e 100644
--- a/Framework/Algorithms/src/ConjoinWorkspaces.cpp
+++ b/Framework/Algorithms/src/ConjoinWorkspaces.cpp
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/ConjoinWorkspaces.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/WorkspaceHistory.h"
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/ConvertAxisByFormula.cpp b/Framework/Algorithms/src/ConvertAxisByFormula.cpp
index 5941af7807e84f817f720ee98027f19a5d52d29c..ada62fb7d4e67eb951a6db5656442b4f7a2f0481 100644
--- a/Framework/Algorithms/src/ConvertAxisByFormula.cpp
+++ b/Framework/Algorithms/src/ConvertAxisByFormula.cpp
@@ -178,7 +178,7 @@ void ConvertAxisByFormula::exec() {
     if ((isRaggedBins) || (isGeometryRequired)) {
       // ragged bins or geometry used - we have to calculate for every spectra
       size_t numberOfSpectra_i = outputWs->getNumberHistograms();
-      const auto &spectrumInfo = outputWs->spectrumInfo();
+      auto &spectrumInfo = outputWs->mutableSpectrumInfo();
 
       size_t failedDetectorCount = 0;
       Progress prog(this, 0.6, 1.0, numberOfSpectra_i);
@@ -192,7 +192,8 @@ void ConvertAxisByFormula::exec() {
         // both handled the same way
         {
           // could not find the geometry info for this spectra
-          outputWs->maskWorkspaceIndex(i);
+          outputWs->getSpectrum(i).clearData();
+          spectrumInfo.setMasked(i, true);
           failedDetectorCount++;
         }
         prog.report();
diff --git a/Framework/Algorithms/src/ConvertDiffCal.cpp b/Framework/Algorithms/src/ConvertDiffCal.cpp
index 90b46ea4f97906261070c5c72880ae2b4ae52b6a..6d95ac735057d0ab6595b1473b91479f4bef4c44 100644
--- a/Framework/Algorithms/src/ConvertDiffCal.cpp
+++ b/Framework/Algorithms/src/ConvertDiffCal.cpp
@@ -112,8 +112,8 @@ double calculateDIFC(OffsetsWorkspace_const_sptr offsetsWS,
 
   // the factor returned is what is needed to convert TOF->d-spacing
   // the table is supposed to be filled with DIFC which goes the other way
-  const double factor = Instrument::calcConversion(l1, beamline, beamline_norm,
-                                                   samplePos, detector, offset);
+  const double factor = Instrument::calcConversion(
+      l1, beamline, beamline_norm, samplePos, detector->getPos(), offset);
   return 1. / factor;
 }
 
diff --git a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
index f566afe5adb0f4a5885d1a0a8937fb0bb6b7938e..8d7d1252590090f4fbce57f648fa8330a7cff05b 100644
--- a/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
+++ b/Framework/Algorithms/src/ConvertSpectrumAxis.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectraAxisValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -95,15 +96,16 @@ void ConvertSpectrumAxis::exec() {
       emode = 2;
     const double delta = 0.0;
     double efixed;
+    auto &spectrumInfo = inputWS->spectrumInfo();
     for (size_t i = 0; i < nHist; i++) {
       std::vector<double> xval{inputWS->x(i).front(), inputWS->x(i).back()};
-      IDetector_const_sptr detector = inputWS->getDetector(i);
       double twoTheta, l1val, l2;
-      if (!detector->isMonitor()) {
-        twoTheta = inputWS->detectorTwoTheta(*detector);
-        l2 = detector->getDistance(*sample);
+      if (!spectrumInfo.isMonitor(i)) {
+        twoTheta = spectrumInfo.twoTheta(i);
+        l2 = spectrumInfo.l2(i);
         l1val = l1;
-        efixed = getEfixed(detector, inputWS, emode); // get efixed
+        efixed =
+            getEfixed(spectrumInfo.detector(i), inputWS, emode); // get efixed
       } else {
         twoTheta = 0.0;
         l2 = l1;
@@ -172,14 +174,15 @@ void ConvertSpectrumAxis::exec() {
   setProperty("OutputWorkspace", outputWS);
 }
 
-double ConvertSpectrumAxis::getEfixed(IDetector_const_sptr detector,
-                                      MatrixWorkspace_const_sptr inputWS,
-                                      int emode) const {
+double
+ConvertSpectrumAxis::getEfixed(const Mantid::Geometry::IDetector &detector,
+                               MatrixWorkspace_const_sptr inputWS,
+                               int emode) const {
   double efixed(0);
   double efixedProp = getProperty("Efixed");
   if (efixedProp != EMPTY_DBL()) {
     efixed = efixedProp;
-    g_log.debug() << "Detector: " << detector->getID() << " Efixed: " << efixed
+    g_log.debug() << "Detector: " << detector.getID() << " Efixed: " << efixed
                   << "\n";
   } else {
     if (emode == 1) {
@@ -192,29 +195,29 @@ double ConvertSpectrumAxis::getEfixed(IDetector_const_sptr detector,
         } else {
           efixed = 0.0;
           g_log.warning() << "Efixed could not be found for detector "
-                          << detector->getID() << ", set to 0.0\n";
+                          << detector.getID() << ", set to 0.0\n";
         }
       } else {
         efixed = 0.0;
         g_log.warning() << "Efixed could not be found for detector "
-                        << detector->getID() << ", set to 0.0\n";
+                        << detector.getID() << ", set to 0.0\n";
       }
     } else if (emode == 2) {
-      std::vector<double> efixedVec = detector->getNumberParameter("Efixed");
+      std::vector<double> efixedVec = detector.getNumberParameter("Efixed");
       if (efixedVec.empty()) {
-        int detid = detector->getID();
+        int detid = detector.getID();
         IDetector_const_sptr detectorSingle =
             inputWS->getInstrument()->getDetector(detid);
         efixedVec = detectorSingle->getNumberParameter("Efixed");
       }
       if (!efixedVec.empty()) {
         efixed = efixedVec.at(0);
-        g_log.debug() << "Detector: " << detector->getID()
+        g_log.debug() << "Detector: " << detector.getID()
                       << " EFixed: " << efixed << "\n";
       } else {
         efixed = 0.0;
         g_log.warning() << "Efixed could not be found for detector "
-                        << detector->getID() << ", set to 0.0\n";
+                        << detector.getID() << ", set to 0.0\n";
       }
     }
   }
diff --git a/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp b/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp
index 95c8c1d9b4b11ba605eac98c4cedba61f3158216..7e890887c830342d0607417fa9ce2df734613fb7 100644
--- a/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp
+++ b/Framework/Algorithms/src/ConvertSpectrumAxis2.cpp
@@ -15,6 +15,8 @@
 
 #include <cfloat>
 
+constexpr double rad2deg = 180.0 / M_PI;
+
 namespace Mantid {
 namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
@@ -151,12 +153,13 @@ void ConvertSpectrumAxis2::createElasticQMap(API::Progress &progress,
   else if (emodeStr == "Indirect")
     emode = 2;
 
+  auto &spectrumInfo = inputWS->spectrumInfo();
   for (size_t i = 0; i < nHist; i++) {
-    IDetector_const_sptr detector = inputWS->getDetector(i);
     double twoTheta(0.0), efixed(0.0);
-    if (!detector->isMonitor()) {
-      twoTheta = 0.5 * inputWS->detectorTwoTheta(*detector);
-      efixed = getEfixed(detector, inputWS, emode); // get efixed
+    if (!spectrumInfo.isMonitor(i)) {
+      twoTheta = 0.5 * spectrumInfo.twoTheta(i);
+      efixed =
+          getEfixed(spectrumInfo.detector(i), inputWS, emode); // get efixed
     } else {
       twoTheta = 0.0;
       efixed = DBL_MIN;
@@ -229,14 +232,15 @@ MatrixWorkspace_sptr ConvertSpectrumAxis2::createOutputWorkspace(
   return outputWorkspace;
 }
 
-double ConvertSpectrumAxis2::getEfixed(IDetector_const_sptr detector,
-                                       MatrixWorkspace_const_sptr inputWS,
-                                       int emode) const {
+double
+ConvertSpectrumAxis2::getEfixed(const Mantid::Geometry::IDetector &detector,
+                                MatrixWorkspace_const_sptr inputWS,
+                                int emode) const {
   double efixed(0);
   double efixedProp = getProperty("Efixed");
   if (efixedProp != EMPTY_DBL()) {
     efixed = efixedProp;
-    g_log.debug() << "Detector: " << detector->getID() << " Efixed: " << efixed
+    g_log.debug() << "Detector: " << detector.getID() << " Efixed: " << efixed
                   << "\n";
   } else {
     if (emode == 1) {
@@ -247,20 +251,20 @@ double ConvertSpectrumAxis2::getEfixed(IDetector_const_sptr detector,
                                     "workspace. Please provide a value.");
       }
     } else if (emode == 2) {
-      std::vector<double> efixedVec = detector->getNumberParameter("Efixed");
+      std::vector<double> efixedVec = detector.getNumberParameter("Efixed");
       if (efixedVec.empty()) {
-        int detid = detector->getID();
+        int detid = detector.getID();
         IDetector_const_sptr detectorSingle =
             inputWS->getInstrument()->getDetector(detid);
         efixedVec = detectorSingle->getNumberParameter("Efixed");
       }
       if (!efixedVec.empty()) {
         efixed = efixedVec.at(0);
-        g_log.debug() << "Detector: " << detector->getID()
+        g_log.debug() << "Detector: " << detector.getID()
                       << " EFixed: " << efixed << "\n";
       } else {
         g_log.warning() << "Efixed could not be found for detector "
-                        << detector->getID() << ", please provide a value\n";
+                        << detector.getID() << ", please provide a value\n";
         throw std::invalid_argument("Could not retrieve Efixed from the "
                                     "detector. Please provide a value.");
       }
diff --git a/Framework/Algorithms/src/ConvertToConstantL2.cpp b/Framework/Algorithms/src/ConvertToConstantL2.cpp
index 8a2d807fe4fb76cdcf1b8a2af890f30d2ab27418..6410f92040daef8b4bd19dfd5d84bb5cc385022c 100644
--- a/Framework/Algorithms/src/ConvertToConstantL2.cpp
+++ b/Framework/Algorithms/src/ConvertToConstantL2.cpp
@@ -9,6 +9,8 @@
 #include "MantidGeometry/Instrument/ComponentHelper.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidKernel/CompositeValidator.h"
+#include "MantidKernel/PhysicalConstants.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/UnitFactory.h"
 
 #include <cmath>
diff --git a/Framework/Algorithms/src/ConvertUnits.cpp b/Framework/Algorithms/src/ConvertUnits.cpp
index b8daac1c8f3cedcdebd0fccf887e100003c44a5a..60f066fb630ebe8cc2ce1b8f558983bd6008f5e3 100644
--- a/Framework/Algorithms/src/ConvertUnits.cpp
+++ b/Framework/Algorithms/src/ConvertUnits.cpp
@@ -517,6 +517,9 @@ ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit,
       (!parameters.empty()) &&
       find(parameters.begin(), parameters.end(), "Always") != parameters.end();
 
+  auto localFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
+  auto localOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
+
   // Perform Sanity Validation before creating workspace
   double checkefixed = efixedProp;
   double checkl2;
@@ -528,12 +531,10 @@ ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit,
     // copy the X values for the check
     auto checkXValues = inputWS->readX(checkIndex);
     // Convert the input unit to time-of-flight
-    auto checkFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
-    auto checkOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
-    checkFromUnit->toTOF(checkXValues, emptyVec, l1, checkl2, checktwoTheta,
+    localFromUnit->toTOF(checkXValues, emptyVec, l1, checkl2, checktwoTheta,
                          emode, checkefixed, checkdelta);
     // Convert from time-of-flight to the desired unit
-    checkOutputUnit->fromTOF(checkXValues, emptyVec, l1, checkl2, checktwoTheta,
+    localOutputUnit->fromTOF(checkXValues, emptyVec, l1, checkl2, checktwoTheta,
                              emode, checkefixed, checkdelta);
   }
 
@@ -543,7 +544,7 @@ ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit,
       boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
   assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check
 
-  const auto &outSpectrumInfo = outputWS->spectrumInfo();
+  auto &outSpectrumInfo = outputWS->mutableSpectrumInfo();
   // Loop over the histograms (detector spectra)
   for (int64_t i = 0; i < numberOfSpectra_i; ++i) {
     double efixed = efixedProp;
@@ -554,11 +555,6 @@ ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit,
     if (getDetectorValues(outSpectrumInfo, *outputUnit, emode, *outputWS,
                           signedTheta, i, efixed, l2, twoTheta)) {
 
-      // Make local copies of the units. This allows running the loop in
-      // parallel
-      auto localFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
-      auto localOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
-
       /// @todo Don't yet consider hold-off (delta)
       const double delta = 0.0;
 
@@ -581,7 +577,9 @@ ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUnit,
       // detectors, this call is
       // the same as just zeroing out the data (calling clearData on the
       // spectrum)
-      outputWS->maskWorkspaceIndex(i);
+      outputWS->getSpectrum(i).clearData();
+      if (outSpectrumInfo.hasDetectors(i))
+        outSpectrumInfo.setMasked(i, true);
     }
 
     prog.report("Convert to " + m_outputUnit->unitID());
diff --git a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
index 9906fb3a512a4d65e02ca9485a32508cb45d996c..4eda0c21ddb3b1092072d94dbc2c9f265fe59cc8 100644
--- a/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
+++ b/Framework/Algorithms/src/ConvertUnitsUsingDetectorTable.cpp
@@ -4,6 +4,7 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidAPI/HistogramValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/ListValidator.h"
@@ -174,23 +175,20 @@ MatrixWorkspace_sptr ConvertUnitsUsingDetectorTable::convertViaTOF(
       boost::dynamic_pointer_cast<EventWorkspace>(outputWS);
   assert(static_cast<bool>(eventWS) == m_inputEvents); // Sanity check
 
-  // TODO: Check why this parallel stuff breaks
+  auto &spectrumInfo = outputWS->mutableSpectrumInfo();
+
   // Loop over the histograms (detector spectra)
-  // PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS))
   for (int64_t i = 0; i < numberOfSpectra_i; ++i) {
 
     // Lets find what row this spectrum Number appears in our detector table.
 
-    // PARALLEL_START_INTERUPT_REGION
-
     std::size_t wsid = i;
 
-    try {
-
+    if (spectrumInfo.hasDetectors(i)) {
       double deg2rad = M_PI / 180.;
 
-      auto det = outputWS->getDetector(i);
-      int specNo = det->getID();
+      auto &det = spectrumInfo.detector(i);
+      int specNo = det.getID();
 
       // int spectraNumber = static_cast<int>(spectraColumn->toDouble(i));
       // wsid = outputWS->getIndexFromSpectrumNumber(spectraNumber);
@@ -248,23 +246,23 @@ MatrixWorkspace_sptr ConvertUnitsUsingDetectorTable::convertViaTOF(
       } else {
         // Not found
         failedDetectorCount++;
-        outputWS->maskWorkspaceIndex(wsid);
+        outputWS->getSpectrum(wsid).clearData();
+        if (spectrumInfo.hasDetectors(wsid))
+          spectrumInfo.setMasked(wsid, true);
       }
 
-    } catch (Exception::NotFoundError &) {
+    } else {
       // Get to here if exception thrown when calculating distance to detector
       failedDetectorCount++;
       // Since you usually (always?) get to here when there's no attached
       // detectors, this call is
       // the same as just zeroing out the data (calling clearData on the
       // spectrum)
-      outputWS->maskWorkspaceIndex(i);
+      outputWS->getSpectrum(i).clearData();
     }
 
     prog.report("Convert to " + m_outputUnit->unitID());
-    // PARALLEL_END_INTERUPT_REGION
   } // loop over spectra
-  // PARALLEL_CHECK_INTERUPT_REGION
 
   if (failedDetectorCount != 0) {
     g_log.information() << "Something went wrong for " << failedDetectorCount
diff --git a/Framework/Algorithms/src/CopyInstrumentParameters.cpp b/Framework/Algorithms/src/CopyInstrumentParameters.cpp
index 2f35738ae3b0e7208a749dec75292fe33be59aac..d17d1a9ca7485acde9481ee63e53d86ac433a6e8 100644
--- a/Framework/Algorithms/src/CopyInstrumentParameters.cpp
+++ b/Framework/Algorithms/src/CopyInstrumentParameters.cpp
@@ -1,10 +1,9 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/CopyInstrumentParameters.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 
+#include <algorithm>
 #include <iostream>
 
 namespace Mantid {
@@ -97,9 +96,38 @@ void CopyInstrumentParameters::exec() {
     // changed parameters
     m_receivingWorkspace->swapInstrumentParameters(targMap);
 
+    // Deal with parameters that are stored in DetectorInfo. Note that this
+    // mimics what the above code is doing when copying the ParameterMap, even
+    // if it may not make sense. That is, we do a matching purely based on
+    // detector IDs, but completely ignore whether these belong to different
+    // instruments or different incompatible versions of the same instrument.
+    // This algorithm should probably enforce stricter compatiblity checks.
+    const auto &givingDetInfo = m_givingWorkspace->detectorInfo();
+    auto &receivingDetInfo = m_receivingWorkspace->mutableDetectorInfo();
+    try {
+      // If all detector IDs match a simple assignment should work.
+      receivingDetInfo = givingDetInfo;
+    } catch (std::runtime_error &) {
+      // Fallback for mismatch of detector IDs.
+      const auto &givingDetIDs = givingDetInfo.detectorIDs();
+      for (const auto detID : receivingDetInfo.detectorIDs()) {
+        // TODO Uncomment code and add handling for every field being added to
+        // Beamline::DetectorInfo.
+        // const auto receivingIndex = receivingDetInfo.indexOf(detID);
+        if (std::find(givingDetIDs.begin(), givingDetIDs.end(), detID) !=
+            givingDetIDs.end()) {
+          // const auto givingIndex = givingDetInfo.indexOf(detID);
+          // Copy values for all fields in DetectorInfo
+        } else {
+          // Set default values for all fields in DetectorInfo
+        }
+      }
+    }
   } else {
     // unchanged Copy parameters
     m_receivingWorkspace->replaceInstrumentParameters(givParams);
+    m_receivingWorkspace->mutableDetectorInfo() =
+        m_givingWorkspace->detectorInfo();
   }
 }
 
diff --git a/Framework/Algorithms/src/CorelliCrossCorrelate.cpp b/Framework/Algorithms/src/CorelliCrossCorrelate.cpp
index ff4a27633e09540e514db233157aa51ed61540c5..25b1e157925aa7a3dcd293ac05dc1b798d65d2aa 100644
--- a/Framework/Algorithms/src/CorelliCrossCorrelate.cpp
+++ b/Framework/Algorithms/src/CorelliCrossCorrelate.cpp
@@ -10,8 +10,12 @@
 #include "MantidGeometry/muParser_Silent.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
+#include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 namespace Mantid {
 namespace Algorithms {
 
diff --git a/Framework/Algorithms/src/CorrectKiKf.cpp b/Framework/Algorithms/src/CorrectKiKf.cpp
index 49611e20d851c8d88125234d0f79abaad8a2db74..bcfae45fb0f1bb6c9e6f49a2a7a8494b82778177 100644
--- a/Framework/Algorithms/src/CorrectKiKf.cpp
+++ b/Framework/Algorithms/src/CorrectKiKf.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/CorrectKiKf.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/EventWorkspace.h"
@@ -95,6 +96,7 @@ void CorrectKiKf::exec() {
 
   // Get the parameter map
   const ParameterMap &pmap = outputWS->constInstrumentParameters();
+  const auto &spectrumInfo = inputWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
   for (int64_t i = 0; i < int64_t(numberOfSpectra); ++i) {
@@ -105,27 +107,15 @@ void CorrectKiKf::exec() {
     if (emodeStr == "Indirect") {
       if (efixedProp != EMPTY_DBL())
         Efi = efixedProp;
-      else
-        try {
-          IDetector_const_sptr det = inputWS->getDetector(i);
-          if (!det->isMonitor()) {
-            try {
-              Parameter_sptr par = pmap.getRecursive(det.get(), "Efixed");
-              if (par) {
-                Efi = par->value<double>();
-                g_log.debug() << "Detector: " << det->getID()
-                              << " EFixed: " << Efi << "\n";
-              }
-            } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use
-                                                single provided value */
-            }
-          }
-
-        } catch (std::runtime_error &) {
-          g_log.information() << "Workspace Index " << i
-                              << ": cannot find detector"
-                              << "\n";
-        }
+      // If a DetectorGroup is present should provide a value as a property
+      // instead
+      else if (spectrumInfo.hasUniqueDetector(i)) {
+        getEfixedFromParameterMap(Efi, i, spectrumInfo, pmap);
+      } else {
+        g_log.information() << "Workspace Index " << i
+                            << ": cannot find detector"
+                            << "\n";
+      }
     }
 
     auto &yOut = outputWS->mutableY(i);
@@ -221,6 +211,7 @@ void CorrectKiKf::execEvent() {
   const ParameterMap &pmap = outputWS->constInstrumentParameters();
 
   int64_t numHistograms = static_cast<int64_t>(inputWS->getNumberHistograms());
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   API::Progress prog = API::Progress(this, 0.0, 1.0, numHistograms);
   PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS))
   for (int64_t i = 0; i < numHistograms; ++i) {
@@ -230,29 +221,17 @@ void CorrectKiKf::execEvent() {
     // Now get the detector object for this histogram to check if monitor
     // or to get Ef for indirect geometry
     if (emodeStr == "Indirect") {
-      if (efixedProp != EMPTY_DBL())
+      if (efixedProp != EMPTY_DBL()) {
         Efi = efixedProp;
-      else
-        try {
-          IDetector_const_sptr det = inputWS->getDetector(i);
-          if (!det->isMonitor()) {
-            try {
-              Parameter_sptr par = pmap.getRecursive(det.get(), "Efixed");
-              if (par) {
-                Efi = par->value<double>();
-                g_log.debug() << "Detector: " << det->getID()
-                              << " EFixed: " << Efi << "\n";
-              }
-            } catch (std::runtime_error &) { /* Throws if a DetectorGroup, use
-                                                single provided value */
-            }
-          }
-
-        } catch (std::runtime_error &) {
-          g_log.information() << "Workspace Index " << i
-                              << ": cannot find detector"
-                              << "\n";
-        }
+        // If a DetectorGroup is present should provide a value as a property
+        // instead
+      } else if (spectrumInfo.hasUniqueDetector(i)) {
+        getEfixedFromParameterMap(Efi, i, spectrumInfo, pmap);
+      } else {
+        g_log.information() << "Workspace Index " << i
+                            << ": cannot find detector"
+                            << "\n";
+      }
     }
 
     if (emodeStr == "Indirect")
@@ -324,5 +303,21 @@ void CorrectKiKf::correctKiKfEventHelper(std::vector<T> &wevector,
   }
 }
 
+void CorrectKiKf::getEfixedFromParameterMap(double &Efi, int64_t i,
+                                            const SpectrumInfo &spectrumInfo,
+                                            const ParameterMap &pmap) {
+  Efi = 0;
+
+  if (spectrumInfo.isMonitor(i))
+    return;
+
+  const auto &det = spectrumInfo.detector(i);
+  Parameter_sptr par = pmap.getRecursive(&det, "Efixed");
+  if (par) {
+    Efi = par->value<double>();
+    g_log.debug() << "Detector: " << det.getID() << " EFixed: " << Efi << "\n";
+  }
+}
+
 } // namespace Algorithm
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
index f356ccd1f4d391bda04a02fe4cd370934d82cb50..3c2cbe2ab2f1b5808a45b8b8bfe04e43524ff0f3 100644
--- a/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateGroupingWorkspace.cpp
@@ -6,6 +6,7 @@
 #include "MantidKernel/System.h"
 #include <boost/algorithm/string/detail/classification.hpp>
 #include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
 #include <queue>
 #include <fstream>
 #include "MantidAPI/FileProperty.h"
@@ -70,11 +71,13 @@ void CreateGroupingWorkspace::init() {
                   "Use / or , to separate multiple groups. "
                   "If empty, then an empty GroupingWorkspace will be created.");
 
-  std::vector<std::string> grouping{"", "All", "Group", "Column", "bank"};
+  std::vector<std::string> grouping{"", "All", "Group", "2_4Grouping", "Column",
+                                    "bank"};
   declareProperty(
       "GroupDetectorsBy", "", boost::make_shared<StringListValidator>(grouping),
       "Only used if GroupNames is empty: All detectors as one group, Groups "
-      "(East,West for SNAP), Columns for SNAP, detector banks");
+      "(Group or East,West for SNAP), 2_4Grouping (SNAP), Columns, detector "
+      "banks");
   declareProperty("MaxRecursionDepth", 5,
                   "Number of levels to search into the instrument (default=5)");
 
@@ -354,12 +357,23 @@ void CreateGroupingWorkspace::exec() {
     inst = tempWS->getInstrument();
   }
 
+  // Validation for 2_4Grouping input used only for SNAP
+  if (inst->getName().compare("SNAP") != 0 &&
+      grouping.compare("2_4Grouping") == 0) {
+    const std::string message("2_4Grouping only works for SNAP.");
+    g_log.error(message);
+    throw std::invalid_argument(message);
+  }
+
   if (GroupNames.empty() && OldCalFilename.empty()) {
     if (grouping.compare("All") == 0) {
       GroupNames = inst->getName();
     } else if (inst->getName().compare("SNAP") == 0 &&
                grouping.compare("Group") == 0) {
       GroupNames = "East,West";
+    } else if (inst->getName().compare("SNAP") == 0 &&
+               grouping.compare("2_4Grouping") == 0) {
+      GroupNames = "Column1,Column2,Column3,Column4,Column5,Column6,";
     } else {
       sortnames = true;
       GroupNames = "";
@@ -391,9 +405,20 @@ void CreateGroupingWorkspace::exec() {
 
   Progress prog(this, 0.2, 1.0, outWS->getNumberHistograms());
   // Make the grouping one of three ways:
-  if (!GroupNames.empty())
+  if (!GroupNames.empty()) {
     detIDtoGroup = makeGroupingByNames(GroupNames, inst, prog, sortnames);
-  else if (!OldCalFilename.empty())
+    if (grouping.compare("2_4Grouping") == 0) {
+      std::map<detid_t, int>::const_iterator it_end = detIDtoGroup.end();
+      std::map<detid_t, int>::const_iterator it;
+      for (it = detIDtoGroup.begin(); it != it_end; ++it) {
+        if (it->second < 5)
+          detIDtoGroup[it->first] = 1;
+        else
+          detIDtoGroup[it->first] = 2;
+      }
+    }
+
+  } else if (!OldCalFilename.empty())
     detIDtoGroup = readGroupingFile(OldCalFilename, prog);
   else if ((numGroups > 0) && !componentName.empty())
     detIDtoGroup =
diff --git a/Framework/Algorithms/src/CreateLogPropertyTable.cpp b/Framework/Algorithms/src/CreateLogPropertyTable.cpp
index a22bef79ccbabd6d61b932d7b14e321f04c71c57..4b6f41a8e91e5f3dfceaf8b857eea95aff01e005 100644
--- a/Framework/Algorithms/src/CreateLogPropertyTable.cpp
+++ b/Framework/Algorithms/src/CreateLogPropertyTable.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/CreateLogPropertyTable.h"
 
 #include "MantidAPI/ITableWorkspace.h"
@@ -8,6 +5,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/Algorithms/src/CreateLogTimeCorrection.cpp b/Framework/Algorithms/src/CreateLogTimeCorrection.cpp
index 94a3f3b9663747446eede1a87d3d383784415d5f..7398d113b689e7b72f0b354e3b6480d2dc476ac6 100644
--- a/Framework/Algorithms/src/CreateLogTimeCorrection.cpp
+++ b/Framework/Algorithms/src/CreateLogTimeCorrection.cpp
@@ -69,7 +69,7 @@ void CreateLogTimeCorrection::exec() {
 
   string filename = getProperty("OutputFilename");
   g_log.information() << "Output file name is " << filename << ".\n";
-  if (filename.size() > 0) {
+  if (!filename.empty()) {
     writeCorrectionToFile(filename);
   }
 }
diff --git a/Framework/Algorithms/src/CreatePSDBleedMask.cpp b/Framework/Algorithms/src/CreatePSDBleedMask.cpp
index 3c096be5f472d65eaacaf2f4717970b1749f2556..56e19b29e6c385928ede57999e58581eced0f02d 100644
--- a/Framework/Algorithms/src/CreatePSDBleedMask.cpp
+++ b/Framework/Algorithms/src/CreatePSDBleedMask.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/CreatePSDBleedMask.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -98,6 +99,8 @@ void CreatePSDBleedMask::exec() {
 
   API::Progress progress(this, 0, 1, numSpectra);
 
+  const auto &spectrumInfo = inputWorkspace->spectrumInfo();
+
   // NOTE: This loop is intentionally left unparallelized as the majority of the
   // work requires a lock around it which actually slows down the loop.
   // Another benefit of keep it serial is losing the need for a call to 'sort'
@@ -106,24 +109,23 @@ void CreatePSDBleedMask::exec() {
   // correct
   // order
   for (int i = 0; i < numSpectra; ++i) {
-    IDetector_const_sptr det;
-    try {
-      det = inputWorkspace->getDetector(i);
-    } catch (Kernel::Exception::NotFoundError &) {
+    if (!spectrumInfo.hasDetectors(i))
       continue;
-    }
-    if (det->isMonitor())
+
+    if (spectrumInfo.isMonitor(i))
       continue;
 
-    boost::shared_ptr<const Geometry::DetectorGroup> group =
-        boost::dynamic_pointer_cast<const Geometry::DetectorGroup>(det);
+    auto &det = spectrumInfo.detector(i);
+    boost::shared_ptr<const Geometry::IComponent> parent;
 
-    if (group) {
-      det = group->getDetectors().front();
-      if (!det)
-        continue;
+    if (!spectrumInfo.hasUniqueDetector(i)) {
+      const Geometry::DetectorGroup &group =
+          dynamic_cast<const Geometry::DetectorGroup &>(det);
+      parent = group.getDetectors().front()->getParent();
+    } else {
+      parent = det.getParent();
     }
-    boost::shared_ptr<const Geometry::IComponent> parent = det->getParent();
+
     if (!parent)
       continue;
 
diff --git a/Framework/Algorithms/src/CreatePeaksWorkspace.cpp b/Framework/Algorithms/src/CreatePeaksWorkspace.cpp
index 3907b4f7e01c9f88e0b4146bc07dcb4fdcf20a7a..5798838d5e6609528a966970bdd2abd9bc75157b 100644
--- a/Framework/Algorithms/src/CreatePeaksWorkspace.cpp
+++ b/Framework/Algorithms/src/CreatePeaksWorkspace.cpp
@@ -1,6 +1,7 @@
 #include "MantidAlgorithms/CreatePeaksWorkspace.h"
 #include "MantidKernel/System.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 
diff --git a/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp b/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp
index 480a7750823e9452083b21e9df38f6183e48f35c..ea2bfebd41d0d8b2c43a20267c8abbdea0a4737b 100644
--- a/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp
+++ b/Framework/Algorithms/src/CreateTransmissionWorkspace.cpp
@@ -1,6 +1,7 @@
 #include "MantidAlgorithms/CreateTransmissionWorkspace.h"
 #include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
 
diff --git a/Framework/Algorithms/src/CylinderAbsorption.cpp b/Framework/Algorithms/src/CylinderAbsorption.cpp
index e53f194cb50b1cee566ca1b87b98f380e64b14bd..c54af1c352c05dce23a9b745f06519f3d678dc70 100644
--- a/Framework/Algorithms/src/CylinderAbsorption.cpp
+++ b/Framework/Algorithms/src/CylinderAbsorption.cpp
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/CylinderAbsorption.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/BoundedValidator.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/DeleteWorkspace.cpp b/Framework/Algorithms/src/DeleteWorkspace.cpp
index 0bc10a13d6ee26c295a1b84f4c53d2549c2654fc..030dd4a64a8a0f80dddfeb057855b9b7e84f6adb 100644
--- a/Framework/Algorithms/src/DeleteWorkspace.cpp
+++ b/Framework/Algorithms/src/DeleteWorkspace.cpp
@@ -1,19 +1,12 @@
-//--------------------------------------------------------------------------
-// Includes
-//--------------------------------------------------------------------------
 #include "MantidAlgorithms/DeleteWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 namespace Mantid {
-
 namespace Algorithms {
 
 // Register the algorithm
 DECLARE_ALGORITHM(DeleteWorkspace)
 
-//--------------------------------------------------------------------------
-// Private member functions
-//--------------------------------------------------------------------------
-
 /// Initialize the algorithm properties
 void DeleteWorkspace::init() {
   declareProperty(Kernel::make_unique<API::WorkspaceProperty<API::Workspace>>(
diff --git a/Framework/Algorithms/src/DetectorDiagnostic.cpp b/Framework/Algorithms/src/DetectorDiagnostic.cpp
index 010b0b5d2714495e4dcb036b73d68ed48a23c2bc..7b1ea1099f6a9540a272c204363d5b64748246b5 100644
--- a/Framework/Algorithms/src/DetectorDiagnostic.cpp
+++ b/Framework/Algorithms/src/DetectorDiagnostic.cpp
@@ -1,4 +1,6 @@
 #include "MantidAlgorithms/DetectorDiagnostic.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspaceHelpers.h"
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
@@ -604,29 +606,26 @@ std::vector<double> DetectorDiagnostic::calculateMedian(
   std::vector<double> medianvec;
   g_log.debug("Calculating the median count rate of the spectra");
 
+  bool checkForMask = false;
+  Geometry::Instrument_const_sptr instrument = input.getInstrument();
+  if (instrument != nullptr) {
+    checkForMask = ((instrument->getSource() != nullptr) &&
+                    (instrument->getSample() != nullptr));
+  }
+  const auto &spectrumInfo = input.spectrumInfo();
+
   for (const auto &hists : indexmap) {
     std::vector<double> medianInput;
     const int nhists = static_cast<int>(hists.size());
     // The maximum possible length is that of workspace length
     medianInput.reserve(nhists);
 
-    bool checkForMask = false;
-    Geometry::Instrument_const_sptr instrument = input.getInstrument();
-    if (instrument != nullptr) {
-      checkForMask = ((instrument->getSource() != nullptr) &&
-                      (instrument->getSample() != nullptr));
-    }
-
     PARALLEL_FOR_IF(Kernel::threadSafe(input))
     for (int i = 0; i < nhists; ++i) { // NOLINT
       PARALLEL_START_INTERUPT_REGION
 
-      if (checkForMask) {
-        const std::set<detid_t> &detids =
-            input.getSpectrum(hists[i]).getDetectorIDs();
-        if (instrument->isDetectorMasked(detids))
-          continue;
-        if (instrument->isMonitor(detids))
+      if (checkForMask && spectrumInfo.hasDetectors(hists[i])) {
+        if (spectrumInfo.isMasked(hists[i]) || spectrumInfo.isMonitor(hists[i]))
           continue;
       }
 
diff --git a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp
index d1c4f78f5d14ea76bd104dffdca0e3fc27cd438c..46828fde5fa5aa85bc21ddbd505f5c5e0d21639f 100644
--- a/Framework/Algorithms/src/DetectorEfficiencyCor.cpp
+++ b/Framework/Algorithms/src/DetectorEfficiencyCor.cpp
@@ -3,10 +3,13 @@
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
+#include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/Exception.h"
@@ -120,6 +123,7 @@ void DetectorEfficiencyCor::exec() {
   int64_t numHists = m_inputWS->getNumberHistograms();
   double numHists_d = static_cast<double>(numHists);
   const int64_t progStep = static_cast<int64_t>(ceil(numHists_d / 100.0));
+  auto &spectrumInfo = m_inputWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS))
   for (int64_t i = 0; i < numHists; ++i) {
@@ -127,7 +131,7 @@ void DetectorEfficiencyCor::exec() {
 
     m_outputWS->setSharedX(i, m_inputWS->sharedX(i));
     try {
-      correctForEfficiency(i);
+      correctForEfficiency(i, spectrumInfo);
     } catch (Exception::NotFoundError &) {
       // zero the Y data that can't be corrected
       m_outputWS->mutableY(i) *= 0.0;
@@ -180,18 +184,23 @@ void DetectorEfficiencyCor::retrieveProperties() {
   }
 }
 
-/** Corrects a spectra for the detector efficiency calculated from detector
-information
-Gets the detector information and uses this to calculate its efficiency
-*  @param spectraIn :: index of the spectrum to get the efficiency for
-*  @throw invalid_argument if the shape of a detector is isn't a cylinder
-aligned along one axis
-*  @throw NotFoundError if the detector or its gas pressure or wall thickness
-were not found
-*/
-void DetectorEfficiencyCor::correctForEfficiency(int64_t spectraIn) {
-  IDetector_const_sptr det = m_inputWS->getDetector(spectraIn);
-  if (det->isMonitor() || det->isMasked()) {
+/**
+ * Corrects a spectra for the detector efficiency calculated from detector
+ * information
+ * Gets the detector information and uses this to calculate its efficiency
+ *  @param spectraIn :: index of the spectrum to get the efficiency for
+ *  @param spectrumInfo :: The SpectrumInfo object for the input workspace
+ *  @throw invalid_argument if the shape of a detector is not a cylinder aligned
+ * along one axis
+ *  @throw NotFoundError if the detector or its gas pressure or wall thickness
+ * were not found
+ */
+void DetectorEfficiencyCor::correctForEfficiency(
+    int64_t spectraIn, const SpectrumInfo &spectrumInfo) {
+  if (!spectrumInfo.hasDetectors(spectraIn))
+    throw Exception::NotFoundError("No detectors found", spectraIn);
+
+  if (spectrumInfo.isMonitor(spectraIn) || spectrumInfo.isMasked(spectraIn)) {
     return;
   }
 
@@ -209,9 +218,6 @@ void DetectorEfficiencyCor::correctForEfficiency(int64_t spectraIn) {
                                                         // average the
                                                         // correction computing
                                                         // it for the spectrum
-  if (ndets == 0) {
-    throw Exception::NotFoundError("No detectors found", spectraIn);
-  }
 
   // Storage for the reciprocal wave vectors that are calculated as the
   // correction proceeds
diff --git a/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp b/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp
index 66ec494094395d3a0564e14bdcf33b991cb0bb69..54475523b3552d23620654bb8315d6bf017366ff 100644
--- a/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp
+++ b/Framework/Algorithms/src/DetectorEfficiencyCorUser.cpp
@@ -8,6 +8,7 @@
 #include "MantidGeometry/muParser_Silent.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
+#include "MantidKernel/Strings.h"
 
 using Mantid::HistogramData::Histogram;
 using Mantid::HistogramData::Points;
diff --git a/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp b/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp
index a57422657fab20266d7e1e1eec6699112eabe040..f4b9a526b8eef66ade492616921726592a41ba52 100644
--- a/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp
+++ b/Framework/Algorithms/src/DiffractionEventCalibrateDetectors.cpp
@@ -1,8 +1,6 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/DiffractionEventCalibrateDetectors.h"
 #include "MantidAlgorithms/GSLFunctions.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IFunction.h"
 #include "MantidAPI/InstrumentValidator.h"
diff --git a/Framework/Algorithms/src/DiffractionFocussing2.cpp b/Framework/Algorithms/src/DiffractionFocussing2.cpp
index 4e5d01254e97d441c5322f6c5fba68f5c1ec06f8..9c53f1b3a87754e930bfd2cef0dbb6f73638afad 100644
--- a/Framework/Algorithms/src/DiffractionFocussing2.cpp
+++ b/Framework/Algorithms/src/DiffractionFocussing2.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/RawCountValidator.h"
 #include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
@@ -551,6 +552,7 @@ void DiffractionFocussing2::determineRebinParameters() {
     checkForMask = ((instrument->getSource() != nullptr) &&
                     (instrument->getSample() != nullptr));
   }
+  const auto &spectrumInfo = m_matrixInputW->spectrumInfo();
 
   groupAtWorkspaceIndex.resize(nHist);
   for (int wi = 0; wi < nHist;
@@ -561,10 +563,8 @@ void DiffractionFocussing2::determineRebinParameters() {
     if (group == -1)
       continue;
 
-    // the spectrum is the real thing we want to work with
-    const auto &spec = m_matrixInputW->getSpectrum(wi);
     if (checkForMask) {
-      if (instrument->isDetectorMasked(spec.getDetectorIDs())) {
+      if (spectrumInfo.isMasked(wi)) {
         groupAtWorkspaceIndex[wi] = -1;
         continue;
       }
@@ -578,7 +578,7 @@ void DiffractionFocussing2::determineRebinParameters() {
     }
     const double min = (gpit->second).first;
     const double max = (gpit->second).second;
-    auto &X = spec.x();
+    auto &X = m_matrixInputW->x(wi);
     double temp = X.front();
     if (temp < (min)) // New Xmin found
       (gpit->second).first = temp;
diff --git a/Framework/Algorithms/src/EditInstrumentGeometry.cpp b/Framework/Algorithms/src/EditInstrumentGeometry.cpp
index c727e25f80786eea70e2797b67025e27daa8e0dd..fb7b9a82722fa9b0f84e89c937166dbfe9eefa36 100644
--- a/Framework/Algorithms/src/EditInstrumentGeometry.cpp
+++ b/Framework/Algorithms/src/EditInstrumentGeometry.cpp
@@ -300,9 +300,6 @@ void EditInstrumentGeometry::exec() {
   instrument->markAsSource(source);
   source->setPos(0.0, 0.0, -1.0 * l1);
 
-  // Add the new instrument
-  workspace->setInstrument(instrument);
-
   // Add/copy detector information
   auto indexInfo = workspace->indexInfo();
   std::vector<detid_t> detIDs;
@@ -339,6 +336,9 @@ void EditInstrumentGeometry::exec() {
   } // ENDFOR workspace index
   indexInfo.setDetectorIDs(std::move(detIDs));
   workspace->setIndexInfo(indexInfo);
+
+  // Add the new instrument
+  workspace->setInstrument(instrument);
 }
 
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/ExportTimeSeriesLog.cpp b/Framework/Algorithms/src/ExportTimeSeriesLog.cpp
index 4ae94729ef60e636719249a76d1e9491e762d72d..6090c20b461d5c1bc14943298e031e37d8af44b8 100644
--- a/Framework/Algorithms/src/ExportTimeSeriesLog.cpp
+++ b/Framework/Algorithms/src/ExportTimeSeriesLog.cpp
@@ -122,7 +122,7 @@ void ExportTimeSeriesLog::exportLog(const std::string &logname,
   std::vector<Kernel::DateAndTime> times;
   std::vector<double> values;
 
-  if (logname.size() > 0) {
+  if (!logname.empty()) {
     // Log
     Kernel::TimeSeriesProperty<double> *tlog =
         dynamic_cast<Kernel::TimeSeriesProperty<double> *>(
diff --git a/Framework/Algorithms/src/ExtractMask.cpp b/Framework/Algorithms/src/ExtractMask.cpp
index 4c735bd8db9d69a8b84378a4f35949a62ba7db90..bd2a694cd77f5ecfedc4e0db4381031a9769946d 100644
--- a/Framework/Algorithms/src/ExtractMask.cpp
+++ b/Framework/Algorithms/src/ExtractMask.cpp
@@ -80,10 +80,6 @@ void ExtractMask::exec() {
   }
   PARALLEL_CHECK_INTERUPT_REGION
 
-  // Clear all the "masked" bits on the output masked workspace
-  Geometry::ParameterMap &pmap = maskWS->instrumentParameters();
-  pmap.clearParametersByName("masked");
-
   g_log.information() << maskWS->getNumberMasked() << " spectra are masked\n";
   g_log.information() << detectorList.size() << " detectors are masked\n";
   setProperty("OutputWorkspace", maskWS);
diff --git a/Framework/Algorithms/src/ExtractMaskToTable.cpp b/Framework/Algorithms/src/ExtractMaskToTable.cpp
index 6b3d82165fc9a11218bfca054bf845d0c166ea06..c1982376720f308b7aa1e28eb17ecb97b3f9eb68 100644
--- a/Framework/Algorithms/src/ExtractMaskToTable.cpp
+++ b/Framework/Algorithms/src/ExtractMaskToTable.cpp
@@ -1,4 +1,5 @@
 #include "MantidAlgorithms/ExtractMaskToTable.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataObjects/MaskWorkspace.h"
@@ -202,22 +203,19 @@ std::vector<detid_t> ExtractMaskToTable::extractMaskFromMatrixWorkspace() {
   std::vector<detid_t> maskeddetids;
 
   // Get on hold of instrument
-  Instrument_const_sptr instrument = m_dataWS->getInstrument();
-  if (!instrument)
+  const auto &detectorInfo = m_dataWS->detectorInfo();
+  if (detectorInfo.size() == 0)
     throw runtime_error("There is no instrument in input workspace.");
 
   // Extract
-  size_t numdets = instrument->getNumberDetectors();
-  vector<detid_t> detids = instrument->getDetectorIDs();
+  const vector<detid_t> &detids = detectorInfo.detectorIDs();
 
-  for (size_t i = 0; i < numdets; ++i) {
-    detid_t tmpdetid = detids[i];
-    IDetector_const_sptr tmpdetector = instrument->getDetector(tmpdetid);
-    bool masked = tmpdetector->isMasked();
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    bool masked = detectorInfo.isMasked(i);
     if (masked) {
-      maskeddetids.push_back(tmpdetid);
+      maskeddetids.push_back(detids[i]);
     }
-    g_log.debug() << "[DB] Detector No. " << i << ":  ID = " << tmpdetid
+    g_log.debug() << "[DB] Detector No. " << i << ":  ID = " << detids[i]
                   << ", Masked = " << masked << ".\n";
   }
 
diff --git a/Framework/Algorithms/src/FilterEvents.cpp b/Framework/Algorithms/src/FilterEvents.cpp
index 599d9830e904ff43fd888923f9c5c7a7b64820fc..43b622fcac7ea738a3719d9137059a741ad9c2ed 100644
--- a/Framework/Algorithms/src/FilterEvents.cpp
+++ b/Framework/Algorithms/src/FilterEvents.cpp
@@ -1,4 +1,5 @@
 #include "MantidAlgorithms/FilterEvents.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/SpectrumInfo.h"
@@ -305,7 +306,7 @@ void FilterEvents::processAlgorithmProperties() {
   if (m_isSplittersRelativeTime) {
     // Using relative time
     std::string start_time_str = getProperty("FilterStartTime");
-    if (start_time_str.size() > 0) {
+    if (!start_time_str.empty()) {
       // User specifies the filter starting time
       Kernel::DateAndTime temp_shift_time(start_time_str);
       m_filterStartTime = temp_shift_time;
diff --git a/Framework/Algorithms/src/FindPeaks.cpp b/Framework/Algorithms/src/FindPeaks.cpp
index e2e5d619df2a6118204f62bf8233b1e3fd92c932..1970805ca417c667bb99ec394bc53aafd6cc723d 100644
--- a/Framework/Algorithms/src/FindPeaks.cpp
+++ b/Framework/Algorithms/src/FindPeaks.cpp
@@ -983,7 +983,7 @@ void FindPeaks::fitSinglePeak(const API::MatrixWorkspace_sptr &input,
   std::string errmsg = estimatePeakParameters(
       vecX, vecY, i_min, i_max, vecbkgdparvalue, i_obscentre, est_height,
       est_fwhm, est_leftfwhm, est_rightfwhm);
-  if (errmsg.size() > 0) {
+  if (!errmsg.empty()) {
     // Unable to estimate peak
     i_obscentre = i_centre;
     est_fwhm = 1.;
diff --git a/Framework/Algorithms/src/FitPeak.cpp b/Framework/Algorithms/src/FitPeak.cpp
index f28a19783e16ea36e092fd53c7e50532bfc72472..cf3e596986d436d0cfe29dc55189f75c9a4d7ab6 100644
--- a/Framework/Algorithms/src/FitPeak.cpp
+++ b/Framework/Algorithms/src/FitPeak.cpp
@@ -264,7 +264,7 @@ bool FitOneSinglePeak::hasSetupToFitPeak(std::string &errmsg) {
   if (!m_dataWS)
     errmsg += "Data workspace ";
 
-  if (errmsg.size() > 0) {
+  if (!errmsg.empty()) {
     errmsg = "These parameters have not been set for fitting peak: " + errmsg;
     return false;
   }
@@ -835,7 +835,7 @@ double FitOneSinglePeak::fitCompositeFunction(
   // Check fit result
   goodness = checkFittedPeak(peakfunc, goodness, errorreason);
 
-  if (errorreason.size() > 0)
+  if (!errorreason.empty())
     m_sstream << "Error reason of fit peak+background composite: "
               << errorreason << "\n";
 
diff --git a/Framework/Algorithms/src/FlatPlateAbsorption.cpp b/Framework/Algorithms/src/FlatPlateAbsorption.cpp
index d3e84128f3ff86da4460d1ccab6044f1edb41d3e..65edf29229e768263534cdd451517944a8e0e474 100644
--- a/Framework/Algorithms/src/FlatPlateAbsorption.cpp
+++ b/Framework/Algorithms/src/FlatPlateAbsorption.cpp
@@ -1,9 +1,8 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/FlatPlateAbsorption.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/BoundedValidator.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/GenerateEventsFilter.cpp b/Framework/Algorithms/src/GenerateEventsFilter.cpp
index fa2ec6a0e2cf0c4df440ec7aebff5e3bc67a3902..34eb203fba83d0de4d893b626884d338575f304b 100644
--- a/Framework/Algorithms/src/GenerateEventsFilter.cpp
+++ b/Framework/Algorithms/src/GenerateEventsFilter.cpp
@@ -216,7 +216,7 @@ void GenerateEventsFilter::processInOutWorkspaces() {
 
   // Output splitter information workspace
   std::string title = getProperty("TitleOfSplitters");
-  if (title.size() == 0) {
+  if (title.empty()) {
     // Using default
     title = "Splitters";
   }
@@ -263,8 +263,8 @@ void GenerateEventsFilter::processInputTime() {
   std::string s_inptf = this->getProperty("StopTime");
 
   // Default
-  bool defaultstart = (s_inpt0.size() == 0);
-  bool defaultstop = (s_inptf.size() == 0);
+  bool defaultstart = s_inpt0.empty();
+  bool defaultstop = s_inptf.empty();
 
   // Determine format
   bool instringformat = true;
@@ -1674,7 +1674,7 @@ void GenerateEventsFilter::addNewTimeFilterSplitter(
   }
 
   // Information
-  if (info.size() > 0) {
+  if (!info.empty()) {
     API::TableRow row = m_filterInfoWS->appendRow();
     row << wsindex << info;
   }
diff --git a/Framework/Algorithms/src/GenerateIPythonNotebook.cpp b/Framework/Algorithms/src/GenerateIPythonNotebook.cpp
index ee5f18dc756624435606a9e84798cb5fbe815190..529b33549073a74d25262e8d5c7f7ee6288da4d6 100644
--- a/Framework/Algorithms/src/GenerateIPythonNotebook.cpp
+++ b/Framework/Algorithms/src/GenerateIPythonNotebook.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AlgorithmHistory.h"
 #include "MantidAPI/NotebookBuilder.h"
+#include "MantidAPI/Workspace.h"
 
 #include <fstream>
 
@@ -21,9 +22,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(GenerateIPythonNotebook)
 
-//----------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
 */
 void GenerateIPythonNotebook::init() {
@@ -61,7 +59,6 @@ void GenerateIPythonNotebook::init() {
       "When to specify which algorithm version was used by Mantid.");
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
 */
 void GenerateIPythonNotebook::exec() {
diff --git a/Framework/Algorithms/src/GeneratePeaks.cpp b/Framework/Algorithms/src/GeneratePeaks.cpp
index 729c5b9ea6387ccdaec2bf8fd7e3128600338c21..b132b81487dd8f8c2a86a5193eff8bb832ad3935 100644
--- a/Framework/Algorithms/src/GeneratePeaks.cpp
+++ b/Framework/Algorithms/src/GeneratePeaks.cpp
@@ -166,7 +166,7 @@ void GeneratePeaks::processAlgProperties(std::string &peakfunctype,
                                          std::string &bkgdfunctype) {
   // Function parameters
   std::string paramwsname = getPropertyValue("PeakParametersWorkspace");
-  if (paramwsname.size() > 0) {
+  if (!paramwsname.empty()) {
     // Using parameter table workspace has a higher priority
     m_useFuncParamWS = true;
     m_funcParamWS = getProperty("PeakParametersWorkspace");
diff --git a/Framework/Algorithms/src/GeneratePythonScript.cpp b/Framework/Algorithms/src/GeneratePythonScript.cpp
index a5624685f535d8c70740aa329e4ffa3d0497279e..5ee5894becf7f62babb485492b17bdbe834ab4b9 100644
--- a/Framework/Algorithms/src/GeneratePythonScript.cpp
+++ b/Framework/Algorithms/src/GeneratePythonScript.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AlgorithmHistory.h"
 #include "MantidAPI/ScriptBuilder.h"
+#include "MantidAPI/Workspace.h"
 
 #include <fstream>
 
@@ -21,9 +22,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(GeneratePythonScript)
 
-//----------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
 */
 void GeneratePythonScript::init() {
@@ -60,7 +58,6 @@ void GeneratePythonScript::init() {
       "When to specify which algorithm version was used by Mantid.");
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
 */
 void GeneratePythonScript::exec() {
diff --git a/Framework/Algorithms/src/GetAllEi.cpp b/Framework/Algorithms/src/GetAllEi.cpp
index 52d211f369fd24a26b1b11af68848c5324a14ab9..ce1be24a33b0e93bf90759afeee000adac26da80 100644
--- a/Framework/Algorithms/src/GetAllEi.cpp
+++ b/Framework/Algorithms/src/GetAllEi.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/HistoWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
@@ -226,8 +227,8 @@ void GetAllEi::exec() {
   auto monitorWS = buildWorkspaceToFit(inputWS, det1WSIndex);
 
   // recalculate delay time from chopper position to monitor position
-  auto detector1 = inputWS->getDetector(det1WSIndex);
-  double mon1Distance = detector1->getDistance(*moderator);
+  const auto &detector1 = inputWS->spectrumInfo().detector(det1WSIndex);
+  double mon1Distance = detector1.getDistance(*moderator);
   double TOF0 = mon1Distance / velocity;
 
   //--->> below is reserved until full chopper's implementation is available;
diff --git a/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp b/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp
index 9f4f0beb3356eaf24905c8d998f1e7bad3a5e277..d3e8835e03d7e4493079cfd027e8fc75d47bd2bb 100644
--- a/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp
+++ b/Framework/Algorithms/src/GetDetOffsetsMultiPeaks.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/IPeakFunction.h"
 #include "MantidAPI/IBackgroundFunction.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/EventWorkspace.h"
@@ -303,7 +304,7 @@ void GetDetOffsetsMultiPeaks::processProperties() {
   // Fit windows
   std::string fitwinwsname = getPropertyValue("FitwindowTableWorkspace");
   g_log.notice() << "FitWindowTableWorkspace name: " << fitwinwsname << "\n";
-  if (fitwinwsname.size() > 0) {
+  if (!fitwinwsname.empty()) {
     // Use fit window workspace for each spectrum
     TableWorkspace_sptr fitwintablews = getProperty("FitwindowTableWorkspace");
     importFitWindowTableWorkspace(fitwintablews);
@@ -360,7 +361,7 @@ void GetDetOffsetsMultiPeaks::processProperties() {
 
   // Input resolution
   std::string reswsname = getPropertyValue("InputResolutionWorkspace");
-  if (reswsname.size() == 0)
+  if (reswsname.empty())
     m_hasInputResolution = false;
   else {
     m_inputResolutionWS = getProperty("InputResolutionWorkspace");
@@ -475,6 +476,7 @@ void GetDetOffsetsMultiPeaks::calculateDetectorsOffsets() {
   // Fit all the spectra with a gaussian
   Progress prog(this, 0, 1.0, nspec);
 
+  auto &spectrumInfo = m_maskWS->mutableSpectrumInfo();
   // cppcheck-suppress syntaxError
     PRAGMA_OMP(parallel for schedule(dynamic, 1) )
     for (int wi = 0; wi < nspec; ++wi) {
@@ -509,7 +511,8 @@ void GetDetOffsetsMultiPeaks::calculateDetectorsOffsets() {
           const size_t workspaceIndex = mapEntry->second;
           if (offsetresult.mask > 0.9) {
             // Being masked
-            m_maskWS->maskWorkspaceIndex(workspaceIndex);
+            m_maskWS->getSpectrum(workspaceIndex).clearData();
+            spectrumInfo.setMasked(workspaceIndex, true);
             m_maskWS->mutableY(workspaceIndex)[0] = offsetresult.mask;
           } else {
             // Using the detector
diff --git a/Framework/Algorithms/src/GetDetectorOffsets.cpp b/Framework/Algorithms/src/GetDetectorOffsets.cpp
index 5ce99a549b31ded3c5c9594601522212aa645330..e7cdc66de35303c94659427317c17ef8f6693543 100644
--- a/Framework/Algorithms/src/GetDetectorOffsets.cpp
+++ b/Framework/Algorithms/src/GetDetectorOffsets.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/IPeakFunction.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
@@ -108,6 +109,7 @@ void GetDetectorOffsets::exec() {
 
   // Fit all the spectra with a gaussian
   Progress prog(this, 0, 1.0, nspec);
+  auto &spectrumInfo = maskWS->mutableSpectrumInfo();
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputW))
   for (int wi = 0; wi < nspec; ++wi) {
     PARALLEL_START_INTERUPT_REGION
@@ -134,7 +136,8 @@ void GetDetectorOffsets::exec() {
         const size_t workspaceIndex = mapEntry->second;
         if (mask == 1.) {
           // Being masked
-          maskWS->maskWorkspaceIndex(workspaceIndex);
+          maskWS->getSpectrum(workspaceIndex).clearData();
+          spectrumInfo.setMasked(workspaceIndex, true);
           maskWS->mutableY(workspaceIndex)[0] = mask;
         } else {
           // Using the detector
diff --git a/Framework/Algorithms/src/GetEi2.cpp b/Framework/Algorithms/src/GetEi2.cpp
index e6d6c8fcb86a102df2c67b940bc0624e41498e23..3bae47f9cfa64c471d24f964c75a30fd968778d0 100644
--- a/Framework/Algorithms/src/GetEi2.cpp
+++ b/Framework/Algorithms/src/GetEi2.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
+#include "MantidGeometry/IDetector_fwd.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidGeometry/muParser_Silent.h"
@@ -216,9 +217,10 @@ double GetEi2::calculateEi(const double initial_guess) {
   // Calculate actual peak postion for each monitor peak
   double peak_times[2] = {0.0, 0.0};
   double det_distances[2] = {0.0, 0.0};
+  auto &spectrumInfo = m_input_ws->spectrumInfo();
   for (unsigned int i = 0; i < 2; ++i) {
     size_t ws_index = mon_indices[i];
-    det_distances[i] = getDistanceFromSource(ws_index);
+    det_distances[i] = getDistanceFromSource(ws_index, spectrumInfo);
     const double peak_guess =
         det_distances[i] * std::sqrt(m_t_to_mev / initial_guess);
     const double t_min = (1.0 - m_tof_window) * peak_guess;
@@ -276,31 +278,33 @@ double GetEi2::calculateEi(const double initial_guess) {
   }
 }
 
-/** Gets the distance between the source and detectors whose workspace index is
+/**
+ * Gets the distance between the source and detectors whose workspace index is
  * passed
  *  @param ws_index :: The workspace index of the detector
+ *  @param spectrumInfo :: A spectrum info object for the input workspace
  *  @return The distance between the source and the given detector(or
  * DetectorGroup)
  *  @throw runtime_error if there is a problem
  */
-double GetEi2::getDistanceFromSource(size_t ws_index) const {
+double GetEi2::getDistanceFromSource(size_t ws_index,
+                                     const SpectrumInfo &spectrumInfo) const {
   g_log.debug() << "Computing distance between spectrum at index '" << ws_index
                 << "' and the source\n";
 
+  const auto &detector = spectrumInfo.detector(ws_index);
   const IComponent_const_sptr source = m_input_ws->getInstrument()->getSource();
-  // Retrieve a pointer detector
-  IDetector_const_sptr det = m_input_ws->getDetector(ws_index);
-  if (!det) {
+  if (!spectrumInfo.hasDetectors(ws_index)) {
     std::ostringstream msg;
     msg << "A detector for monitor at workspace index " << ws_index
         << " cannot be found. ";
     throw std::runtime_error(msg.str());
   }
   if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
-    g_log.debug() << "Detector position = " << det->getPos()
+    g_log.debug() << "Detector position = " << spectrumInfo.position(ws_index)
                   << ", Source position = " << source->getPos() << "\n";
   }
-  const double dist = det->getDistance(*source);
+  const double dist = detector.getDistance(*source);
   g_log.debug() << "Distance = " << dist << " metres\n";
   return dist;
 }
diff --git a/Framework/Algorithms/src/GetEiMonDet2.cpp b/Framework/Algorithms/src/GetEiMonDet2.cpp
index b047270bc69d9ee46b93ab5682a46ceb47ef8f04..25cbcefb2e337197f64f5bd5ef4c13362fc43b80 100644
--- a/Framework/Algorithms/src/GetEiMonDet2.cpp
+++ b/Framework/Algorithms/src/GetEiMonDet2.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ArrayProperty.h"
@@ -198,6 +199,7 @@ void GetEiMonDet2::averageDetectorDistanceAndTOF(
   double distanceSum = 0;
   double eppSum = 0;
   size_t n = 0;
+  auto &spectrumInfo = m_detectorWs->spectrumInfo();
   // cppcheck-suppress syntaxError
   PRAGMA_OMP(parallel for if ( m_detectorEPPTable->threadSafe())
              reduction(+: n, distanceSum, eppSum))
@@ -210,17 +212,16 @@ void GetEiMonDet2::averageDetectorDistanceAndTOF(
     }
     if (fitStatusColumn->cell<std::string>(index) ==
         EPPTableLiterals::FIT_STATUS_SUCCESS) {
-      const auto detector = m_detectorWs->getDetector(index);
-      if (!detector) {
+      if (!spectrumInfo.hasDetectors(index)) {
         throw std::runtime_error("No detector specified by " +
                                  PropertyNames::DETECTORS + " found");
       }
-      if (detector->isMonitor()) {
+      if (spectrumInfo.isMonitor(index)) {
         g_log.warning() << "Workspace index " << index
                         << " should be detector, but is marked as monitor.\n";
       }
-      if (!detector->isMasked()) {
-        const double d = detector->getDistance(*sample);
+      if (!spectrumInfo.isMasked(index)) {
+        const double d = spectrumInfo.detector(index).getDistance(*sample);
         distanceSum += d;
         const double epp = (*peakPositionColumn)[index];
         eppSum += epp;
@@ -337,16 +338,17 @@ void GetEiMonDet2::monitorDistanceAndTOF(const size_t monitorIndex,
     throw std::runtime_error("No successful monitor fit found in " +
                              PropertyNames::MONITOR_EPP_TABLE);
   }
-  const auto monitor = m_monitorWs->getDetector(monitorIndex);
-  if (monitor->isMasked()) {
+  auto &spectrumInfo = m_monitorWs->spectrumInfo();
+  if (spectrumInfo.isMasked(monitorIndex)) {
     throw std::runtime_error("Monitor spectrum is masked");
   }
-  if (!monitor->isMonitor()) {
+  if (!spectrumInfo.isMonitor(monitorIndex)) {
     g_log.warning() << "The monitor spectrum is not actually marked "
                     << "as monitor.\n";
   }
   const auto sample = m_detectorWs->getInstrument()->getSample();
-  monitorToSampleDistance = monitor->getDistance(*sample);
+  monitorToSampleDistance =
+      spectrumInfo.position(monitorIndex).distance(sample->getPos());
   g_log.information() << "Monitor-to-sample distance: "
                       << monitorToSampleDistance << ".\n";
 
diff --git a/Framework/Algorithms/src/GetTimeSeriesLogInformation.cpp b/Framework/Algorithms/src/GetTimeSeriesLogInformation.cpp
index 504118a4a6b388ddc7dda0c025ca0e3e979d4cb8..e435683928198c3309f33f187686672ed2d50e1f 100644
--- a/Framework/Algorithms/src/GetTimeSeriesLogInformation.cpp
+++ b/Framework/Algorithms/src/GetTimeSeriesLogInformation.cpp
@@ -84,7 +84,7 @@ void GetTimeSeriesLogInformation::exec() {
   }
 
   string logname = getProperty("LogName");
-  if (logname.size() == 0)
+  if (logname.empty())
     throw runtime_error("Input log value cannot be an empty string. ");
 
   Kernel::Property *log = m_dataWS->run().getProperty(logname);
diff --git a/Framework/Algorithms/src/GroupWorkspaces.cpp b/Framework/Algorithms/src/GroupWorkspaces.cpp
index a685d64a15d79c9981b1d063afe5ac1814651efa..0c6e692ebe01705c324257c8c66049da88f26d33 100644
--- a/Framework/Algorithms/src/GroupWorkspaces.cpp
+++ b/Framework/Algorithms/src/GroupWorkspaces.cpp
@@ -1,8 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/GroupWorkspaces.h"
 #include "MantidAPI/ADSValidator.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ArrayProperty.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/He3TubeEfficiency.cpp b/Framework/Algorithms/src/He3TubeEfficiency.cpp
index 96dad74d98a5a1ab9e6c9f02c17248b27e66cbd3..7f7be044328501c2e4cfe4c1ced8ef907ff8c4b3 100644
--- a/Framework/Algorithms/src/He3TubeEfficiency.cpp
+++ b/Framework/Algorithms/src/He3TubeEfficiency.cpp
@@ -2,12 +2,15 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
+#include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/ArrayBoundedValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/CompositeValidator.h"
@@ -116,6 +119,7 @@ void He3TubeEfficiency::exec() {
 
   std::size_t numHists = this->inputWS->getNumberHistograms();
   this->progress = new API::Progress(this, 0.0, 1.0, numHists);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
   for (int i = 0; i < static_cast<int>(numHists); ++i) {
@@ -123,7 +127,7 @@ void He3TubeEfficiency::exec() {
 
     this->outputWS->setX(i, this->inputWS->refX(i));
     try {
-      this->correctForEfficiency(i);
+      this->correctForEfficiency(i, spectrumInfo);
     } catch (std::out_of_range &) {
       // if we don't have all the data there will be spectra we can't correct,
       // avoid leaving the workspace part corrected
@@ -155,17 +159,20 @@ void He3TubeEfficiency::exec() {
  * information. Gets the detector information and uses this to calculate its
  * efficiency
  *  @param spectraIndex :: index of the spectrum to get the efficiency for
+ *  @param spectrumInfo :: the SpectrumInfo object for the input workspace
  *  @throw invalid_argument if the shape of a detector is isn't a cylinder
  *  aligned along one axis
  *  @throw NotFoundError if the detector or its gas pressure or wall thickness
  *  were not found
  */
-void He3TubeEfficiency::correctForEfficiency(std::size_t spectraIndex) {
-  Geometry::IDetector_const_sptr det = this->inputWS->getDetector(spectraIndex);
-  if (det->isMonitor() || det->isMasked()) {
+void He3TubeEfficiency::correctForEfficiency(
+    std::size_t spectraIndex, const API::SpectrumInfo &spectrumInfo) {
+  if (spectrumInfo.isMonitor(spectraIndex) ||
+      spectrumInfo.isMasked(spectraIndex)) {
     return;
   }
 
+  const auto &det = spectrumInfo.detector(spectraIndex);
   const double exp_constant = this->calculateExponential(spectraIndex, det);
   const double scale = this->getProperty("ScaleFactor");
 
@@ -201,9 +208,9 @@ void He3TubeEfficiency::correctForEfficiency(std::size_t spectraIndex) {
  * @throw out_of_range if twice tube thickness is greater than tube diameter
  * @return the exponential contribution for the given detector
  */
-double He3TubeEfficiency::calculateExponential(
-    std::size_t spectraIndex,
-    boost::shared_ptr<const Geometry::IDetector> idet) {
+double
+He3TubeEfficiency::calculateExponential(std::size_t spectraIndex,
+                                        const Geometry::IDetector &idet) {
   // Get the parameters for the current associated tube
   double pressure =
       this->getParameter("TubePressure", spectraIndex, "tube_pressure", idet);
@@ -221,9 +228,9 @@ double He3TubeEfficiency::calculateExponential(
   // now get the sin of the angle, it's the magnitude of the cross product of
   // unit vector along the detector tube axis and a unit vector directed from
   // the sample to the detector center
-  Kernel::V3D vectorFromSample = idet->getPos() - this->samplePos;
+  Kernel::V3D vectorFromSample = idet.getPos() - this->samplePos;
   vectorFromSample.normalize();
-  Kernel::Quat rot = idet->getRotation();
+  Kernel::Quat rot = idet.getRotation();
   // rotate the original cylinder object axis to get the detector axis in the
   // actual instrument
   rot.rotate(detAxis);
@@ -248,14 +255,14 @@ double He3TubeEfficiency::calculateExponential(
  * @param detRadius :: An output parameter that contains the detector radius
  * @param detAxis :: An output parameter that contains the detector axis vector
  */
-void He3TubeEfficiency::getDetectorGeometry(
-    const boost::shared_ptr<const Geometry::IDetector> &det, double &detRadius,
-    Kernel::V3D &detAxis) {
-  boost::shared_ptr<const Geometry::Object> shape_sptr = det->shape();
+void He3TubeEfficiency::getDetectorGeometry(const Geometry::IDetector &det,
+                                            double &detRadius,
+                                            Kernel::V3D &detAxis) {
+  boost::shared_ptr<const Geometry::Object> shape_sptr = det.shape();
   if (!shape_sptr) {
     throw std::runtime_error(
         "Detector geometry error: detector with id: " +
-        std::to_string(det->getID()) +
+        std::to_string(det.getID()) +
         " does not have shape. Is this a detectors group?\n"
         "The algorithm works for instruments with one-to-one "
         "spectra-to-detector maps only!");
@@ -386,13 +393,14 @@ void He3TubeEfficiency::logErrors() const {
  * @param idet :: the current detector
  * @return the value of the detector property
  */
-double He3TubeEfficiency::getParameter(
-    std::string wsPropName, std::size_t currentIndex, std::string detPropName,
-    boost::shared_ptr<const Geometry::IDetector> idet) {
+double He3TubeEfficiency::getParameter(std::string wsPropName,
+                                       std::size_t currentIndex,
+                                       std::string detPropName,
+                                       const Geometry::IDetector &idet) {
   std::vector<double> wsProp = this->getProperty(wsPropName);
 
   if (wsProp.empty()) {
-    return idet->getNumberParameter(detPropName).at(0);
+    return idet.getNumberParameter(detPropName).at(0);
   } else {
     if (wsProp.size() == 1) {
       return wsProp.at(0);
@@ -421,13 +429,15 @@ void He3TubeEfficiency::execEvent() {
       boost::dynamic_pointer_cast<DataObjects::EventWorkspace>(matrixOutputWS);
 
   std::size_t numHistograms = outputWS->getNumberHistograms();
+  auto &spectrumInfo = outputWS->mutableSpectrumInfo();
   this->progress = new API::Progress(this, 0.0, 1.0, numHistograms);
+
   PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS))
   for (int i = 0; i < static_cast<int>(numHistograms); ++i) {
     PARALLEL_START_INTERUPT_REGION
 
-    Geometry::IDetector_const_sptr det = outputWS->getDetector(i);
-    if (det->isMonitor() || det->isMasked()) {
+    const auto &det = spectrumInfo.detector(i);
+    if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i)) {
       continue;
     }
 
@@ -438,7 +448,8 @@ void He3TubeEfficiency::execEvent() {
       // Parameters are bad so skip correction
       PARALLEL_CRITICAL(deteff_invalid) {
         this->spectraSkipped.push_back(outputWS->getAxis(1)->spectraNo(i));
-        outputWS->maskWorkspaceIndex(i);
+        outputWS->getSpectrum(i).clearData();
+        spectrumInfo.setMasked(i, true);
       }
     }
 
diff --git a/Framework/Algorithms/src/InterpolatingRebin.cpp b/Framework/Algorithms/src/InterpolatingRebin.cpp
index 43f9fffc6b970c80b64ac2aa5b60eb1e2811b5e0..3005fe25b506e33ee850ad6d7febe8a24ecac145 100644
--- a/Framework/Algorithms/src/InterpolatingRebin.cpp
+++ b/Framework/Algorithms/src/InterpolatingRebin.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/InterpolatingRebin.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -13,6 +10,8 @@
 #include <gsl/gsl_interp.h>
 #include <gsl/gsl_spline.h>
 
+#include <boost/lexical_cast.hpp>
+
 namespace Mantid {
 namespace Algorithms {
 
diff --git a/Framework/Algorithms/src/MaskDetectorsIf.cpp b/Framework/Algorithms/src/MaskDetectorsIf.cpp
index 2c390d55feb06819fce6d1afba2364521c06b280..8a0905510eae4f090765e908ba372413e43dd43e 100644
--- a/Framework/Algorithms/src/MaskDetectorsIf.cpp
+++ b/Framework/Algorithms/src/MaskDetectorsIf.cpp
@@ -1,12 +1,10 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/MaskDetectorsIf.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/ListValidator.h"
 
 #include <fstream>
+#include <iomanip>
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/MedianDetectorTest.cpp b/Framework/Algorithms/src/MedianDetectorTest.cpp
index 8844f32e172146c517f6e2be5ffcba795eda476d..55dc0c82a9aca0f0dd86653ac5c4292ba7840d59 100644
--- a/Framework/Algorithms/src/MedianDetectorTest.cpp
+++ b/Framework/Algorithms/src/MedianDetectorTest.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/MedianDetectorTest.h"
 #include "MantidAPI/HistogramValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/BoundedValidator.h"
 
 #include <cmath>
@@ -246,6 +247,7 @@ int MedianDetectorTest::maskOutliers(
     checkForMask = ((instrument->getSource() != nullptr) &&
                     (instrument->getSample() != nullptr));
   }
+  auto &spectrumInfo = countsWS->mutableSpectrumInfo();
 
   for (size_t i = 0; i < indexmap.size(); ++i) {
     std::vector<size_t> &hists = indexmap[i];
@@ -255,19 +257,23 @@ int MedianDetectorTest::maskOutliers(
     for (int j = 0; j < static_cast<int>(hists.size()); ++j) { // NOLINT
       const double value = countsWS->y(hists[j])[0];
       if ((value == 0.) && checkForMask) {
-        const auto &detids = countsWS->getSpectrum(hists[j]).getDetectorIDs();
-        if (instrument->isDetectorMasked(detids)) {
+        if (spectrumInfo.hasDetectors(hists[j]) &&
+            spectrumInfo.isMasked(hists[j])) {
           numFailed -= 1; // it was already masked
         }
       }
       if ((value < out_lo * median) && (value > 0.0)) {
-        countsWS->maskWorkspaceIndex(hists[j]);
-        PARALLEL_ATOMIC
-        ++numFailed;
+        countsWS->getSpectrum(hists[j]).clearData();
+        PARALLEL_CRITICAL(setMasked) {
+          spectrumInfo.setMasked(hists[j], true);
+          ++numFailed;
+        }
       } else if (value > out_hi * median) {
-        countsWS->maskWorkspaceIndex(hists[j]);
-        PARALLEL_ATOMIC
-        ++numFailed;
+        countsWS->getSpectrum(hists[j]).clearData();
+        PARALLEL_CRITICAL(setMasked) {
+          spectrumInfo.setMasked(hists[j], true);
+          ++numFailed;
+        }
       }
     }
     PARALLEL_CHECK_INTERUPT_REGION
@@ -313,6 +319,7 @@ int MedianDetectorTest::doDetectorTests(
     checkForMask = ((instrument->getSource() != nullptr) &&
                     (instrument->getSample() != nullptr));
   }
+  const auto &spectrumInfo = countsWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*countsWS, *maskWS))
   for (int j = 0; j < static_cast<int>(indexmap.size()); ++j) {
@@ -331,14 +338,12 @@ int MedianDetectorTest::doDetectorTests(
                                  numSpec));
       }
 
-      if (checkForMask) {
-        const auto &detids =
-            countsWS->getSpectrum(hists.at(i)).getDetectorIDs();
-        if (instrument->isDetectorMasked(detids)) {
+      if (checkForMask && spectrumInfo.hasDetectors(hists.at(i))) {
+        if (spectrumInfo.isMasked(hists.at(i))) {
           maskWS->mutableY(hists.at(i))[0] = deadValue;
           continue;
         }
-        if (instrument->isMonitor(detids)) {
+        if (spectrumInfo.isMonitor(hists.at(i))) {
           // Don't include in calculation but don't mask it
           continue;
         }
diff --git a/Framework/Algorithms/src/MergeRuns.cpp b/Framework/Algorithms/src/MergeRuns.cpp
index 786187ed989cc0e3772db284e29391c960a14df3..3beab65d7afd6ec7895b67eef6358482613085ff 100644
--- a/Framework/Algorithms/src/MergeRuns.cpp
+++ b/Framework/Algorithms/src/MergeRuns.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidAPI/ADSValidator.h"
 #include "MantidAlgorithms/MergeRuns/SampleLogsBehaviour.h"
diff --git a/Framework/Algorithms/src/MergeRuns/SampleLogsBehaviour.cpp b/Framework/Algorithms/src/MergeRuns/SampleLogsBehaviour.cpp
index 86c351bad639c95b665a08d563f24629a66ad635..586a856801b0363baaca5fbeb0940763596898bd 100644
--- a/Framework/Algorithms/src/MergeRuns/SampleLogsBehaviour.cpp
+++ b/Framework/Algorithms/src/MergeRuns/SampleLogsBehaviour.cpp
@@ -1,6 +1,8 @@
 #include "MantidAlgorithms/MergeRuns/SampleLogsBehaviour.h"
 #include "MantidAPI/Run.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/Strings.h"
+#include "MantidKernel/StringTokenizer.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/ModeratorTzeroLinear.cpp b/Framework/Algorithms/src/ModeratorTzeroLinear.cpp
index d13fb6f89e68e43efca0fd6ae96c3f2ccdf0cf21..cbcf742bbd77ebc7ab2d4726c5ed1f6faf343041 100644
--- a/Framework/Algorithms/src/ModeratorTzeroLinear.cpp
+++ b/Framework/Algorithms/src/ModeratorTzeroLinear.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/UnitFactory.h"
 
 #include <boost/lexical_cast.hpp>
diff --git a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
index bb91bd7c334fb828df65f1eb2db31b6694ec0ffc..69061e7f696d6b01d083ac219968cc5db68482e3 100644
--- a/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
+++ b/Framework/Algorithms/src/MonitorEfficiencyCorUser.cpp
@@ -7,6 +7,7 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/muParser_Silent.h"
 #include "MantidKernel/MultiThreaded.h"
+#include "MantidKernel/Strings.h"
 
 using Mantid::HistogramData::HistogramX;
 using Mantid::HistogramData::HistogramY;
diff --git a/Framework/Algorithms/src/NormaliseByCurrent.cpp b/Framework/Algorithms/src/NormaliseByCurrent.cpp
index 0265cc8de657d3a3cc5268b773717aa5e19ac9ec..628a78f0d648507faf4f82e8da4cb1815d3f673e 100644
--- a/Framework/Algorithms/src/NormaliseByCurrent.cpp
+++ b/Framework/Algorithms/src/NormaliseByCurrent.cpp
@@ -4,6 +4,8 @@
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/LogFilter.h"
 
+#include <boost/lexical_cast.hpp>
+
 namespace Mantid {
 namespace Algorithms {
 
@@ -42,7 +44,7 @@ double NormaliseByCurrent::extractCharge(
   int nPeriods = 0;
   try {
     Property *nPeriodsProperty = run.getLogData("nperiods");
-    Kernel::toValue<int>(nPeriodsProperty->value(), nPeriods);
+    nPeriods = boost::lexical_cast<int>(nPeriodsProperty->value());
   } catch (Exception::NotFoundError &) {
     g_log.information() << "No nperiods property. If this is multi-period "
                            "data, then you will be normalising against the "
@@ -50,7 +52,6 @@ double NormaliseByCurrent::extractCharge(
   }
   // Handle multiperiod data.
   // The number of periods is set above by reference
-  // cppcheck-suppress knownConditionTrueFalse
   if (nPeriods > 1) {
     // Fetch the period property
     Property *currentPeriodNumberProperty = run.getLogData("current_period");
diff --git a/Framework/Algorithms/src/PDCalibration.cpp b/Framework/Algorithms/src/PDCalibration.cpp
index add9a37abc27229595f6933dcc463847bdd50b6a..22c16709e077d05d02039bc6c638d025c3af4a48 100644
--- a/Framework/Algorithms/src/PDCalibration.cpp
+++ b/Framework/Algorithms/src/PDCalibration.cpp
@@ -397,7 +397,7 @@ void PDCalibration::exec() {
       tof_vec.push_back(centre);
     }
 
-    if (d_vec.size() == 0) {
+    if (d_vec.empty()) {
       maskWS->setMaskedIndex(wkspIndex, true);
       continue;
     } else {
diff --git a/Framework/Algorithms/src/Pause.cpp b/Framework/Algorithms/src/Pause.cpp
index 0ce83c15cc6c594ef49c56cc2f442e9e81b5ff67..9eed799b21f036851e216ea5e2f04666f0cb9ec4 100644
--- a/Framework/Algorithms/src/Pause.cpp
+++ b/Framework/Algorithms/src/Pause.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/Pause.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidKernel/DateAndTime.h"
 
 #include <Poco/Thread.h>
 
@@ -12,7 +13,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(Pause)
 
-//----------------------------------------------------------------------------------------------
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string Pause::name() const { return "Pause"; }
 
@@ -22,9 +22,6 @@ int Pause::version() const { return 1; }
 /// Algorithm's category for identification. @see Algorithm::category
 const std::string Pause::category() const { return "Utility\\Development"; }
 
-//----------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void Pause::init() {
@@ -33,7 +30,6 @@ void Pause::init() {
                   "Enter a negative number to pause forever until cancelled.");
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void Pause::exec() {
diff --git a/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp b/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp
index ae77d31cf88053bb4d0c2a9ef4849f7e0948c7f0..e7a106c02f1fefa737fd50f98ddf405247b0b377 100644
--- a/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp
+++ b/Framework/Algorithms/src/PlotAsymmetryByLogValue.cpp
@@ -18,6 +18,7 @@
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "Poco/File.h"
 #include <MantidAPI/FileFinder.h>
+#include "MantidAPI/WorkspaceGroup.h"
 
 namespace // anonymous
     {
diff --git a/Framework/Algorithms/src/PolarizationCorrection.cpp b/Framework/Algorithms/src/PolarizationCorrection.cpp
index c7a88b8320e57aea23a6ea3f4bb28d032f9ad478..d3f4983a28dda537a8e7659fc3320d01f9db9164 100644
--- a/Framework/Algorithms/src/PolarizationCorrection.cpp
+++ b/Framework/Algorithms/src/PolarizationCorrection.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataObjects/WorkspaceSingleValue.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ListValidator.h"
diff --git a/Framework/Algorithms/src/Q1DWeighted.cpp b/Framework/Algorithms/src/Q1DWeighted.cpp
index aeb3ac3fdc18b2477d696af6ef6d1dc15877bf79..36fc5177d2c2f4530407f4927210575af9e9b409 100644
--- a/Framework/Algorithms/src/Q1DWeighted.cpp
+++ b/Framework/Algorithms/src/Q1DWeighted.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/Histogram1D.h"
 #include "MantidGeometry/Instrument.h"
@@ -16,6 +17,8 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/VectorHelper.h"
 
+constexpr double deg2rad = M_PI / 180.0;
+
 namespace Mantid {
 namespace Algorithms {
 
@@ -332,7 +335,7 @@ void Q1DWeighted::exec() {
   }
   // set the output property
   std::string outputWSGroupName = getPropertyValue("WedgeWorkspace");
-  if (outputWSGroupName.size() == 0) {
+  if (outputWSGroupName.empty()) {
     std::string outputWSName = getPropertyValue("OutputWorkspace");
     outputWSGroupName = outputWSName + "_wedges";
     setPropertyValue("WedgeWorkspace", outputWSGroupName);
diff --git a/Framework/Algorithms/src/Qxy.cpp b/Framework/Algorithms/src/Qxy.cpp
index 42d8cc3181becfd31991e61c044d7c0fbd8caa71..5a711f89b1e70fa66024d32bd1de66fa1cd932b3 100644
--- a/Framework/Algorithms/src/Qxy.cpp
+++ b/Framework/Algorithms/src/Qxy.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/Qxy.h"
 #include "MantidAPI/BinEdgeAxis.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/SpectrumInfo.h"
@@ -362,10 +363,8 @@ Qxy::setUpOutputWorkspace(API::MatrixWorkspace_const_sptr inputWorkspace) {
   MatrixWorkspace_sptr outputWorkspace = WorkspaceFactory::Instance().create(
       inputWorkspace, bins - 1, bins, bins - 1);
   // ... but clear the masking from the parameter map as we don't want to carry
-  // that over since this is essentially
-  // a 2D rebin
-  ParameterMap &pmap = outputWorkspace->instrumentParameters();
-  pmap.clearParametersByName("masked");
+  // that over since this is essentially a 2D rebin
+  outputWorkspace->mutableDetectorInfo().clearMaskFlags();
 
   // Create a numeric axis to replace the vertical one
   Axis *verticalAxis = new BinEdgeAxis(bins);
diff --git a/Framework/Algorithms/src/RadiusSum.cpp b/Framework/Algorithms/src/RadiusSum.cpp
index 8bdd59379ecce72d43b1e929cbbcd61d968c046f..ea8bbd24fdec5fc61cb3438738bff3e2c9770241 100644
--- a/Framework/Algorithms/src/RadiusSum.cpp
+++ b/Framework/Algorithms/src/RadiusSum.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/IObjComponent.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/ArrayLengthValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -16,6 +17,7 @@
 
 #include <boost/foreach.hpp>
 
+#include <array>
 #include <cmath>
 #include <limits>
 #include <numeric>
diff --git a/Framework/Algorithms/src/ReadGroupsFromFile.cpp b/Framework/Algorithms/src/ReadGroupsFromFile.cpp
index 07880d99ef21d9275996322dbd90c1313005a054..d28782fcd1c1b8ff90921c59f22562fc0f9fbffc 100644
--- a/Framework/Algorithms/src/ReadGroupsFromFile.cpp
+++ b/Framework/Algorithms/src/ReadGroupsFromFile.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/ReadGroupsFromFile.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/InstrumentDataService.h"
@@ -10,6 +7,7 @@
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/StringTokenizer.h"
 
 // Poco XML Headers for Grouping File
 #include <Poco/DOM/DOMParser.h>
diff --git a/Framework/Algorithms/src/ReflectometryReductionOne.cpp b/Framework/Algorithms/src/ReflectometryReductionOne.cpp
index b63524e8dedc9d12b073e0cdff37594c64e5b54a..cebbed8514eea1057bb4ec8973707e0b5787862d 100644
--- a/Framework/Algorithms/src/ReflectometryReductionOne.cpp
+++ b/Framework/Algorithms/src/ReflectometryReductionOne.cpp
@@ -8,6 +8,7 @@
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/EnabledWhenProperty.h"
+#include "MantidKernel/Tolerance.h"
 #include "MantidKernel/Unit.h"
 #include <boost/make_shared.hpp>
 
diff --git a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp
index 060c169b191450288e25ac7e19f5816d8933b957..812bfcfceda57568ff87887a4299bf5bfb2d4322 100644
--- a/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp
+++ b/Framework/Algorithms/src/ReflectometryReductionOneAuto.cpp
@@ -1,5 +1,6 @@
 #include "MantidAlgorithms/BoostOptionalToAlgorithmProperty.h"
 #include "MantidAlgorithms/ReflectometryReductionOneAuto.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
diff --git a/Framework/Algorithms/src/RemoveBackground.cpp b/Framework/Algorithms/src/RemoveBackground.cpp
index ffc385ad655973ebfbd0d832acd1b1a07b1fbb0b..3a47639fac0ccc4b68b4a055d7cc6f56fd891a6b 100644
--- a/Framework/Algorithms/src/RemoveBackground.cpp
+++ b/Framework/Algorithms/src/RemoveBackground.cpp
@@ -13,6 +13,7 @@
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/RebinParamsValidator.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/VectorHelper.h"
 #include "MantidKernel/VisibleWhenProperty.h"
 #include "MantidKernel/make_unique.h"
diff --git a/Framework/Algorithms/src/RemoveLowResTOF.cpp b/Framework/Algorithms/src/RemoveLowResTOF.cpp
index 711fea813694721da46c6037d22a2ba004d3ee72..38766a9291431b3b2da65a61afde21efdaacff03 100644
--- a/Framework/Algorithms/src/RemoveLowResTOF.cpp
+++ b/Framework/Algorithms/src/RemoveLowResTOF.cpp
@@ -9,6 +9,7 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include <cmath>
 #include <limits>
@@ -115,7 +116,7 @@ void RemoveLowResTOF::exec() {
   m_numberOfSpectra = m_inputWS->getNumberHistograms();
 
   std::string lowreswsname = getPropertyValue("LowResTOFWorkspace");
-  if (lowreswsname.size() > 0)
+  if (!lowreswsname.empty())
     m_outputLowResTOF = true;
   else
     m_outputLowResTOF = false;
diff --git a/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp b/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp
index 269cd5a3f2893b130deebfe4b2adb8d8c7b00579..acd3339fbe716b586cd144e42c962a86b8d43f34 100644
--- a/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp
+++ b/Framework/Algorithms/src/RemoveWorkspaceHistory.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/Workspace.h"
 #include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAlgorithms/RemoveWorkspaceHistory.h"
 
@@ -10,7 +11,6 @@ namespace Algorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(RemoveWorkspaceHistory)
 
-//----------------------------------------------------------------------------------------------
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string RemoveWorkspaceHistory::name() const {
   return "RemoveWorkspaceHistory";
@@ -29,7 +29,6 @@ const std::string RemoveWorkspaceHistory::summary() const {
   return "Removes all algorithm history records from a given workspace.";
 }
 
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void RemoveWorkspaceHistory::init() {
@@ -38,7 +37,6 @@ void RemoveWorkspaceHistory::init() {
                   "Workspace to remove the algorithm history from.");
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void RemoveWorkspaceHistory::exec() {
@@ -47,4 +45,4 @@ void RemoveWorkspaceHistory::exec() {
 }
 
 } // namespace Algorithms
-} // namespace Mantid
\ No newline at end of file
+} // namespace Mantid
diff --git a/Framework/Algorithms/src/RenameWorkspace.cpp b/Framework/Algorithms/src/RenameWorkspace.cpp
index e20e72a4815c9ea53372e3b646d38b270d57b4b8..5659b7e1e4f2cdba9228966ea89f0a51c131f877 100644
--- a/Framework/Algorithms/src/RenameWorkspace.cpp
+++ b/Framework/Algorithms/src/RenameWorkspace.cpp
@@ -1,11 +1,9 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAlgorithms/RenameWorkspace.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Exception.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -114,7 +112,7 @@ void RenameWorkspace::exec() {
   if (monWS) {
     std::string monWSName = monWS->getName();
     // rename the monitor workspace accordingly
-    if (monWSName.size() == 0) {
+    if (monWSName.empty()) {
       // workspace will always have name after added to ADS, so apparently not
       // the case
       AnalysisDataService::Instance().add(outputwsName + "_monitors", monWS);
diff --git a/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp b/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
index 2bac0f324cfc9055ac3db231f76bd1df9e44ff17..f4a73febff75595e268cc3eaf37e0d3bd7368279 100644
--- a/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/MCAbsorptionStrategy.cpp
@@ -25,7 +25,9 @@ namespace Algorithms {
 MCAbsorptionStrategy::MCAbsorptionStrategy(const IBeamProfile &beamProfile,
                                            const API::Sample &sample,
                                            size_t nevents)
-    : m_beamProfile(beamProfile), m_scatterVol(MCInteractionVolume(sample)),
+    : m_beamProfile(beamProfile),
+      m_scatterVol(
+          MCInteractionVolume(sample, beamProfile.defineActiveRegion(sample))),
       m_nevents(nevents), m_error(1.0 / std::sqrt(m_nevents)) {}
 
 /**
@@ -42,19 +44,15 @@ std::tuple<double, double>
 MCAbsorptionStrategy::calculate(Kernel::PseudoRandomNumberGenerator &rng,
                                 const Kernel::V3D &finalPos,
                                 double lambdaBefore, double lambdaAfter) const {
-  // The simulation consists of sampling the beam profile and then computing the
-  // absorption within the interacting volume defined by the sample (and
-  // environment. The final correction factor is computed as the simple average
-  // of m_nevents of this process.
   const auto scatterBounds = m_scatterVol.getBoundingBox();
   double factor(0.0);
   for (size_t i = 0; i < m_nevents; ++i) {
     size_t attempts(0);
     do {
       const auto neutron = m_beamProfile.generatePoint(rng, scatterBounds);
+
       const double wgt = m_scatterVol.calculateAbsorption(
-          rng, neutron.startPos, neutron.unitDir, finalPos, lambdaBefore,
-          lambdaAfter);
+          rng, neutron.startPos, finalPos, lambdaBefore, lambdaAfter);
       if (wgt < 0.0) {
         ++attempts;
       } else {
diff --git a/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp b/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
index 8045cc5c99ce939964480012eef83ad9b5547e1b..3d96995f6d11a9bc4dc6658ba936372f9207f064 100644
--- a/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/MCInteractionVolume.cpp
@@ -13,6 +13,10 @@ using Kernel::V3D;
 namespace Algorithms {
 
 namespace {
+
+// Maximum number of attempts to generate a scatter point
+constexpr size_t MAX_SCATTER_ATTEMPTS = 500;
+
 /**
  * Compute the attenuation factor for the given coefficients
  * @param rho Number density of the sample in \f$\\A^{-3}\f$
@@ -27,12 +31,17 @@ double attenuation(double rho, double sigma, double length) {
 }
 
 /**
- * Construct the volume with only a sample object
+ * Construct the volume encompassing the sample + any environment kit. The
+ * beam profile defines a bounding region for the sampling of the scattering
+ * position.
  * @param sample A reference to a sample object that defines a valid shape
  * & material
+ * @param activeRegion Restrict scattering point sampling to this region
  */
-MCInteractionVolume::MCInteractionVolume(const API::Sample &sample)
-    : m_sample(sample.getShape()), m_env(nullptr) {
+MCInteractionVolume::MCInteractionVolume(
+    const API::Sample &sample, const Geometry::BoundingBox &activeRegion)
+    : m_sample(sample.getShape()), m_env(nullptr),
+      m_activeRegion(activeRegion) {
   if (!m_sample.hasValidShape()) {
     throw std::invalid_argument(
         "MCInteractionVolume() - Sample shape does not have a valid shape.");
@@ -57,11 +66,11 @@ const Geometry::BoundingBox &MCInteractionVolume::getBoundingBox() const {
 }
 
 /**
- * Calculate the attenuation correction factor for given track through the
- * volume
- * @param rng A reference to a PseudoRandomNumberGenerator
+ * Calculate the attenuation correction factor the volume given a start and
+ * end point.
+ * @param rng A reference to a PseudoRandomNumberGenerator producing
+ * random number between [0,1]
  * @param startPos Origin of the initial track
- * @param direc Direction of travel of the neutron
  * @param endPos Final position of neutron after scattering (assumed to be
  * outside of the "volume")
  * @param lambdaBefore Wavelength, in \f$\\A^-1\f$, before scattering
@@ -71,68 +80,59 @@ const Geometry::BoundingBox &MCInteractionVolume::getBoundingBox() const {
  */
 double MCInteractionVolume::calculateAbsorption(
     Kernel::PseudoRandomNumberGenerator &rng, const Kernel::V3D &startPos,
-    const Kernel::V3D &direc, const Kernel::V3D &endPos, double lambdaBefore,
-    double lambdaAfter) const {
-  // Create track with start position and direction and "fire" it through
-  // the sample to produce a number of intersections. Choose a random
-  // intersection and within this section pick a random "depth". This point
-  // is the scatter point.
-  // Form a second track originating at the scatter point and ending at endPos
-  // to give a second set of intersections.
-  // The total attenuation factor is the product of the attenuation factor
-  // for each intersection
-
-  // Generate scatter point
-  Track path1(startPos, direc);
-  int nsegments = m_sample.interceptSurface(path1);
+    const Kernel::V3D &endPos, double lambdaBefore, double lambdaAfter) const {
+  // Generate scatter point. If there is an environment present then
+  // first select whether the scattering occurs on the sample or the
+  // environment. The attenuation for the path leading to the scatter point
+  // is calculated in reverse, i.e. defining the track from the scatter pt
+  // backwards for simplicity with how the Track object works. This avoids
+  // having to understand exactly which object the scattering occurred in.
+  V3D scatterPos;
+  if (m_env && (rng.nextValue() > 0.5)) {
+    scatterPos =
+        m_env->generatePoint(rng, m_activeRegion, MAX_SCATTER_ATTEMPTS);
+  } else {
+    scatterPos = m_sample.generatePointInObject(rng, m_activeRegion,
+                                                MAX_SCATTER_ATTEMPTS);
+  }
+  auto toStart = startPos - scatterPos;
+  toStart.normalize();
+  Track beforeScatter(scatterPos, toStart);
+  int nlinks = m_sample.interceptSurface(beforeScatter);
   if (m_env) {
-    nsegments += m_env->interceptSurfaces(path1);
+    nlinks += m_env->interceptSurfaces(beforeScatter);
   }
-  if (nsegments == 0) {
+  // This should not happen but numerical precision means that it can
+  // occasionally occur with tracks that are very close to the surface
+  if (nlinks == 0) {
     return -1.0;
   }
-  int scatterSegmentNo(1);
-  if (nsegments != 1) {
-    scatterSegmentNo = rng.nextInt(1, nsegments);
-  }
 
-  double atten(1.0);
-  V3D scatterPos;
-  auto segItr(path1.cbegin());
-  for (int i = 0; i < scatterSegmentNo; ++i, ++segItr) {
-    double length = segItr->distInsideObject;
-    if (i == scatterSegmentNo - 1) {
-      length *= rng.nextValue();
-      scatterPos = segItr->entryPoint + direc * length;
+  // Function to calculate total attenuation for a track
+  auto calculateAttenuation = [](const Track &path, double lambda) {
+    double factor(1.0);
+    for (const auto &segment : path) {
+      const double length = segment.distInsideObject;
+      const auto &segObj = *(segment.object);
+      const auto &segMat = segObj.material();
+      factor *= attenuation(segMat.numberDensity(),
+                            segMat.totalScatterXSection(lambda) +
+                                segMat.absorbXSection(lambda),
+                            length);
     }
-    const auto &segObj = *(segItr->object);
-    const auto &segMat = segObj.material();
-    atten *= attenuation(segMat.numberDensity(),
-                         segMat.totalScatterXSection(lambdaBefore) +
-                             segMat.absorbXSection(lambdaBefore),
-                         length);
-  }
+    return factor;
+  };
 
   // Now track to final destination
   V3D scatteredDirec = endPos - scatterPos;
   scatteredDirec.normalize();
-  Track path2(scatterPos, scatteredDirec);
-  m_sample.interceptSurface(path2);
+  Track afterScatter(scatterPos, scatteredDirec);
+  m_sample.interceptSurface(afterScatter);
   if (m_env) {
-    m_env->interceptSurfaces(path2);
+    m_env->interceptSurfaces(afterScatter);
   }
-
-  for (const auto &segment : path2) {
-    double length = segment.distInsideObject;
-    const auto &segObj = *(segment.object);
-    const auto &segMat = segObj.material();
-    atten *= attenuation(segMat.numberDensity(),
-                         segMat.totalScatterXSection(lambdaAfter) +
-                             segMat.absorbXSection(lambdaAfter),
-                         length);
-  }
-
-  return atten;
+  return calculateAttenuation(beforeScatter, lambdaBefore) *
+         calculateAttenuation(afterScatter, lambdaAfter);
 }
 
 } // namespace Algorithms
diff --git a/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp b/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp
index f4e353e0230cc2d8ad3768ee8939f93842c285c1..bbb995b2a206661ed80e8af8483f1810957325ba 100644
--- a/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/MayersSampleCorrection.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/SampleValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
@@ -83,7 +84,6 @@ void MayersSampleCorrection::exec() {
   const auto sample = instrument->getSample();
   const auto beamLine = sample->getPos() - source->getPos();
   const auto frame = instrument->getReferenceFrame();
-  const double l1 = sample->getDistance(*source);
 
   // Sample
   const auto &sampleShape = inputWS->sample().getShape();
@@ -101,25 +101,25 @@ void MayersSampleCorrection::exec() {
   Progress prog(this, 0., 1., nhist);
   prog.setNotifyStep(0.01);
 
+  const auto &spectrumInfo = inputWS->spectrumInfo();
+
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
   for (int64_t i = 0; i < static_cast<int64_t>(nhist); ++i) {
     PARALLEL_START_INTERUPT_REGION
 
-    IDetector_const_sptr det;
-    try {
-      det = inputWS->getDetector(i);
-    } catch (Exception::NotFoundError &) {
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i) ||
+        spectrumInfo.isMasked(i)) {
       continue;
     }
-    if (det->isMonitor() || det->isMasked())
-      continue;
+
+    const auto &det = spectrumInfo.detector(i);
 
     MayersSampleCorrectionStrategy::Parameters params;
     params.mscat = mscatOn;
-    params.l1 = l1;
-    params.l2 = det->getDistance(*sample);
-    params.twoTheta = det->getTwoTheta(sample->getPos(), beamLine);
-    params.phi = det->getPhi();
+    params.l1 = spectrumInfo.l1();
+    params.l2 = spectrumInfo.l2(i);
+    params.twoTheta = det.getTwoTheta(sample->getPos(), beamLine);
+    params.phi = det.getPhi();
     params.rho = sampleMaterial.numberDensity();
     params.sigmaAbs = sampleMaterial.absorbXSection();
     params.sigmaSc = sampleMaterial.totalScatterXSection();
diff --git a/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp b/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
index 5fe679a20237a1a1956b8b3c511cbcc38ce5da9c..b3aa0b2168d826c9b6c507eb66a2176a538befa2 100644
--- a/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
+++ b/Framework/Algorithms/src/SampleCorrections/RectangularBeamProfile.cpp
@@ -1,5 +1,7 @@
 #include "MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h"
+#include "MantidAPI/Sample.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidGeometry/Instrument/SampleEnvironment.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 #include "MantidKernel/V3D.h"
@@ -70,5 +72,34 @@ IBeamProfile::Ray RectangularBeamProfile::generatePoint(
   return rngRay;
 }
 
+/**
+ * Compute a region that defines how the beam illuminates the given sample/can
+ * @param sample A reference to a sample object holding its shape
+ * @return A BoundingBox defining the active region
+ */
+Geometry::BoundingBox
+RectangularBeamProfile::defineActiveRegion(const API::Sample &sample) const {
+  auto sampleBox = sample.getShape().getBoundingBox();
+  try {
+    const auto &envBox = sample.getEnvironment().boundingBox();
+    sampleBox.grow(envBox);
+  } catch (std::runtime_error &) {
+  }
+  // In the beam direction use the maximum sample extent other wise restrict
+  // the active region to the width/height of beam
+  const auto &sampleMin(sampleBox.minPoint());
+  const auto &sampleMax(sampleBox.maxPoint());
+  V3D minPoint, maxPoint;
+  minPoint[m_horIdx] = m_min[m_horIdx];
+  maxPoint[m_horIdx] = m_min[m_horIdx] + m_width;
+  minPoint[m_upIdx] = m_min[m_upIdx];
+  maxPoint[m_upIdx] = m_min[m_upIdx] + m_height;
+  minPoint[m_beamIdx] = sampleMin[m_beamIdx];
+  maxPoint[m_beamIdx] = sampleMax[m_beamIdx];
+
+  return Geometry::BoundingBox(maxPoint.X(), maxPoint.Y(), maxPoint.Z(),
+                               minPoint.X(), minPoint.Y(), minPoint.Z());
+}
+
 } // namespace Algorithms
 } // namespace Mantid
diff --git a/Framework/Algorithms/src/SmoothNeighbours.cpp b/Framework/Algorithms/src/SmoothNeighbours.cpp
index f0ed22d076496e8b786e0b88413a0926d9d0b855..7cb6006d0abf01f2c91ab4bb00022de668edb42d 100644
--- a/Framework/Algorithms/src/SmoothNeighbours.cpp
+++ b/Framework/Algorithms/src/SmoothNeighbours.cpp
@@ -1,6 +1,8 @@
 #include "MantidAlgorithms/SmoothNeighbours.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/NearestNeighbourInfo.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidDataObjects/EventWorkspace.h"
@@ -332,7 +334,6 @@ void SmoothNeighbours::findNeighboursUbiqutious() {
   // Cull by radius
   RadiusFilter radiusFilter(Radius);
 
-  IDetector_const_sptr det;
   // Go through every input workspace pixel
   outWI = 0;
   int sum = getProperty("SumNumberOfNeighbours");
@@ -343,6 +344,7 @@ void SmoothNeighbours::findNeighboursUbiqutious() {
     for (size_t wi = 0; wi < inWS->getNumberHistograms(); wi++)
       used[wi] = false;
   }
+  const auto &detectorInfo = inWS->detectorInfo();
   for (size_t wi = 0; wi < inWS->getNumberHistograms(); wi++) {
     if (sum > 1)
       if (used[wi])
@@ -351,10 +353,10 @@ void SmoothNeighbours::findNeighboursUbiqutious() {
     try {
       // Get the list of detectors in this pixel
       const auto &dets = inWS->getSpectrum(wi).getDetectorIDs();
-      det = inst->getDetector(*dets.begin());
-      if (det->isMonitor())
+      const auto index = detectorInfo.indexOf(*dets.begin());
+      if (detectorInfo.isMonitor(index))
         continue; // skip monitor
-      if (det->isMasked()) {
+      if (detectorInfo.isMasked(index)) {
         // Calibration masks many detectors, but there should be 0s after
         // smoothing
         if (sum == 1)
@@ -362,7 +364,8 @@ void SmoothNeighbours::findNeighboursUbiqutious() {
         continue; // skip masked detectors
       }
       if (sum > 1) {
-        parent = det->getParent();
+        const auto &det = detectorInfo.detector(index);
+        parent = det.getParent();
         if (parent)
           grandparent = parent->getParent();
       }
@@ -404,8 +407,8 @@ void SmoothNeighbours::findNeighboursUbiqutious() {
             // Get the list of detectors in this pixel
             const std::set<detid_t> &dets =
                 inWS->getSpectrum(neighWI).getDetectorIDs();
-            det = inst->getDetector(*dets.begin());
-            neighbParent = det->getParent();
+            const auto &det = detectorInfo.detector(*dets.begin());
+            neighbParent = det.getParent();
             neighbGParent = neighbParent->getParent();
             if (noNeigh >= sum ||
                 neighbParent->getName().compare(parent->getName()) != 0 ||
@@ -510,10 +513,10 @@ double SmoothNeighbours::translateToMeters(const std::string radiusUnits,
     Instrument_const_sptr instrument = fetchInstrument();
 
     // Get the first idetector from the workspace index 0.
-    IDetector_const_sptr firstDet = inWS->getDetector(0);
+    const auto &firstDet = inWS->spectrumInfo().detector(0);
     // Find the bounding box of that detector
     BoundingBox bbox;
-    firstDet->getBoundingBox(bbox);
+    firstDet.getBoundingBox(bbox);
     // Multiply (meters/pixels) by number of pixels, note that enteredRadius
     // takes on meaning of the number of pixels.
     translatedRadius = bbox.width().norm() * enteredRadius;
diff --git a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
index 37797c11d91678d83cfe47feaa7c88c410d1179d..f48ec4225a508478c76fe69fc72e4bf787e1bd91 100644
--- a/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
+++ b/Framework/Algorithms/src/SofQWNormalisedPolygon.cpp
@@ -3,11 +3,15 @@
 #include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/NearestNeighbourInfo.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/Object.h"
 #include "MantidIndexing/IndexInfo.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/VectorHelper.h"
@@ -101,6 +105,7 @@ void SofQWNormalisedPolygon::exec() {
   int emode = m_EmodeProperties.m_emode;
 
   const auto &inputIndices = inputWS->indexInfo();
+  const auto &spectrumInfo = inputWS->spectrumInfo();
 
   PARALLEL_FOR_IF(Kernel::threadSafe(*inputWS, *outputWS))
   for (int64_t i = 0; i < static_cast<int64_t>(nHistos);
@@ -108,8 +113,7 @@ void SofQWNormalisedPolygon::exec() {
   {
     PARALLEL_START_INTERUPT_REGION
 
-    DetConstPtr detector = inputWS->getDetector(i);
-    if (detector->isMasked() || detector->isMonitor()) {
+    if (spectrumInfo.isMasked(i) || spectrumInfo.isMonitor(i)) {
       continue;
     }
 
@@ -128,7 +132,7 @@ void SofQWNormalisedPolygon::exec() {
     const double phiLower = phi - phiHalfWidth;
     const double phiUpper = phi + phiHalfWidth;
 
-    const double efixed = m_EmodeProperties.getEFixed(*detector);
+    const double efixed = m_EmodeProperties.getEFixed(spectrumInfo.detector(i));
     const specnum_t specNo = inputIndices.spectrumNumber(i);
     std::stringstream logStream;
     for (size_t j = 0; j < nEnergyBins; ++j) {
@@ -166,7 +170,7 @@ void SofQWNormalisedPolygon::exec() {
       if (qIndex != 0 && qIndex < static_cast<int>(m_Qout.size())) {
         // Add this spectra-detector pair to the mapping
         PARALLEL_CRITICAL(SofQWNormalisedPolygon_spectramap) {
-          detIDMapping[qIndex - 1].push_back(detector->getID());
+          detIDMapping[qIndex - 1].push_back(spectrumInfo.detector(i).getID());
         }
       }
     }
@@ -248,32 +252,29 @@ void SofQWNormalisedPolygon::initAngularCachesNonPSD(
   auto inst = workspace->getInstrument();
   const PointingAlong upDir = inst->getReferenceFrame()->pointingUp();
 
+  const auto &spectrumInfo = workspace->spectrumInfo();
+
   for (size_t i = 0; i < nhist; ++i) // signed for OpenMP
   {
     m_progress->report("Calculating detector angles");
-    IDetector_const_sptr det;
-    try {
-      det = workspace->getDetector(i);
-      // Check to see if there is an EFixed, if not skip it
-      try {
-        m_EmodeProperties.getEFixed(*det);
-      } catch (std::runtime_error &) {
-        det.reset();
-      }
-    } catch (Kernel::Exception::NotFoundError &) {
-      // Catch if no detector. Next line tests whether this happened - test
-      // placed
-      // outside here because Mac Intel compiler doesn't like 'continue' in a
-      // catch
-      // in an openmp block.
-    }
+
+    this->m_theta[i] = -1.0; // Indicates a detector to skip
+    this->m_thetaWidths[i] = -1.0;
+
     // If no detector found, skip onto the next spectrum
-    if (!det || det->isMonitor()) {
-      this->m_theta[i] = -1.0; // Indicates a detector to skip
-      this->m_thetaWidths[i] = -1.0;
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i)) {
       continue;
     }
-    this->m_theta[i] = workspace->detectorTwoTheta(*det);
+
+    const auto &det = spectrumInfo.detector(i);
+    // Check to see if there is an EFixed, if not skip it
+    try {
+      m_EmodeProperties.getEFixed(det);
+    } catch (std::runtime_error &) {
+      continue;
+    }
+
+    this->m_theta[i] = spectrumInfo.twoTheta(i);
 
     /**
      * Determine width from shape geometry. A group is assumed to contain
@@ -281,18 +282,26 @@ void SofQWNormalisedPolygon::initAngularCachesNonPSD(
      * The shape is retrieved and rotated to match the rotation of the detector.
      * The angular width is computed using the l2 distance from the sample
      */
-    if (auto group = boost::dynamic_pointer_cast<const DetectorGroup>(det)) {
+    Kernel::V3D pos;
+    boost::shared_ptr<const Object>
+        shape; // Defined in its own reference frame with centre at 0,0,0
+    Kernel::Quat rot;
+
+    if (spectrumInfo.hasUniqueDetector(i)) {
+      pos = det.getPos();
+      shape = det.shape();
+      rot = det.getRotation();
+    } else {
       // assume they all have same shape and same r,theta
-      auto dets = group->getDetectors();
-      det = dets[0];
+      const auto &group = dynamic_cast<const Geometry::DetectorGroup &>(det);
+      const auto &firstDet = group.getDetectors();
+      pos = firstDet[0]->getPos();
+      shape = firstDet[0]->shape();
+      rot = firstDet[0]->getRotation();
     }
-    const auto pos = det->getPos();
+
     double l2(0.0), t(0.0), p(0.0);
     pos.getSpherical(l2, t, p);
-    // Get the shape
-    auto shape =
-        det->shape(); // Defined in its own reference frame with centre at 0,0,0
-    auto rot = det->getRotation();
     BoundingBox bbox = shape->getBoundingBox();
     auto maxPoint(bbox.maxPoint());
     rot.rotate(maxPoint);
@@ -328,9 +337,11 @@ void SofQWNormalisedPolygon::initAngularCachesPSD(
   this->m_phi = std::vector<double>(nHistos);
   this->m_phiWidths = std::vector<double>(nHistos);
 
+  const auto &spectrumInfo = workspace->spectrumInfo();
+
   for (size_t i = 0; i < nHistos; ++i) {
     m_progress->report("Calculating detector angular widths");
-    DetConstPtr detector = workspace->getDetector(i);
+    const auto &detector = spectrumInfo.detector(i);
     g_log.debug() << "Current histogram: " << i << '\n';
     specnum_t inSpec = workspace->getSpectrum(i).getSpectrumNo();
     SpectraDistanceMap neighbours = neighbourInfo.getNeighboursExact(inSpec);
@@ -341,8 +352,8 @@ void SofQWNormalisedPolygon::initAngularCachesPSD(
     double phiWidth = -DBL_MAX;
 
     // Find theta and phi widths
-    double theta = workspace->detectorTwoTheta(*detector);
-    double phi = detector->getPhi();
+    double theta = spectrumInfo.twoTheta(i);
+    double phi = detector.getPhi();
 
     specnum_t deltaPlus1 = inSpec + 1;
     specnum_t deltaMinus1 = inSpec - 1;
@@ -354,9 +365,9 @@ void SofQWNormalisedPolygon::initAngularCachesPSD(
       g_log.debug() << "Neighbor ID: " << spec << '\n';
       if (spec == deltaPlus1 || spec == deltaMinus1 || spec == deltaPlusT ||
           spec == deltaMinusT) {
-        DetConstPtr detector_n = workspace->getDetector(spec - 1);
-        double theta_n = workspace->detectorTwoTheta(*detector_n) * 0.5;
-        double phi_n = detector_n->getPhi();
+        const auto &detector_n = spectrumInfo.detector(spec - 1);
+        double theta_n = spectrumInfo.twoTheta(spec - 1) * 0.5;
+        double phi_n = detector_n.getPhi();
 
         double dTheta = std::fabs(theta - theta_n);
         double dPhi = std::fabs(phi - phi_n);
diff --git a/Framework/Algorithms/src/Stitch1DMany.cpp b/Framework/Algorithms/src/Stitch1DMany.cpp
index ac33223869f903a578eea16a2a5916575528a5c7..482b4c769eb05fd71c71d9632cf54a9d7ec0c14e 100644
--- a/Framework/Algorithms/src/Stitch1DMany.cpp
+++ b/Framework/Algorithms/src/Stitch1DMany.cpp
@@ -1,5 +1,7 @@
 #include "MantidAlgorithms/Stitch1DMany.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -134,13 +136,6 @@ std::map<std::string, std::string> Stitch1DMany::validateInputs() {
   if (m_params.empty())
     errors["Params"] = "At least one parameter must be given.";
 
-  if (!m_scaleRHSWorkspace) {
-    // Flip these around for processing
-    std::reverse(m_inputWorkspaces.begin(), m_inputWorkspaces.end());
-    std::reverse(m_startOverlaps.begin(), m_startOverlaps.end());
-    std::reverse(m_endOverlaps.begin(), m_endOverlaps.end());
-  }
-
   m_scaleFactors.clear();
   m_outputWorkspace.reset();
 
diff --git a/Framework/Algorithms/src/StripVanadiumPeaks.cpp b/Framework/Algorithms/src/StripVanadiumPeaks.cpp
index f1a6c737dc7852b46e240494c3e09676859cacaa..3dc076cec44ac139de469c088c62e1ed69dc87c7 100644
--- a/Framework/Algorithms/src/StripVanadiumPeaks.cpp
+++ b/Framework/Algorithms/src/StripVanadiumPeaks.cpp
@@ -5,6 +5,7 @@
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/PhysicalConstants.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/VectorHelper.h"
 
 namespace Mantid {
diff --git a/Framework/Algorithms/src/SumSpectra.cpp b/Framework/Algorithms/src/SumSpectra.cpp
index 7ea0a775dea07feb9e15ecbfda1d55e0ce1eae66..083e34eb156686f729e8079b5648ba00d9310e02 100644
--- a/Framework/Algorithms/src/SumSpectra.cpp
+++ b/Framework/Algorithms/src/SumSpectra.cpp
@@ -21,7 +21,8 @@ using namespace DataObjects;
 
 SumSpectra::SumSpectra()
     : API::Algorithm(), m_outSpecNum(0), m_minWsInd(0), m_maxWsInd(0),
-      m_keepMonitors(false), m_numberOfSpectra(0), m_yLength(0), m_indices(),
+      m_keepMonitors(false), m_replaceSpecialValues(false),
+      m_numberOfSpectra(0), m_yLength(0), m_indices(),
       m_calculateWeightedSum(false) {}
 
 /** Initialisation method.
@@ -69,6 +70,10 @@ void SumSpectra::init() {
                   "values with zero error are dropped from the summation. To "
                   "estimate the number of dropped values see the "
                   "description. ");
+
+  declareProperty("RemoveSpecialValues", false,
+                  "If enabled floating point special values such as NaN or Inf"
+                  " are removed before the spectra are summed.");
 }
 
 /** Executes the algorithm
@@ -81,6 +86,7 @@ void SumSpectra::exec() {
   const std::vector<int> indices_list = getProperty("ListOfWorkspaceIndices");
 
   m_keepMonitors = getProperty("IncludeMonitors");
+  m_replaceSpecialValues = getProperty("RemoveSpecialValues");
 
   // Get the input workspace
   MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace");
@@ -141,7 +147,7 @@ void SumSpectra::exec() {
     size_t numMasked(0);  // total number of the masked and skipped spectra
     size_t numZeros(0);   // number of spectra which have 0 value in the first
     // column (used in special cases of evaluating how good
-    // Puasonian statistics is)
+    // Poissonian statistics is)
 
     Progress progress(this, 0, 1, this->m_indices.size());
 
@@ -159,8 +165,7 @@ void SumSpectra::exec() {
       this->doRebinnedOutput(outputWorkspace, progress, numSpectra, numMasked,
                              numZeros);
     } else {
-      this->doWorkspace2D(localworkspace, outSpec, progress, numSpectra,
-                          numMasked, numZeros);
+      this->doWorkspace2D(outSpec, progress, numSpectra, numMasked, numZeros);
     }
 
     // Pointer to sqrt function
@@ -212,9 +217,33 @@ SumSpectra::getOutputSpecNo(MatrixWorkspace_const_sptr localworkspace) {
   return specId;
 }
 
+/**
+  * Calls an algorithm to replace special values within the workspace
+  * such as NaN or Inf to 0.
+  * @param inputWs The workspace to process
+  * @return The workspace with special floating point values set to 0
+  */
+API::MatrixWorkspace_sptr
+SumSpectra::replaceSpecialValues(API::MatrixWorkspace_sptr inputWs) {
+  if (!m_replaceSpecialValues) {
+    // Skip any additional processing
+    return inputWs;
+  }
+
+  IAlgorithm_sptr alg = this->createChildAlgorithm("ReplaceSpecialValues");
+  alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", inputWs);
+  std::string outName = "_" + inputWs->getName() + "_clean";
+  alg->setProperty("OutputWorkspace", outName);
+  alg->setProperty("NaNValue", 0.0);
+  alg->setProperty("NaNError", 0.0);
+  alg->setProperty("InfinityValue", 0.0);
+  alg->setProperty("InfinityError", 0.0);
+  alg->executeAsChildAlg();
+  return alg->getProperty("OutputWorkspace");
+}
+
 /**
  * This function deals with the logic necessary for summing a Workspace2D.
- * @param localworkspace The input workspace for summing.
  * @param outSpec The spectrum for the summed output.
  * @param progress The progress indicator.
  * @param numSpectra The number of spectra contributed to the sum.
@@ -223,69 +252,73 @@ SumSpectra::getOutputSpecNo(MatrixWorkspace_const_sptr localworkspace) {
  * @param numZeros The number of zero bins in histogram workspace or empty
  * spectra for event workspace.
  */
-void SumSpectra::doWorkspace2D(MatrixWorkspace_const_sptr localworkspace,
-                               ISpectrum &outSpec, Progress &progress,
+void SumSpectra::doWorkspace2D(ISpectrum &outSpec, Progress &progress,
                                size_t &numSpectra, size_t &numMasked,
                                size_t &numZeros) {
   // Get references to the output workspaces's data vectors
-  auto &YSum = outSpec.mutableY();
-  auto &YError = outSpec.mutableE();
+  auto &OutputYSum = outSpec.mutableY();
+  auto &OutputYError = outSpec.mutableE();
 
   std::vector<double> Weight;
   std::vector<size_t> nZeros;
   if (m_calculateWeightedSum) {
-    Weight.assign(YSum.size(), 0);
-    nZeros.assign(YSum.size(), 0);
+    Weight.assign(OutputYSum.size(), 0);
+    nZeros.assign(OutputYSum.size(), 0);
   }
   numSpectra = 0;
   numMasked = 0;
   numZeros = 0;
 
+  MatrixWorkspace_sptr in_ws = getProperty("InputWorkspace");
+  // Clean workspace of any NANs or Inf values
+  auto localworkspace = replaceSpecialValues(in_ws);
   const auto &spectrumInfo = localworkspace->spectrumInfo();
   // Loop over spectra
-  for (const auto i : this->m_indices) {
+  for (const auto wsIndex : this->m_indices) {
     // Don't go outside the range.
-    if ((i >= this->m_numberOfSpectra) || (i < 0)) {
-      g_log.error() << "Invalid index " << i
+    if ((wsIndex >= this->m_numberOfSpectra) || (wsIndex < 0)) {
+      g_log.error() << "Invalid index " << wsIndex
                     << " was specified. Sum was aborted.\n";
       break;
     }
 
-    if (spectrumInfo.hasDetectors(i)) {
+    if (spectrumInfo.hasDetectors(wsIndex)) {
       // Skip monitors, if the property is set to do so
-      if (!m_keepMonitors && spectrumInfo.isMonitor(i))
+      if (!m_keepMonitors && spectrumInfo.isMonitor(wsIndex))
         continue;
       // Skip masked detectors
-      if (spectrumInfo.isMasked(i)) {
+      if (spectrumInfo.isMasked(wsIndex)) {
         numMasked++;
         continue;
       }
     }
     numSpectra++;
 
+    const auto &YValues = localworkspace->y(wsIndex);
+    const auto &YErrors = localworkspace->e(wsIndex);
+
     // Retrieve the spectrum into a vector
-    const auto &YValues = localworkspace->y(i);
-    const auto &YErrors = localworkspace->e(i);
-    if (m_calculateWeightedSum) {
-      for (int k = 0; k < this->m_yLength; ++k) {
-        if (YErrors[k] != 0) {
-          double errsq = YErrors[k] * YErrors[k];
-          YError[k] += errsq;
-          Weight[k] += 1. / errsq;
-          YSum[k] += YValues[k] / errsq;
+
+    for (int i = 0; i < m_yLength; ++i) {
+      if (m_calculateWeightedSum) {
+        if (std::isnormal(YErrors[i])) {
+          const double errsq = YErrors[i] * YErrors[i];
+          OutputYError[i] += errsq;
+          Weight[i] += 1. / errsq;
+          OutputYSum[i] += YValues[i] / errsq;
         } else {
-          nZeros[k]++;
+          nZeros[i]++;
         }
-      }
-    } else {
-      for (int k = 0; k < this->m_yLength; ++k) {
-        YSum[k] += YValues[k];
-        YError[k] += YErrors[k] * YErrors[k];
+
+      } else {
+        OutputYSum[i] += YValues[i];
+        OutputYError[i] += YErrors[i] * YErrors[i];
       }
     }
 
     // Map all the detectors onto the spectrum of the output
-    outSpec.addDetectorIDs(localworkspace->getSpectrum(i).getDetectorIDs());
+    outSpec.addDetectorIDs(
+        localworkspace->getSpectrum(wsIndex).getDetectorIDs());
 
     progress.report();
   }
@@ -294,7 +327,7 @@ void SumSpectra::doWorkspace2D(MatrixWorkspace_const_sptr localworkspace,
     numZeros = 0;
     for (size_t i = 0; i < Weight.size(); i++) {
       if (numSpectra > nZeros[i])
-        YSum[i] *= double(numSpectra - nZeros[i]) / Weight[i];
+        OutputYSum[i] *= double(numSpectra - nZeros[i]) / Weight[i];
       if (nZeros[i] != 0)
         numZeros += nZeros[i];
     }
@@ -313,21 +346,12 @@ void SumSpectra::doRebinnedOutput(MatrixWorkspace_sptr outputWorkspace,
                                   Progress &progress, size_t &numSpectra,
                                   size_t &numMasked, size_t &numZeros) {
   // Get a copy of the input workspace
-  MatrixWorkspace_sptr temp = getProperty("InputWorkspace");
+  MatrixWorkspace_sptr in_ws = getProperty("InputWorkspace");
 
   // First, we need to clean the input workspace for nan's and inf's in order
   // to treat the data correctly later. This will create a new private
   // workspace that will be retrieved as mutable.
-  IAlgorithm_sptr alg = this->createChildAlgorithm("ReplaceSpecialValues");
-  alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", temp);
-  std::string outName = "_" + temp->getName() + "_clean";
-  alg->setProperty("OutputWorkspace", outName);
-  alg->setProperty("NaNValue", 0.0);
-  alg->setProperty("NaNError", 0.0);
-  alg->setProperty("InfinityValue", 0.0);
-  alg->setProperty("InfinityError", 0.0);
-  alg->executeAsChildAlg();
-  MatrixWorkspace_sptr localworkspace = alg->getProperty("OutputWorkspace");
+  auto localworkspace = replaceSpecialValues(in_ws);
 
   // Transform to real workspace types
   RebinnedOutput_sptr inWS =
diff --git a/Framework/Algorithms/src/UnGroupWorkspace.cpp b/Framework/Algorithms/src/UnGroupWorkspace.cpp
index 87f1dfcff5a90a6fa43ab1e69555097eabd348c1..816b067e552520f39a14b1fd04e7695cf228203d 100644
--- a/Framework/Algorithms/src/UnGroupWorkspace.cpp
+++ b/Framework/Algorithms/src/UnGroupWorkspace.cpp
@@ -1,5 +1,7 @@
 #include "MantidAlgorithms/UnGroupWorkspace.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 namespace Mantid {
 namespace Algorithms {
diff --git a/Framework/Algorithms/src/UnwrapMonitor.cpp b/Framework/Algorithms/src/UnwrapMonitor.cpp
index 7d42b638d6878d561e92425ea46197fbc916e8ad..6d6519460ff56a3a994f4191772ef6742fe8bd96 100644
--- a/Framework/Algorithms/src/UnwrapMonitor.cpp
+++ b/Framework/Algorithms/src/UnwrapMonitor.cpp
@@ -97,7 +97,7 @@ void UnwrapMonitor::exec() {
 
   // This will be used later to store the maximum number of bin BOUNDARIES for
   // the rebinning
-  int max_bins = 0;
+  size_t max_bins = 0;
 
   const auto &spectrumInfo = m_inputWS->spectrumInfo();
   const double L1 = spectrumInfo.l1();
@@ -124,12 +124,12 @@ void UnwrapMonitor::exec() {
 
     // Unwrap the x data. Returns the bin ranges that end up being used
     const double Ld = L1 + spectrumInfo.l2(i);
-    MantidVec newX;
+    std::vector<double> newX;
     const std::vector<int> rangeBounds = this->unwrapX(newX, i, Ld);
 
     // Unwrap the y & e data according to the ranges found above
-    MantidVec newY;
-    MantidVec newE;
+    std::vector<double> newY;
+    std::vector<double> newE;
     this->unwrapYandE(tempWS, i, rangeBounds, newY, newE);
 
     // Now set the new X, Y and E values on the Histogram
@@ -142,7 +142,7 @@ void UnwrapMonitor::exec() {
     // Get the maximum number of bins (excluding monitors) for the rebinning
     // below
     if (!spectrumInfo.isMonitor(i)) {
-      const int XLen = static_cast<int>(tempWS->x(i).size());
+      const size_t XLen = tempWS->x(i).size();
       if (XLen > max_bins)
         max_bins = XLen;
     }
@@ -176,8 +176,9 @@ void UnwrapMonitor::exec() {
  *  @return A 3-element vector containing the bins at which the upper and lower
  * ranges start & end
  */
-const std::vector<int>
-UnwrapMonitor::unwrapX(MantidVec &newX, const int &spectrum, const double &Ld) {
+const std::vector<int> UnwrapMonitor::unwrapX(std::vector<double> &newX,
+                                              const int &spectrum,
+                                              const double &Ld) {
   // Create and initalise the vector that will store the bin ranges, and will be
   // returned
   // Elements are: 0 - Lower range start, 1 - Lower range end, 2 - Upper range
@@ -302,10 +303,11 @@ std::pair<int, int> UnwrapMonitor::handleFrameOverlapped(
 void UnwrapMonitor::unwrapYandE(const API::MatrixWorkspace_sptr &tempWS,
                                 const int &spectrum,
                                 const std::vector<int> &rangeBounds,
-                                MantidVec &newY, MantidVec &newE) {
+                                std::vector<double> &newY,
+                                std::vector<double> &newE) {
   // Copy over the relevant ranges of Y & E data
-  MantidVec &Y = newY;
-  MantidVec &E = newE;
+  std::vector<double> &Y = newY;
+  std::vector<double> &E = newE;
   // Get references to the input data
   const auto &YIn = m_inputWS->y(spectrum);
   const auto &EIn = m_inputWS->e(spectrum);
@@ -360,9 +362,10 @@ void UnwrapMonitor::unwrapYandE(const API::MatrixWorkspace_sptr &tempWS,
  */
 API::MatrixWorkspace_sptr
 UnwrapMonitor::rebin(const API::MatrixWorkspace_sptr &workspace,
-                     const double &min, const double &max, const int &numBins) {
+                     const double &min, const double &max,
+                     const size_t &numBins) {
   // Calculate the width of a bin
-  const double step = (max - min) / numBins;
+  const double step = (max - min) / static_cast<double>(numBins);
 
   // Create a Rebin child algorithm
   IAlgorithm_sptr childAlg = createChildAlgorithm("Rebin");
diff --git a/Framework/Algorithms/src/UnwrapSNS.cpp b/Framework/Algorithms/src/UnwrapSNS.cpp
index bb222f377302d1bc01bebbade2aa7dfa4eb54c6f..ab2a39198048fe388ac4dafa5bdc790b0143552b 100644
--- a/Framework/Algorithms/src/UnwrapSNS.cpp
+++ b/Framework/Algorithms/src/UnwrapSNS.cpp
@@ -150,7 +150,7 @@ void UnwrapSNS::exec() {
     } else {
       const double Ld = L1 + spectrumInfo.l2(workspaceIndex);
       // fix the x-axis
-      MantidVec timeBins;
+      std::vector<double> timeBins;
       size_t pivot = this->unwrapX(m_inputWS->x(workspaceIndex), timeBins, Ld);
       outputWS->setBinEdges(workspaceIndex, std::move(timeBins));
 
@@ -212,7 +212,7 @@ void UnwrapSNS::execEvent() {
     if (spectrumInfo.hasDetectors(workspaceIndex))
       Ld = L1 + spectrumInfo.l2(workspaceIndex);
 
-    MantidVec time_bins;
+    std::vector<double> time_bins;
     if (outW->x(0).size() > 2) {
       this->unwrapX(m_inputWS->x(workspaceIndex), time_bins, Ld);
       outW->setBinEdges(workspaceIndex, std::move(time_bins));
@@ -220,7 +220,7 @@ void UnwrapSNS::execEvent() {
       outW->setSharedX(workspaceIndex, m_inputWS->sharedX(workspaceIndex));
     }
     if (numEvents > 0) {
-      MantidVec times(numEvents);
+      std::vector<double> times(numEvents);
       outW->getSpectrum(workspaceIndex).getTofs(times);
       double filterVal = m_Tmin * Ld / m_LRef;
       for (size_t j = 0; j < numEvents; j++) {
@@ -239,11 +239,11 @@ void UnwrapSNS::execEvent() {
 }
 
 int UnwrapSNS::unwrapX(const Mantid::HistogramData::HistogramX &datain,
-                       MantidVec &dataout, const double &Ld) {
-  MantidVec tempX_L; // lower half - to be frame wrapped
+                       std::vector<double> &dataout, const double &Ld) {
+  std::vector<double> tempX_L; // lower half - to be frame wrapped
   tempX_L.reserve(m_XSize);
   tempX_L.clear();
-  MantidVec tempX_U; // upper half - to not be frame wrapped
+  std::vector<double> tempX_U; // upper half - to not be frame wrapped
   tempX_U.reserve(m_XSize);
   tempX_U.clear();
 
diff --git a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
index dfcb105e054d8bb8b140f1f83623055df87fe92b..872e319dd4ee5ecae44b6eef4c727fb0be9afe83 100644
--- a/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
+++ b/Framework/Algorithms/src/VesuvioL1ThetaResolution.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/TextAxis.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/Statistics.h"
 #include "MantidKernel/Unit.h"
@@ -37,8 +38,6 @@ public:
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(VesuvioL1ThetaResolution)
 
-//----------------------------------------------------------------------------------------------
-
 /// Algorithms name for identification. @see Algorithm::name
 const std::string VesuvioL1ThetaResolution::name() const {
   return "VesuvioL1ThetaResolution";
@@ -213,12 +212,11 @@ void VesuvioL1ThetaResolution::exec() {
     // Process data for L1 distribution
     if (m_l1DistributionWs) {
       auto &x = m_l1DistributionWs->mutableX(i);
-      std::vector<double> y(numEvents, 1.0);
 
       std::sort(l1.begin(), l1.end());
       std::copy(l1.begin(), l1.end(), x.begin());
 
-      m_l1DistributionWs->mutableY(i) = y;
+      m_l1DistributionWs->mutableY(i) = 1.0;
 
       auto &spec = m_l1DistributionWs->getSpectrum(i);
       spec.setSpectrumNo(specNo);
@@ -228,12 +226,11 @@ void VesuvioL1ThetaResolution::exec() {
     // Process data for theta distribution
     if (m_thetaDistributionWs) {
       auto &x = m_thetaDistributionWs->mutableX(i);
-      std::vector<double> y(numEvents, 1.0);
 
       std::sort(theta.begin(), theta.end());
       std::copy(theta.begin(), theta.end(), x.begin());
 
-      m_thetaDistributionWs->mutableY(i) = y;
+      m_thetaDistributionWs->mutableY(i) = 1.0;
 
       auto &spec = m_thetaDistributionWs->getSpectrum(i);
       spec.setSpectrumNo(specNo);
diff --git a/Framework/Algorithms/src/WienerSmooth.cpp b/Framework/Algorithms/src/WienerSmooth.cpp
index a8f8d361dddf9bf06d40028e2290b4b18c811ebc..0d1683b2624ea21a1f0678b89055f88180486bea 100644
--- a/Framework/Algorithms/src/WienerSmooth.cpp
+++ b/Framework/Algorithms/src/WienerSmooth.cpp
@@ -371,9 +371,10 @@ WienerSmooth::smoothSingleSpectrum(API::MatrixWorkspace_sptr inputWS,
     auto histogram = out->histogram(0);
     histogram.setSharedX(inputWS->sharedX(wsIndex));
     histogram.setSharedE(inputWS->sharedE(wsIndex));
-    auto newSize = histogram.y().size() - 1;
 
+    auto newSize = histogram.y().size() - 1;
     histogram.resize(newSize);
+
     out->setHistogram(0, histogram);
   } else {
     out->setSharedX(0, inputWS->sharedX(wsIndex));
@@ -386,9 +387,8 @@ WienerSmooth::smoothSingleSpectrum(API::MatrixWorkspace_sptr inputWS,
 /**
  * Get the start and end of the x-interval.
  * @param X :: The x-vector of a spectrum.
- * @param isHistogram :: Is the x-vector comming form a histogram? If it's true
- * the bin
- *   centres are used.
+ * @param isHistogram :: Is the x-vector coming form a histogram? If it's true
+ * the bin centers are used.
  * @return :: A pair of start x and end x.
  */
 std::pair<double, double>
diff --git a/Framework/Algorithms/src/WorkflowAlgorithmRunner.cpp b/Framework/Algorithms/src/WorkflowAlgorithmRunner.cpp
index c41b7b2f6cf0db115c3073f9d21b2d8dc0cbc12a..c0969dddf839feb9f60d955a635465d412d0e670 100644
--- a/Framework/Algorithms/src/WorkflowAlgorithmRunner.cpp
+++ b/Framework/Algorithms/src/WorkflowAlgorithmRunner.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidKernel/MandatoryValidator.h"
 
+#include <deque>
 #include <unordered_map>
 
 using namespace Mantid::API;
diff --git a/Framework/Algorithms/src/WorkspaceJoiners.cpp b/Framework/Algorithms/src/WorkspaceJoiners.cpp
index 6dc573aeda47c3d5044017c16f84c47da1d6d797..2703228332aaca364febf218dbea5fbcfd528948 100644
--- a/Framework/Algorithms/src/WorkspaceJoiners.cpp
+++ b/Framework/Algorithms/src/WorkspaceJoiners.cpp
@@ -6,6 +6,7 @@
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidDataObjects/WorkspaceCreation.h"
+#include "MantidKernel/Unit.h"
 
 namespace Mantid {
 namespace Algorithms {
@@ -75,6 +76,7 @@ MatrixWorkspace_sptr WorkspaceJoiners::execWS2D(const MatrixWorkspace &ws1,
   // For second loop we use the offset from the first
   const int64_t &nhist2 = ws2.getNumberHistograms();
   const auto &spectrumInfo = ws2.spectrumInfo();
+  auto &outSpectrumInfo = output->mutableSpectrumInfo();
   PARALLEL_FOR_IF(Kernel::threadSafe(ws2, *output))
   for (int64_t j = 0; j < nhist2; ++j) {
     PARALLEL_START_INTERUPT_REGION
@@ -94,8 +96,12 @@ MatrixWorkspace_sptr WorkspaceJoiners::execWS2D(const MatrixWorkspace &ws1,
       }
     }
     // Propagate spectrum masking
-    if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j))
-      output->maskWorkspaceIndex(nhist1 + j);
+    if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j)) {
+      output->getSpectrum(nhist1 + j).clearData();
+      PARALLEL_CRITICAL(setMasked) {
+        outSpectrumInfo.setMasked(nhist1 + j, true);
+      }
+    }
 
     m_progress->report();
     PARALLEL_END_INTERUPT_REGION
@@ -130,6 +136,7 @@ MatrixWorkspace_sptr WorkspaceJoiners::execEvent() {
   // For second loop we use the offset from the first
   const int64_t &nhist2 = event_ws2->getNumberHistograms();
   const auto &spectrumInfo = event_ws2->spectrumInfo();
+  auto &outSpectrumInfo = output->mutableSpectrumInfo();
   for (int64_t j = 0; j < nhist2; ++j) {
     // This is the workspace index at which we assign in the output
     int64_t output_wi = j + nhist1;
@@ -137,8 +144,12 @@ MatrixWorkspace_sptr WorkspaceJoiners::execEvent() {
 
     // Propagate spectrum masking. First workspace will have been done by the
     // factory
-    if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j))
-      output->maskWorkspaceIndex(output_wi);
+    if (spectrumInfo.hasDetectors(j) && spectrumInfo.isMasked(j)) {
+      output->getSpectrum(output_wi).clearData();
+      PARALLEL_CRITICAL(setMaskedEvent) {
+        outSpectrumInfo.setMasked(output_wi, true);
+      }
+    }
 
     m_progress->report();
   }
diff --git a/Framework/Algorithms/test/AddLogDerivativeTest.h b/Framework/Algorithms/test/AddLogDerivativeTest.h
index 4d83e735cc5a6c71f92b432f70c620b418e92612..756cb8cf04a4186297275c2de4dbf495feee6365 100644
--- a/Framework/Algorithms/test/AddLogDerivativeTest.h
+++ b/Framework/Algorithms/test/AddLogDerivativeTest.h
@@ -34,7 +34,7 @@ public:
   /** Perform test, return result */
   TimeSeriesProperty<double> *do_test(int Derivative, bool willFail = false,
                                       bool addRepeatedTimes = false) {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("Dummy", ws);
 
     TimeSeriesProperty<double> *p =
diff --git a/Framework/Algorithms/test/AddNoteTest.h b/Framework/Algorithms/test/AddNoteTest.h
index 8397e4aa49ab1395e39960b546f78189ccd91163..f35be8902d98d76ac1a0554cb3270e06bad6b571 100644
--- a/Framework/Algorithms/test/AddNoteTest.h
+++ b/Framework/Algorithms/test/AddNoteTest.h
@@ -18,7 +18,7 @@ public:
   static void destroySuite(AddNoteTest *suite) { delete suite; }
 
   void test_delete_existing_removes_complete_log_first() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     TS_ASSERT_THROWS_NOTHING(executeAlgorithm(
         ws, "Test Name", "2010-09-14T04:20:12", "First Test String"));
     checkLogWithEntryExists<std::string>(ws, "Test Name", "2010-09-14T04:20:12",
@@ -30,7 +30,7 @@ public:
   }
 
   void test_empty_time_property_produces_current_time_in_log_output() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     // Get Current Date Time
     namespace pt = boost::posix_time;
@@ -66,7 +66,7 @@ public:
   }
 
   void test_algorithm_fails_if_log_exists_but_is_not_a_time_series() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     auto &run = ws->mutableRun();
     run.addProperty<std::string>("Test Name", "Test");
     TS_ASSERT_THROWS(
@@ -140,4 +140,4 @@ private:
   }
 };
 
-#endif /* MANTID_ALGORITHMS_ADDNOTETEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_ADDNOTETEST_H_ */
diff --git a/Framework/Algorithms/test/AddSampleLogTest.h b/Framework/Algorithms/test/AddSampleLogTest.h
index 5941f875d468c03717f9290b498714a7f0b1fdee..c2cb9ec6c7e91f98aecd9595fcc046322936960e 100644
--- a/Framework/Algorithms/test/AddSampleLogTest.h
+++ b/Framework/Algorithms/test/AddSampleLogTest.h
@@ -18,26 +18,26 @@ class AddSampleLogTest : public CxxTest::TestSuite {
 public:
   void test_Workspace2D() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "String", "My Value", 0.0);
   }
 
   void test_EventWorkspace() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "String", "My Value", 0.0);
   }
 
   void test_CanOverwrite() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "String", "My Value", 0.0);
     ExecuteAlgorithm(ws, "My Name", "String", "My New Value", 0.0);
   }
 
   void test_Number() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "Number", "1.234", 1.234);
     ExecuteAlgorithm(ws, "My Name", "Number", "2.456", 2.456);
 
@@ -47,19 +47,19 @@ public:
 
   void test_BadNumber() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "Number", "OneTwoThreeFour", 0.0, true);
   }
 
   void test_BadNumberSeries() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ExecuteAlgorithm(ws, "My Name", "Number Series", "FiveSixSeven", 0.0, true);
   }
 
   void test_NumberSeries() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ws->mutableRun().setStartAndEndTime(DateAndTime("2013-12-18T13:40:00"),
                                         DateAndTime("2013-12-18T13:42:00"));
     ExecuteAlgorithm(ws, "My Name", "Number Series", "1.234", 1.234);
@@ -73,7 +73,7 @@ public:
 
   void test_Units() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ws->mutableRun().setStartAndEndTime(DateAndTime("2013-12-18T13:40:00"),
                                         DateAndTime("2013-12-18T13:42:00"));
     ExecuteAlgorithm(ws, "My Name", "Number Series", "1.234", 1.234, false,
@@ -86,7 +86,7 @@ public:
 
   void test_number_type() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     ws->mutableRun().setStartAndEndTime(DateAndTime("2013-12-18T13:40:00"),
                                         DateAndTime("2013-12-18T13:42:00"));
     ExecuteAlgorithm(ws, "My Name", "Number Series", "1.234", 1.234, false,
diff --git a/Framework/Algorithms/test/AddTimeSeriesLogTest.h b/Framework/Algorithms/test/AddTimeSeriesLogTest.h
index 59b106f78f7235964cb04b426860256dc5f0d2de..682fe50fb867080daad80c1c6921d0dc9f0f806b 100644
--- a/Framework/Algorithms/test/AddTimeSeriesLogTest.h
+++ b/Framework/Algorithms/test/AddTimeSeriesLogTest.h
@@ -20,7 +20,7 @@ public:
   static void destroySuite(AddTimeSeriesLogTest *suite) { delete suite; }
 
   void test_defaults_create_a_double_type_series() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     TS_ASSERT_THROWS_NOTHING(
         executeAlgorithm(ws, "Test Name", "2010-09-14T04:20:12", 20.0));
     checkLogWithEntryExists<double>(ws, "Test Name", "2010-09-14T04:20:12",
@@ -32,7 +32,7 @@ public:
   }
 
   void test_forcing_to_int_creates_int_from_double() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     TS_ASSERT_THROWS_NOTHING(executeAlgorithm(
         ws, "Test Name", "2010-09-14T04:20:12", 20.5, Integer));
 
@@ -57,7 +57,7 @@ public:
   }
 
   void test_delete_existing_removes_complete_log_first() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     TS_ASSERT_THROWS_NOTHING(
         executeAlgorithm(ws, "Test Name", "2010-09-14T04:20:12", 20.0));
     checkLogWithEntryExists<double>(ws, "Test Name", "2010-09-14T04:20:12",
@@ -105,7 +105,7 @@ public:
   }
 
   void test_algorithm_fails_if_log_exists_but_is_not_a_time_series() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     auto &run = ws->mutableRun();
     run.addProperty<double>("Test Name", 1.0);
     TS_ASSERT_THROWS(
@@ -114,7 +114,7 @@ public:
   }
 
   void test_algorithm_fails_if_time_series_exists_but_it_is_incorrect_type() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     auto &run = ws->mutableRun();
     const std::string logName = "DoubleSeries";
     auto *timeSeries = new Mantid::Kernel::TimeSeriesProperty<double>(logName);
diff --git a/Framework/Algorithms/test/AlignDetectorsTest.h b/Framework/Algorithms/test/AlignDetectorsTest.h
index e59810f9d8dbb0742533ce8b6647c73e4e3ae4ef..15cf8cde20e998d7e96a342bfe72033be1fb89b2 100644
--- a/Framework/Algorithms/test/AlignDetectorsTest.h
+++ b/Framework/Algorithms/test/AlignDetectorsTest.h
@@ -9,6 +9,7 @@
 #include "MantidDataHandling/LoadEventPreNexus.h"
 #include "MantidDataHandling/LoadNexus.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidKernel/Unit.h"
 
 using namespace Mantid::Algorithms;
 using namespace Mantid::DataHandling;
diff --git a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
index ac1d57638cffd3a60457e02d1dabac05e5a42737..c3131a7605dfc62b27e0a04b6682aa016d4bf9a6 100644
--- a/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
+++ b/Framework/Algorithms/test/AnnularRingAbsorptionTest.h
@@ -45,9 +45,9 @@ public:
 
     const double delta(1e-08);
     const size_t middle_index = 4;
-    TS_ASSERT_DELTA(0.97773712, outWS->readY(0).front(), delta);
-    TS_ASSERT_DELTA(0.83720057, outWS->readY(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.72020602, outWS->readY(0).back(), delta);
+    TS_ASSERT_DELTA(0.96859812, outWS->readY(0).front(), delta);
+    TS_ASSERT_DELTA(0.79254304, outWS->readY(0)[middle_index], delta);
+    TS_ASSERT_DELTA(0.67064972, outWS->readY(0).back(), delta);
   }
 
   //-------------------- Failure cases --------------------------------
@@ -57,7 +57,7 @@ public:
 
     auto alg = createAlgorithm();
     // Create a simple test workspace that has no instrument
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace(10, 5);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace(10, 5);
 
     TS_ASSERT_THROWS(
         alg->setProperty<MatrixWorkspace_sptr>("InputWorkspace", testWS),
diff --git a/Framework/Algorithms/test/AppendSpectraTest.h b/Framework/Algorithms/test/AppendSpectraTest.h
index 97369dc7ad525bbe481975e12c9378e7ba549b9d..50e462cd810566124065940690350decaa5634c0 100644
--- a/Framework/Algorithms/test/AppendSpectraTest.h
+++ b/Framework/Algorithms/test/AppendSpectraTest.h
@@ -4,6 +4,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAlgorithms/AppendSpectra.h"
 #include "MantidDataHandling/LoadRaw3.h"
 #include "MantidKernel/TimeSeriesProperty.h"
@@ -66,8 +67,10 @@ public:
 
     // Mask a spectrum and check it is carried over
     const size_t maskTop(5), maskBottom(10);
-    in1->maskWorkspaceIndex(maskTop);
-    in2->maskWorkspaceIndex(maskBottom);
+    in1->getSpectrum(maskTop).clearData();
+    in2->getSpectrum(maskBottom).clearData();
+    in1->mutableSpectrumInfo().setMasked(maskTop, true);
+    in2->mutableSpectrumInfo().setMasked(maskBottom, true);
 
     // Now it should succeed
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace1", "top"));
@@ -94,8 +97,8 @@ public:
                      in2->getAxis(1)->spectraNo(2));
 
     // Check masking
-    TS_ASSERT_EQUALS(output->getDetector(maskTop)->isMasked(), true);
-    TS_ASSERT_EQUALS(output->getDetector(10 + maskBottom)->isMasked(), true);
+    TS_ASSERT_EQUALS(output->spectrumInfo().isMasked(maskTop), true);
+    TS_ASSERT_EQUALS(output->spectrumInfo().isMasked(10 + maskBottom), true);
   }
 
   //----------------------------------------------------------------------------------------------
@@ -145,14 +148,14 @@ public:
   //----------------------------------------------------------------------------------------------
   void testExecMismatchedWorkspaces() {
     MatrixWorkspace_sptr ews =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace(10, 10);
 
     // Check it fails if mixing event workspaces and workspace 2Ds
     AppendSpectra alg;
     alg.initialize();
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace1", ews));
     TS_ASSERT_THROWS_NOTHING(alg.setProperty(
-        "InputWorkspace2", WorkspaceCreationHelper::Create2DWorkspace(10, 10)));
+        "InputWorkspace2", WorkspaceCreationHelper::create2DWorkspace(10, 10)));
     TS_ASSERT_THROWS_NOTHING(
         alg.setPropertyValue("OutputWorkspace", "outevent"));
     alg.execute();
@@ -165,12 +168,12 @@ public:
     int numBins = 20;
 
     if (event) {
-      ws1 = WorkspaceCreationHelper::CreateEventWorkspace2(
+      ws1 = WorkspaceCreationHelper::createEventWorkspace2(
           10, numBins); // 2 events per bin
-      ws2 = WorkspaceCreationHelper::CreateEventWorkspace2(5, numBins);
+      ws2 = WorkspaceCreationHelper::createEventWorkspace2(5, numBins);
     } else {
-      ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, numBins);
-      ws2 = WorkspaceCreationHelper::Create2DWorkspace(5, numBins);
+      ws1 = WorkspaceCreationHelper::create2DWorkspace(10, numBins);
+      ws2 = WorkspaceCreationHelper::create2DWorkspace(5, numBins);
     }
 
     auto ws1Log = new TimeSeriesProperty<std::string>("aLog");
diff --git a/Framework/Algorithms/test/ApplyDeadTimeCorrTest.h b/Framework/Algorithms/test/ApplyDeadTimeCorrTest.h
index 131b19f6c1f9527054c5bcf7e80c8338efc74476..18b2d5c4a25a18b8d720a5afb06f1b096e4bb63b 100644
--- a/Framework/Algorithms/test/ApplyDeadTimeCorrTest.h
+++ b/Framework/Algorithms/test/ApplyDeadTimeCorrTest.h
@@ -171,7 +171,7 @@ public:
   /// Test algorithm rejects an input workspace with uneven bin widths
   void testUnevenBinWidths() {
     constexpr size_t numSpectra(2);
-    auto workspace = WorkspaceCreationHelper::Create2DWorkspace(
+    auto workspace = WorkspaceCreationHelper::create2DWorkspace(
         static_cast<int>(numSpectra), 10);
 
     // Rebin the workspace to make bin widths uneven
diff --git a/Framework/Algorithms/test/ApplyDetailedBalanceTest.h b/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
index 399616f057b25cc00d79de3007a3ecebbe5664d8..a522d25c087a781ca5d6a00839ae649ea34729e6 100644
--- a/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
+++ b/Framework/Algorithms/test/ApplyDetailedBalanceTest.h
@@ -92,7 +92,7 @@ public:
   }
 
   void test_event() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     evin->getAxis(0)->unit() = UnitFactory::Instance().create("DeltaE");
diff --git a/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h b/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
index 2f28b6442e34ea003f6798c478bf1d50cc1964e8..cde5ba6e7c2a5c1e34ee464c1a6c02f9038852fd 100644
--- a/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
+++ b/Framework/Algorithms/test/ApplyTransmissionCorrectionTest.h
@@ -48,7 +48,7 @@ public:
 
     const std::string transWS("trans");
     Workspace2D_sptr trans_ws =
-        WorkspaceCreationHelper::Create2DWorkspace154(1, 1, 1);
+        WorkspaceCreationHelper::create2DWorkspace154(1, 1, 1);
     trans_ws->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength");
     trans_ws->mutableY(0)[0] = 0.6;
     trans_ws->mutableE(0)[0] = 0.02;
diff --git a/Framework/Algorithms/test/AsymmetryCalcTest.h b/Framework/Algorithms/test/AsymmetryCalcTest.h
index 8deb314373051ceae9d4a02181540ed27c7f4ccb..19e8c2d8d9dc0374d25b913192e9b74f338e8e2d 100644
--- a/Framework/Algorithms/test/AsymmetryCalcTest.h
+++ b/Framework/Algorithms/test/AsymmetryCalcTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAlgorithms/AsymmetryCalc.h"
 #include "MantidDataHandling/GroupDetectors.h"
 #include "MantidDataHandling/LoadInstrument.h"
@@ -81,7 +82,7 @@ public:
   }
 
   void test_single_spectra() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(3, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(3, 10);
     for (size_t i = 0; i < ws->getNumberHistograms(); ++i) {
       auto &y = ws->mutableY(i);
       std::fill(y.begin(), y.end(), static_cast<double>(i + 1));
@@ -104,7 +105,7 @@ public:
   }
 
   void test_yUnitLabel() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(2, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(2, 1);
 
     AsymmetryCalc alg;
     alg.initialize();
@@ -123,7 +124,7 @@ public:
   }
 
   void test_validateInputs() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(2, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(2, 1);
     AsymmetryCalc asymCalc;
     asymCalc.initialize();
     asymCalc.setChild(true);
@@ -146,9 +147,9 @@ public:
  */
   void testValidateInputsWithWSGroup() {
     auto ws1 = boost::static_pointer_cast<Workspace>(
-        WorkspaceCreationHelper::Create2DWorkspace(2, 1));
+        WorkspaceCreationHelper::create2DWorkspace(2, 1));
     auto ws2 = boost::static_pointer_cast<Workspace>(
-        WorkspaceCreationHelper::Create2DWorkspace(2, 1));
+        WorkspaceCreationHelper::create2DWorkspace(2, 1));
     AnalysisDataService::Instance().add("workspace1", ws1);
     AnalysisDataService::Instance().add("workspace2", ws2);
     auto group = boost::make_shared<WorkspaceGroup>();
diff --git a/Framework/Algorithms/test/AverageLogDataTest.h b/Framework/Algorithms/test/AverageLogDataTest.h
index 0323e175ef1220af6a8ff1acab91942ed18b461c..9fd415828bab13f33c3284cebef7e28d7c767651 100644
--- a/Framework/Algorithms/test/AverageLogDataTest.h
+++ b/Framework/Algorithms/test/AverageLogDataTest.h
@@ -113,7 +113,7 @@ private:
   void makeWS(double shift) {
     inputWS = "AverageLogDataTestWS";
     Mantid::DataObjects::Workspace2D_sptr w =
-        WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+        WorkspaceCreationHelper::create2DWorkspace(1, 1);
     Mantid::Kernel::DateAndTime run_start("2010-01-01T00:00:00");
     Mantid::Kernel::TimeSeriesProperty<double> *pc, *p1;
     pc = new Mantid::Kernel::TimeSeriesProperty<double>("proton_charge");
diff --git a/Framework/Algorithms/test/BinaryOperationTest.h b/Framework/Algorithms/test/BinaryOperationTest.h
index ade17cfb671c262f7b33c68d8995db852bf0fa58..826d443dc14f0f9b6a5e2fab9d00a50db977665e 100644
--- a/Framework/Algorithms/test/BinaryOperationTest.h
+++ b/Framework/Algorithms/test/BinaryOperationTest.h
@@ -7,6 +7,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAlgorithms/BinaryOperation.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
@@ -68,17 +69,17 @@ public:
   void testcheckSizeCompatibility1D1D() {
     // Register the workspace in the data service
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(20);
+        WorkspaceCreationHelper::create1DWorkspaceFib(20);
     Workspace2D_sptr work_in3 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     Workspace2D_sptr work_in4 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(5);
+        WorkspaceCreationHelper::create1DWorkspaceFib(5);
     Workspace2D_sptr work_in5 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(3);
+        WorkspaceCreationHelper::create1DWorkspaceFib(3);
     Workspace2D_sptr work_in6 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(1);
+        WorkspaceCreationHelper::create1DWorkspaceFib(1);
     BinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
@@ -90,22 +91,22 @@ public:
   void testcheckSizeCompatibility2D1D() {
     // Register the workspace in the data service
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace123(10, 10);
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(20);
+        WorkspaceCreationHelper::create1DWorkspaceFib(20);
     Workspace2D_sptr work_in3 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     Workspace2D_sptr work_in4 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(5);
+        WorkspaceCreationHelper::create1DWorkspaceFib(5);
     Workspace2D_sptr work_in5 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(3);
+        WorkspaceCreationHelper::create1DWorkspaceFib(3);
     Workspace2D_sptr work_in6 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(1);
+        WorkspaceCreationHelper::create1DWorkspaceFib(1);
     MatrixWorkspace_sptr work_inEvent1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 1);
+        WorkspaceCreationHelper::createEventWorkspace(10, 1);
     // will not pass x array does not match
     MatrixWorkspace_sptr work_inEvent2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 10);
+        WorkspaceCreationHelper::createEventWorkspace(1, 10);
     BinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
@@ -120,21 +121,21 @@ public:
 
     // Register the workspace in the data service
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 20);
+        WorkspaceCreationHelper::create2DWorkspace(10, 20);
     Workspace2D_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     Workspace2D_sptr work_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace(5, 5);
+        WorkspaceCreationHelper::create2DWorkspace(5, 5);
     Workspace2D_sptr work_in5 =
-        WorkspaceCreationHelper::Create2DWorkspace(3, 3);
+        WorkspaceCreationHelper::create2DWorkspace(3, 3);
     Workspace2D_sptr work_in6 =
-        WorkspaceCreationHelper::Create2DWorkspace(100, 1);
+        WorkspaceCreationHelper::create2DWorkspace(100, 1);
     MatrixWorkspace_sptr work_inEvent1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(5, 5);
+        WorkspaceCreationHelper::createEventWorkspace(5, 5);
     MatrixWorkspace_sptr work_inEvent2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace(10, 10);
     BinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
@@ -153,9 +154,9 @@ public:
     masking.insert(4);
 
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins, 0, masking);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins, 0, masking);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     BinaryOpHelper helper;
     helper.initialize();
@@ -174,18 +175,14 @@ public:
     TS_ASSERT(output);
 
     for (int i = 0; i < nHist; ++i) {
-      IDetector_const_sptr det;
-      try {
-        det = output->getDetector(i);
-      } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      }
+      auto &spectrumInfo = output->spectrumInfo();
 
-      TSM_ASSERT("Detector was found", det);
-      if (det) {
+      TSM_ASSERT("Detector was not found", spectrumInfo.hasDetectors(i));
+      if (spectrumInfo.hasDetectors(i)) {
         if (masking.count(i) == 0) {
-          TS_ASSERT_EQUALS(det->isMasked(), false);
+          TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
         } else {
-          TS_ASSERT_EQUALS(det->isMasked(), true);
+          TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
         }
       }
     }
@@ -196,9 +193,9 @@ public:
                                     std::vector<std::vector<int>> rhs,
                                     bool expect_throw = false) {
     EventWorkspace_sptr lhsWS =
-        WorkspaceCreationHelper::CreateGroupedEventWorkspace(lhs, 50, 1.0);
+        WorkspaceCreationHelper::createGroupedEventWorkspace(lhs, 50, 1.0);
     EventWorkspace_sptr rhsWS =
-        WorkspaceCreationHelper::CreateGroupedEventWorkspace(rhs, 50, 1.0);
+        WorkspaceCreationHelper::createGroupedEventWorkspace(rhs, 50, 1.0);
     BinaryOperation::BinaryOperationTable_sptr table;
     Mantid::Kernel::Timer timer1;
     if (expect_throw) {
diff --git a/Framework/Algorithms/test/CalMuonDetectorPhasesTest.h b/Framework/Algorithms/test/CalMuonDetectorPhasesTest.h
index 6f05454434fc3b749bbc497d3123833e5f03c4cc..90a8ee919699685c0cd922d7ac20eb005aa54df7 100644
--- a/Framework/Algorithms/test/CalMuonDetectorPhasesTest.h
+++ b/Framework/Algorithms/test/CalMuonDetectorPhasesTest.h
@@ -11,6 +11,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/cow_ptr.h"
 #include "MantidKernel/PhysicalConstants.h"
diff --git a/Framework/Algorithms/test/CalculateDIFCTest.h b/Framework/Algorithms/test/CalculateDIFCTest.h
index eb3c64acafa62a1f34d6173bb51c9e2c7baa710a..d682a124cdfbb1f2c73904cabb73ba2acc4912da 100644
--- a/Framework/Algorithms/test/CalculateDIFCTest.h
+++ b/Framework/Algorithms/test/CalculateDIFCTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/CalculateDIFC.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using Mantid::Algorithms::CalculateDIFC;
@@ -81,9 +82,10 @@ public:
 
     auto offsetsWS =
         OffsetsWorkspace_sptr(new OffsetsWorkspace(inputWS->getInstrument()));
+    const auto &spectrumInfo = offsetsWS->spectrumInfo();
     for (int i = 0; i < NUM_SPEC; ++i) {
-      IDetector_const_sptr det = inputWS->getDetector(i);
-      offsetsWS->setValue(det->getID(), OFFSET);
+      const auto &det = spectrumInfo.detector(i);
+      offsetsWS->setValue(det.getID(), OFFSET);
     }
 
     runTest(inputWS, offsetsWS, outWSName);
diff --git a/Framework/Algorithms/test/CalculateEfficiencyTest.h b/Framework/Algorithms/test/CalculateEfficiencyTest.h
index f6767c9025900ee05aba770971dfd401ffa96855..7e9be018df3e451807d5c2dedb5f1da77d890501 100644
--- a/Framework/Algorithms/test/CalculateEfficiencyTest.h
+++ b/Framework/Algorithms/test/CalculateEfficiencyTest.h
@@ -1,7 +1,9 @@
 #ifndef CALCULATEEFFICIENCYTEST_H_
 #define CALCULATEEFFICIENCYTEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAlgorithms/CalculateEfficiency.h"
 #include "MantidDataHandling/LoadSpice2D.h"
 #include "MantidDataHandling/MoveInstrumentComponent.h"
@@ -99,12 +101,9 @@ public:
                     0.4502, tolerance);
 
     // Check that pixels that were out of range were masked
-    TS_ASSERT(
-        !ws2d_out->getDetector(5 + SANSInstrumentCreationHelper::nMonitors)
-             ->isMasked())
-    TS_ASSERT(
-        !ws2d_out->getDetector(1 + SANSInstrumentCreationHelper::nMonitors)
-             ->isMasked())
+    const auto &oSpecInfo = ws2d_out->spectrumInfo();
+    TS_ASSERT(!oSpecInfo.isMasked(5 + SANSInstrumentCreationHelper::nMonitors));
+    TS_ASSERT(!oSpecInfo.isMasked(1 + SANSInstrumentCreationHelper::nMonitors));
 
     // Repeat the calculation by excluding high/low pixels
 
@@ -144,11 +143,10 @@ public:
                     0.5002, tolerance);
 
     // Check that pixels that were out of range were masked
-    TS_ASSERT(ws2d_out->getDetector(5 + SANSInstrumentCreationHelper::nMonitors)
-                  ->isMasked())
+    const auto &oSpecInfo2 = ws2d_out->spectrumInfo();
+    TS_ASSERT(oSpecInfo2.isMasked(5 + SANSInstrumentCreationHelper::nMonitors));
     TS_ASSERT(
-        !ws2d_out->getDetector(1 + SANSInstrumentCreationHelper::nMonitors)
-             ->isMasked())
+        !oSpecInfo2.isMasked(1 + SANSInstrumentCreationHelper::nMonitors));
 
     Mantid::API::AnalysisDataService::Instance().remove(inputWS);
     Mantid::API::AnalysisDataService::Instance().remove(outputWS);
@@ -231,9 +229,10 @@ public:
     TS_ASSERT_DELTA(ws2d_out->e(6 + nmon)[0], 0.105261, tolerance);
 
     // Check that pixels that were out of range were masked
-    TS_ASSERT(ws2d_out->getDetector(1826)->isMasked())
-    TS_ASSERT(ws2d_out->getDetector(2014)->isMasked())
-    TS_ASSERT(ws2d_out->getDetector(2015)->isMasked())
+    const auto &oSpecInfo = ws2d_out->spectrumInfo();
+    TS_ASSERT(oSpecInfo.isMasked(1826));
+    TS_ASSERT(oSpecInfo.isMasked(2014));
+    TS_ASSERT(oSpecInfo.isMasked(2015));
 
     Mantid::API::AnalysisDataService::Instance().remove(inputWS);
     Mantid::API::AnalysisDataService::Instance().remove(outputWS);
diff --git a/Framework/Algorithms/test/CalculateFlatBackgroundTest.h b/Framework/Algorithms/test/CalculateFlatBackgroundTest.h
index d1d9dd843d9d536c52876678fcdb3bd753e09603..8c7ea949d6c22f8cc015381dae83d6b073a191f6 100644
--- a/Framework/Algorithms/test/CalculateFlatBackgroundTest.h
+++ b/Framework/Algorithms/test/CalculateFlatBackgroundTest.h
@@ -4,6 +4,7 @@
 #include "MantidAlgorithms/CalculateFlatBackground.h"
 #include "MantidAlgorithms/CompareWorkspaces.h"
 #include "MantidAlgorithms/Minus.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidDataObjects/Workspace2D.h"
@@ -679,7 +680,6 @@ private:
         new Geometry::Instrument("testInst"));
     // testInst->setReferenceFrame(boost::shared_ptr<Geometry::ReferenceFrame>(new
     // Geometry::ReferenceFrame(Geometry::PointingAlong::Y,Geometry::X,Geometry::Left,"")));
-    WS->setInstrument(testInst);
 
     const double pixelRadius(0.05);
     Geometry::Object_sptr pixelShape =
@@ -699,6 +699,7 @@ private:
       testInst->markAsMonitor(physicalPixel);
       WS->getSpectrum(i).addDetectorID(physicalPixel->getID());
     }
+    WS->setInstrument(testInst);
   }
 
   /// Creates a  workspace with a single special value in each spectrum.
diff --git a/Framework/Algorithms/test/CalculateResolutionTest.h b/Framework/Algorithms/test/CalculateResolutionTest.h
index edfda09c925f9de8d31b69f69e1eea91f0c51728..59983ec67fae22d4207dbf4c4055511b97afc77b 100644
--- a/Framework/Algorithms/test/CalculateResolutionTest.h
+++ b/Framework/Algorithms/test/CalculateResolutionTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/CalculateResolution.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidKernel/V3D.h"
diff --git a/Framework/Algorithms/test/CalculateSlitsTest.h b/Framework/Algorithms/test/CalculateSlitsTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..d094923db0917381b87943e934d36d525541c566
--- /dev/null
+++ b/Framework/Algorithms/test/CalculateSlitsTest.h
@@ -0,0 +1,115 @@
+#ifndef CALCULATESLITSTEST_H_
+#define CALCULATESLITSTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidAlgorithms/CalculateSlits.h"
+
+using namespace Mantid::Algorithms;
+
+namespace {
+double roundFour(double i) { return floor(i * 10000 + 0.5) / 10000; }
+}
+
+class CalculateSlitsTest : public CxxTest::TestSuite {
+public:
+  void testSensibleArgs() {
+    CalculateSlits alg;
+    alg.initialize();
+    alg.setProperty("Slit1Slit2", 1940.5);
+    alg.setProperty("Slit2SA", 364.);
+    alg.setProperty("Angle", 0.7);
+    alg.setProperty("Footprint", 50.);
+    alg.setProperty("Resolution", 0.03);
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    // truncate the output values to 4 decimal places to eliminate
+    // insignificant error
+    const double slit1 = roundFour(alg.getProperty("Slit1"));
+    TS_ASSERT_EQUALS(slit1, 1.0784);
+
+    const double slit2 = roundFour(alg.getProperty("Slit2"));
+    TS_ASSERT_EQUALS(slit2, 0.3440);
+  }
+
+  void testWithNegativeAngle() {
+    CalculateSlits alg;
+    alg.initialize();
+    alg.setProperty("Slit1Slit2", 1940.5);
+    alg.setProperty("Slit2SA", 364.);
+    alg.setProperty("Angle", -0.7);
+    alg.setProperty("Footprint", 50.);
+    alg.setProperty("Resolution", 0.03);
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    // truncate the output values to 4 decimal places to eliminate
+    // insignificant error
+    const double slit1 = roundFour(alg.getProperty("Slit1"));
+    TS_ASSERT_EQUALS(slit1, -1.0784);
+
+    const double slit2 = roundFour(alg.getProperty("Slit2"));
+    TS_ASSERT_EQUALS(slit2, -0.3440);
+  }
+
+  void testWithZeroAngle() {
+    CalculateSlits alg;
+    alg.initialize();
+    alg.setProperty("Slit1Slit2", 1940.5);
+    alg.setProperty("Slit2SA", 364.);
+    alg.setProperty("Angle", 0.);
+    alg.setProperty("Footprint", 50.);
+    alg.setProperty("Resolution", 0.03);
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    const double slit1 = alg.getProperty("Slit1");
+    TS_ASSERT_EQUALS(slit1, 0.0);
+
+    const double slit2 = alg.getProperty("Slit2");
+    TS_ASSERT_EQUALS(slit2, 0.0);
+  }
+
+  void testWithNanAndInf() {
+    const double nan = std::numeric_limits<double>::quiet_NaN();
+    const double inf = std::numeric_limits<double>::infinity();
+    const double ninf = -inf;
+
+    CalculateSlits alg;
+    alg.initialize();
+    alg.setProperty("Slit1Slit2", nan);
+    alg.setProperty("Slit2SA", nan);
+    alg.setProperty("Angle", inf);
+    alg.setProperty("Footprint", inf);
+    alg.setProperty("Resolution", ninf);
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    const double slit1 = alg.getProperty("Slit1");
+    TS_ASSERT(std::isnan(slit1));
+
+    const double slit2 = alg.getProperty("Slit2");
+    TS_ASSERT(std::isnan(slit2));
+  }
+
+  void testWithNoArgs() {
+    CalculateSlits alg;
+    alg.initialize();
+
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    const double slit1 = alg.getProperty("Slit1");
+    TS_ASSERT(std::isnan(slit1));
+
+    const double slit2 = alg.getProperty("Slit2");
+    TS_ASSERT(std::isnan(slit2));
+  }
+};
+
+#endif /*CALCULATESLITSTEST_H_*/
diff --git a/Framework/Algorithms/test/CalculateTransmissionBeamSpreaderTest.h b/Framework/Algorithms/test/CalculateTransmissionBeamSpreaderTest.h
index 611b767c97228eeb71f76297cc6a1847c4d258b0..e19b0356af2d9baf7b1324c371fe6ab8c3f2ee3d 100644
--- a/Framework/Algorithms/test/CalculateTransmissionBeamSpreaderTest.h
+++ b/Framework/Algorithms/test/CalculateTransmissionBeamSpreaderTest.h
@@ -8,6 +8,7 @@
 #include "MantidAlgorithms/CropWorkspace.h"
 #include "MantidDataHandling/LoadInstrument.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidTestHelpers/SANSInstrumentCreationHelper.h"
 
 using namespace Mantid::API;
diff --git a/Framework/Algorithms/test/CalculateZscoreTest.h b/Framework/Algorithms/test/CalculateZscoreTest.h
index 4fe2ffb7b8f7e3104be32b545623dfcc6cfd88d6..c2915b77b9e9719bdbe6dfdafe3d5ff0561b312f 100644
--- a/Framework/Algorithms/test/CalculateZscoreTest.h
+++ b/Framework/Algorithms/test/CalculateZscoreTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAlgorithms/CalculateZscore.h"
diff --git a/Framework/Algorithms/test/ChainedOperatorTest.h b/Framework/Algorithms/test/ChainedOperatorTest.h
index 9a603d282b2e71a63e62b140dabdcc0da4a9a38e..a9c9142cbf1ee6dd8ec34c05095f17de89c62301 100644
--- a/Framework/Algorithms/test/ChainedOperatorTest.h
+++ b/Framework/Algorithms/test/ChainedOperatorTest.h
@@ -48,9 +48,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     performTest(work_in1, work_in2);
   }
@@ -59,9 +59,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(nHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(nHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(nHist, nBins);
 
     performTest(work_in1, work_in2);
   }
diff --git a/Framework/Algorithms/test/ChangeBinOffsetTest.h b/Framework/Algorithms/test/ChangeBinOffsetTest.h
index fd043ebe9fb13ac8c4885d4e16cc0ec9d6530974..af9c2b3684c89c83b6efe1b67b57f053364c8a04 100644
--- a/Framework/Algorithms/test/ChangeBinOffsetTest.h
+++ b/Framework/Algorithms/test/ChangeBinOffsetTest.h
@@ -179,9 +179,9 @@ public:
   }
 
   ChangeBinOffsetTestPerformance() {
-    input = WorkspaceCreationHelper::Create2DWorkspaceBinned(10000, 1000);
+    input = WorkspaceCreationHelper::create2DWorkspaceBinned(10000, 1000);
     inputEvent =
-        WorkspaceCreationHelper::CreateEventWorkspace(10000, 1000, 5000);
+        WorkspaceCreationHelper::createEventWorkspace(10000, 1000, 5000);
   }
 
   void testExec2D() {
diff --git a/Framework/Algorithms/test/ChangeLogTimeTest.h b/Framework/Algorithms/test/ChangeLogTimeTest.h
index f34bfe66876c7d9b08bf139e4348119c0c0ee5f4..77451ab8b5e1a67a1c70945118b7237275f7f44f 100644
--- a/Framework/Algorithms/test/ChangeLogTimeTest.h
+++ b/Framework/Algorithms/test/ChangeLogTimeTest.h
@@ -5,6 +5,7 @@
 #include "MantidAlgorithms/ChangeLogTime.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 
 using std::string;
diff --git a/Framework/Algorithms/test/ChangePulsetimeTest.h b/Framework/Algorithms/test/ChangePulsetimeTest.h
index a3892cc950cf7b2c49658ea7cf175934e4a48c1c..a28318b755f86edf7ad9f51ca08d072b940d2061 100644
--- a/Framework/Algorithms/test/ChangePulsetimeTest.h
+++ b/Framework/Algorithms/test/ChangePulsetimeTest.h
@@ -53,7 +53,7 @@ public:
     TS_ASSERT(alg.isInitialized())
 
     EventWorkspace_sptr in_ws, out_ws;
-    in_ws = WorkspaceCreationHelper::CreateEventWorkspace2(100, 100);
+    in_ws = WorkspaceCreationHelper::createEventWorkspace2(100, 100);
     AnalysisDataService::Instance().addOrReplace(in_ws_name, in_ws);
 
     alg.setPropertyValue("InputWorkspace", in_ws_name);
@@ -136,7 +136,7 @@ private:
 public:
   void setUp() override {
     EventWorkspace_sptr in_ws =
-        WorkspaceCreationHelper::CreateEventWorkspace2(30000, 30000);
+        WorkspaceCreationHelper::createEventWorkspace2(30000, 30000);
     m_workspace = in_ws;
   }
 
diff --git a/Framework/Algorithms/test/ChangeTimeZeroTest.h b/Framework/Algorithms/test/ChangeTimeZeroTest.h
index cff58f6fa4f61e1050c53eabe8d8228133944824..c5d103f8cf39e3c2406e103a6d8b9f6640e2c9d7 100644
--- a/Framework/Algorithms/test/ChangeTimeZeroTest.h
+++ b/Framework/Algorithms/test/ChangeTimeZeroTest.h
@@ -12,6 +12,7 @@
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/DateTimeValidator.h"
 
 using namespace Mantid::Kernel;
@@ -111,7 +112,7 @@ Mantid::API::MatrixWorkspace_sptr provideWorkspace2D(LogType logType,
 Mantid::API::MatrixWorkspace_sptr
 provideWorkspaceSingleValue(LogType logType, DateAndTime startTime,
                             int length) {
-  auto ws = WorkspaceCreationHelper::CreateWorkspaceSingleValue(10);
+  auto ws = WorkspaceCreationHelper::createWorkspaceSingleValue(10);
   // Add the logs
   provideLogs(logType, ws, startTime, length);
   return ws;
@@ -121,7 +122,7 @@ provideWorkspaceSingleValue(LogType logType, DateAndTime startTime,
 Mantid::API::MatrixWorkspace_sptr
 provideEventWorkspaceCustom(LogType logType, DateAndTime startTime, int length,
                             int pixels, int bins, int events) {
-  auto ws = WorkspaceCreationHelper::CreateEventWorkspaceWithStartTime(
+  auto ws = WorkspaceCreationHelper::createEventWorkspaceWithStartTime(
       pixels, bins, events, 0.0, 1.0, 2, 0, startTime);
   // Add the logs
   provideLogs(logType, ws, startTime, length);
diff --git a/Framework/Algorithms/test/CheckWorkspacesMatchTest.h b/Framework/Algorithms/test/CheckWorkspacesMatchTest.h
index fe6f7fb6dbcfdc8f378feb7f7c4d1f281315806e..13c1715feb4192e1cdf1fca04bf88aa73f798ce8 100644
--- a/Framework/Algorithms/test/CheckWorkspacesMatchTest.h
+++ b/Framework/Algorithms/test/CheckWorkspacesMatchTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
@@ -35,7 +36,7 @@ public:
   static void destroySuite(CheckWorkspacesMatchTest *suite) { delete suite; }
 
   CheckWorkspacesMatchTest()
-      : ws1(WorkspaceCreationHelper::Create2DWorkspace123(2, 2)) {
+      : ws1(WorkspaceCreationHelper::create2DWorkspace123(2, 2)) {
     FrameworkManager::Instance();
   }
 
@@ -53,7 +54,7 @@ public:
       checker.initialize();
 
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 100);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 100);
     // A workspace had better match itself!
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws));
@@ -172,9 +173,9 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -192,7 +193,7 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace2", boost::dynamic_pointer_cast<MatrixWorkspace>(ews2)));
@@ -209,9 +210,9 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(15, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(15, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -227,9 +228,9 @@ public:
     if (!checker.isInitialized())
       checker.initialize();
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 0.0, 1.0, 2);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 0.0, 1.0, 2);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -245,9 +246,9 @@ public:
     if (!checker.isInitialized())
       checker.initialize();
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 15.0, 10.0);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 15.0, 10.0);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 5.0, 10.0);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 5.0, 10.0);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -542,7 +543,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(2);
+        WorkspaceCreationHelper::create1DWorkspaceFib(2);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -559,7 +560,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2, true);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2, true);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -577,7 +578,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->setDistribution(true);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -596,7 +597,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::API::Axis *const newAxis = new Mantid::API::NumericAxis(2);
     ws2->replaceAxis(1, newAxis);
 
@@ -616,7 +617,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getAxis(0)->title() = "blah";
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -635,7 +636,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
 
@@ -654,9 +655,9 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws1local =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     // Put numeric axes on these workspaces as checkAxes won't test values on
     // spectra axes
     Axis *newAxisWS1 = new NumericAxis(ws1local->getAxis(1)->length());
@@ -689,7 +690,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->setYUnit("blah");
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -706,7 +707,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getSpectrum(0).setSpectrumNo(1234);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -714,7 +715,7 @@ public:
     TS_ASSERT_EQUALS(checker.getPropertyValue("Result"),
                      "Spectrum number mismatch");
 
-    ws2 = WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+    ws2 = WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getSpectrum(0).setDetectorID(99);
     ws2->getSpectrum(1).setDetectorID(98);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -732,7 +733,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::Geometry::Instrument_sptr instrument(
         new Mantid::Geometry::Instrument("different"));
     ws2->setInstrument(instrument);
@@ -752,7 +753,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->instrumentParameters().addBool(new Mantid::Geometry::Component,
                                         "myParam", true);
 
@@ -772,7 +773,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->maskBin(0, 0);
     ws2->dataY(0)[0] = 2;
     ws2->dataE(0)[0] = 3;
@@ -784,7 +785,7 @@ public:
     TS_ASSERT_EQUALS(checker.getPropertyValue("Result"), "Masking mismatch");
 
     Mantid::API::MatrixWorkspace_sptr ws3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws3->maskBin(0, 1);
     ws3->dataY(0)[1] = 2;
     ws3->dataE(0)[1] = 3;
@@ -804,7 +805,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableSample().setName("different");
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -821,7 +822,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableRun().setProtonCharge(99.99);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -838,7 +839,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop1", 99));
 
@@ -850,7 +851,7 @@ public:
                      "Different numbers of logs");
 
     Mantid::API::MatrixWorkspace_sptr ws3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws3->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop2", 99));
 
@@ -861,7 +862,7 @@ public:
     TS_ASSERT_EQUALS(checker.getPropertyValue("Result"), "Log mismatch");
 
     Mantid::API::MatrixWorkspace_sptr ws4 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws4->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop1", 100));
 
@@ -876,7 +877,7 @@ public:
     // Create a group
     const std::string groupName("TestGroup");
     WorkspaceGroup_sptr group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupName);
 
     doGroupTest(groupName, groupName,
                 Mantid::Algorithms::CheckWorkspacesMatch::successString());
@@ -888,10 +889,10 @@ public:
     // Create a group
     const std::string groupOneName("TestGroupOne");
     WorkspaceGroup_sptr groupOne =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupOneName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupOneName);
     const std::string groupTwoName("TestGroupTwo");
     WorkspaceGroup_sptr groupTwo =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(3, 2, 2, groupTwoName);
+        WorkspaceCreationHelper::createWorkspaceGroup(3, 2, 2, groupTwoName);
 
     doGroupTest(groupOneName, groupTwoName, "GroupWorkspaces size mismatch.",
                 std::map<std::string, std::string>(), true);
@@ -903,9 +904,9 @@ public:
   void test_Input_With_A_Group_And_A_Single_Workspace_Gives_Type_Mismatch() {
     const std::string groupName("CheckWorkspacesMatch_TestGroup");
     WorkspaceGroup_sptr group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupName);
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     const std::string wsName("CheckWorkspacesMatch_TestWS");
     Mantid::API::AnalysisDataService::Instance().add(wsName, ws2);
 
@@ -922,10 +923,10 @@ public:
     // Create a group
     const std::string groupOneName("TestGroupOne");
     WorkspaceGroup_sptr groupOne =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupOneName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupOneName);
     const std::string groupTwoName("TestGroupTwo");
     WorkspaceGroup_sptr groupTwo =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupTwoName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupTwoName);
     Mantid::API::AnalysisDataServiceImpl &dataStore =
         Mantid::API::AnalysisDataService::Instance();
     // Extract the zeroth element of groupTwo and add a spurious log
diff --git a/Framework/Algorithms/test/ChopDataTest.h b/Framework/Algorithms/test/ChopDataTest.h
index 0cf6b1fff3bc6d38d02257b0e36a6c5bffb9d774..879d67a5c15c972c5fa381564b434ee3f3cee221 100644
--- a/Framework/Algorithms/test/ChopDataTest.h
+++ b/Framework/Algorithms/test/ChopDataTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/ChopData.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using namespace Mantid::API;
@@ -28,7 +29,7 @@ public:
 
   void testExec() {
     Mantid::DataObjects::Workspace2D_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(149, 24974, 5, 4);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(149, 24974, 5, 4);
 
     for (int i = 0; i < 4995; i++) {
       inputWS->mutableX(140)[i + 19980] = 0.2;
diff --git a/Framework/Algorithms/test/ClearMaskFlagTest.h b/Framework/Algorithms/test/ClearMaskFlagTest.h
index dc75fa6ff4239f0f03f7262b8ce8a345a99cc34f..91afa209f332d6a04ee56463401054745eb4d617 100644
--- a/Framework/Algorithms/test/ClearMaskFlagTest.h
+++ b/Framework/Algorithms/test/ClearMaskFlagTest.h
@@ -4,6 +4,8 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidAlgorithms/ClearMaskFlag.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
@@ -57,9 +59,9 @@ public:
     space2D->setInstrument(instr);
 
     // set the mask on a bunch of spectra
-    Mantid::Geometry::ParameterMap &pmap = space2D->instrumentParameters();
+    auto &detectorInfo = space2D->mutableDetectorInfo();
     for (int j = 0; j < nummask; ++j) {
-      pmap.addBool(instr->getDetector(j)->getComponentID(), "masked", true);
+      detectorInfo.setMasked(j, true);
     }
 
     // register the workspace in the data service
@@ -84,9 +86,9 @@ public:
       return;
 
     // check the results
-    Instrument_const_sptr out_instr = ws->getInstrument();
+    const auto &resultDetInfo = ws->detectorInfo();
     for (int j = 0; j < numspec; ++j) {
-      TS_ASSERT(!out_instr->isDetectorMasked(j));
+      TS_ASSERT(!resultDetInfo.isMasked(j));
     }
 
     // remove workspace from the data service.
diff --git a/Framework/Algorithms/test/CloneWorkspaceTest.h b/Framework/Algorithms/test/CloneWorkspaceTest.h
index c35f470f9f48995bc3f8b51d3997f4e332f5334d..75d07e833f972aad8aae269bb92af5b24c886fd8 100644
--- a/Framework/Algorithms/test/CloneWorkspaceTest.h
+++ b/Framework/Algorithms/test/CloneWorkspaceTest.h
@@ -10,6 +10,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidGeometry/Instrument.h"
@@ -84,7 +85,7 @@ public:
   void testExecEvent() {
     // First make the algorithm
     EventWorkspace_sptr ew =
-        WorkspaceCreationHelper::CreateEventWorkspace(100, 60, 50);
+        WorkspaceCreationHelper::createEventWorkspace(100, 60, 50);
     AnalysisDataService::Instance().addOrReplace("in_event", ew);
 
     Mantid::Algorithms::CloneWorkspace alg;
@@ -147,7 +148,7 @@ public:
 
   void test_group() {
     WorkspaceGroup_const_sptr ingroup =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(3, 1, 1, "grouptoclone");
+        WorkspaceCreationHelper::createWorkspaceGroup(3, 1, 1, "grouptoclone");
     Mantid::Algorithms::CloneWorkspace alg;
     alg.initialize();
     alg.setPropertyValue("InputWorkspace", "grouptoclone");
diff --git a/Framework/Algorithms/test/CommentTest.h b/Framework/Algorithms/test/CommentTest.h
index 22c846ada84473c034352a8cbd2d5fd71d21f00b..d05d80021f7b19e88515c420fd1cdb099f562a5e 100644
--- a/Framework/Algorithms/test/CommentTest.h
+++ b/Framework/Algorithms/test/CommentTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/Comment.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using namespace Mantid::API;
@@ -25,10 +26,10 @@ public:
   void test_exec() {
     std::string wsName = "CommentTest_Exec_workspace";
     // Create test input
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add(wsName, ws);
     // and an identical ws for comparison later
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     Mantid::Algorithms::Comment alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize())
@@ -61,4 +62,4 @@ public:
   }
 };
 
-#endif /* MANTID_ALGORITHMS_COMMENTTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_COMMENTTEST_H_ */
diff --git a/Framework/Algorithms/test/CommutativeBinaryOperationTest.h b/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
index 7392a6af03789fe5cc97c7a65bf337580e1de596..d0321893aa53fc1f45493f4c8d5de064763deeb2 100644
--- a/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
+++ b/Framework/Algorithms/test/CommutativeBinaryOperationTest.h
@@ -72,17 +72,17 @@ public:
   void testcheckSizeCompatibility1D1D() {
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(20);
+        WorkspaceCreationHelper::create1DWorkspaceFib(20);
     MatrixWorkspace_sptr work_in3 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     MatrixWorkspace_sptr work_in4 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(5);
+        WorkspaceCreationHelper::create1DWorkspaceFib(5);
     MatrixWorkspace_sptr work_in5 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(3);
+        WorkspaceCreationHelper::create1DWorkspaceFib(3);
     MatrixWorkspace_sptr work_in6 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(1);
+        WorkspaceCreationHelper::create1DWorkspaceFib(1);
     CommutativeBinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
@@ -94,21 +94,21 @@ public:
   void testcheckSizeCompatibility2D1D() {
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace123(10, 10);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(20);
+        WorkspaceCreationHelper::create1DWorkspaceFib(20);
     MatrixWorkspace_sptr work_in3 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(10);
+        WorkspaceCreationHelper::create1DWorkspaceFib(10);
     MatrixWorkspace_sptr work_in4 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(5);
+        WorkspaceCreationHelper::create1DWorkspaceFib(5);
     MatrixWorkspace_sptr work_in5 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(3);
+        WorkspaceCreationHelper::create1DWorkspaceFib(3);
     MatrixWorkspace_sptr work_in6 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(1);
+        WorkspaceCreationHelper::create1DWorkspaceFib(1);
     MatrixWorkspace_sptr work_event1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 1);
+        WorkspaceCreationHelper::createEventWorkspace(10, 1);
     MatrixWorkspace_sptr work_event2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 10);
+        WorkspaceCreationHelper::createEventWorkspace(1, 10);
     CommutativeBinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
@@ -123,23 +123,23 @@ public:
   void testcheckSizeCompatibility2D2D() {
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 20);
+        WorkspaceCreationHelper::create2DWorkspace(10, 20);
     MatrixWorkspace_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr work_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace(5, 5);
+        WorkspaceCreationHelper::create2DWorkspace(5, 5);
     MatrixWorkspace_sptr work_in5 =
-        WorkspaceCreationHelper::Create2DWorkspace(3, 3);
+        WorkspaceCreationHelper::create2DWorkspace(3, 3);
     MatrixWorkspace_sptr work_in6 =
-        WorkspaceCreationHelper::Create2DWorkspace(100, 1);
+        WorkspaceCreationHelper::create2DWorkspace(100, 1);
     MatrixWorkspace_sptr work_in7 =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(10.0);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(10.0);
     MatrixWorkspace_sptr work_event1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 1);
+        WorkspaceCreationHelper::createEventWorkspace(10, 1);
     MatrixWorkspace_sptr work_event2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace(10, 10);
     CommutativeBinaryOpHelper helper;
     TS_ASSERT(!helper.checkSizeCompatibility(work_in1, work_in2).empty());
     TS_ASSERT(helper.checkSizeCompatibility(work_in1, work_in3).empty());
diff --git a/Framework/Algorithms/test/CompareWorkspacesTest.h b/Framework/Algorithms/test/CompareWorkspacesTest.h
index 3f04aae3798099f3eee2763416b767f4e0657f22..9ef855e597fa2e0033fd191ad691bdc003c24cfb 100644
--- a/Framework/Algorithms/test/CompareWorkspacesTest.h
+++ b/Framework/Algorithms/test/CompareWorkspacesTest.h
@@ -9,6 +9,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/MDBoxBase.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
@@ -35,7 +36,7 @@ public:
   static void destroySuite(CompareWorkspacesTest *suite) { delete suite; }
 
   CompareWorkspacesTest()
-      : ws1(WorkspaceCreationHelper::Create2DWorkspace123(2, 2)),
+      : ws1(WorkspaceCreationHelper::create2DWorkspace123(2, 2)),
         PROPERTY_VALUE_TRUE("1") {
     FrameworkManager::Instance();
   }
@@ -54,7 +55,7 @@ public:
       checker.initialize();
 
     Workspace2D_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 100);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 100);
     // A workspace had better match itself!
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws));
@@ -170,9 +171,9 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -189,7 +190,7 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace2", boost::dynamic_pointer_cast<MatrixWorkspace>(ews2)));
@@ -205,9 +206,9 @@ public:
       checker.initialize();
 
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(15, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(15, 20, 30);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -222,9 +223,9 @@ public:
     if (!checker.isInitialized())
       checker.initialize();
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 0.0, 1.0, 2);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 0.0, 1.0, 2);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -239,9 +240,9 @@ public:
     if (!checker.isInitialized())
       checker.initialize();
     EventWorkspace_sptr ews1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 15.0, 10.0);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 15.0, 10.0);
     EventWorkspace_sptr ews2 =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 20, 30, 5.0, 10.0);
+        WorkspaceCreationHelper::createEventWorkspace(10, 20, 30, 5.0, 10.0);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
         "Workspace1", boost::dynamic_pointer_cast<MatrixWorkspace>(ews1)));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty(
@@ -520,7 +521,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(2);
+        WorkspaceCreationHelper::create1DWorkspaceFib(2);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -542,7 +543,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2, true);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2, true);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -565,7 +566,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->setDistribution(true);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -589,7 +590,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::API::Axis *const newAxis = new Mantid::API::NumericAxis(2);
     ws2->replaceAxis(1, newAxis);
 
@@ -613,7 +614,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getAxis(0)->title() = "blah";
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -636,7 +637,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
 
@@ -660,9 +661,9 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws1local =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     // Put numeric axes on these workspaces as checkAxes won't test values on
     // spectra axes
     Axis *newAxisWS1 = new NumericAxis(ws1local->getAxis(1)->length());
@@ -700,7 +701,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->setYUnit("blah");
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -723,7 +724,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getSpectrum(0).setSpectrumNo(1234);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace2", ws2));
@@ -737,7 +738,7 @@ public:
     TS_ASSERT_EQUALS(table->cell<std::string>(0, 0),
                      "Spectrum number mismatch");
 
-    ws2 = WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+    ws2 = WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->getSpectrum(0).setDetectorID(99);
     ws2->getSpectrum(1).setDetectorID(98);
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -759,7 +760,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Mantid::Geometry::Instrument_sptr instrument(
         new Mantid::Geometry::Instrument("different"));
     ws2->setInstrument(instrument);
@@ -785,7 +786,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->instrumentParameters().addBool(new Mantid::Geometry::Component,
                                         "myParam", true);
 
@@ -811,7 +812,7 @@ public:
       checker.initialize();
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->maskBin(0, 0);
     ws2->dataY(0)[0] = 2;
     ws2->dataE(0)[0] = 3;
@@ -828,7 +829,7 @@ public:
     TS_ASSERT_EQUALS(table->cell<std::string>(0, 0), "Masking mismatch");
 
     Mantid::API::MatrixWorkspace_sptr ws3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws3->maskBin(0, 1);
     ws3->dataY(0)[1] = 2;
     ws3->dataE(0)[1] = 3;
@@ -853,7 +854,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableSample().setName("different");
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -874,7 +875,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableRun().setProtonCharge(99.99);
 
     TS_ASSERT_THROWS_NOTHING(checker.setProperty("Workspace1", ws1));
@@ -895,7 +896,7 @@ public:
     checker.setProperty("CheckSample", true);
 
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws2->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop1", 99));
 
@@ -912,7 +913,7 @@ public:
                      "Different numbers of logs");
 
     Mantid::API::MatrixWorkspace_sptr ws3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws3->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop2", 99));
 
@@ -927,7 +928,7 @@ public:
     TS_ASSERT_EQUALS(table->cell<std::string>(0, 0), "Log mismatch");
 
     Mantid::API::MatrixWorkspace_sptr ws4 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     ws4->mutableRun().addLogData(
         new Mantid::Kernel::PropertyWithValue<int>("Prop1", 100));
 
@@ -946,7 +947,7 @@ public:
     // Create a group
     const std::string groupName("TestGroup");
     WorkspaceGroup_sptr group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupName);
 
     doGroupTest(groupName, groupName, PROPERTY_VALUE_TRUE);
 
@@ -957,10 +958,10 @@ public:
     // Create a group
     const std::string groupOneName("TestGroupOne");
     WorkspaceGroup_sptr groupOne =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupOneName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupOneName);
     const std::string groupTwoName("TestGroupTwo");
     WorkspaceGroup_sptr groupTwo =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(3, 2, 2, groupTwoName);
+        WorkspaceCreationHelper::createWorkspaceGroup(3, 2, 2, groupTwoName);
 
     doGroupTest(groupOneName, groupTwoName, "GroupWorkspaces size mismatch.",
                 std::map<std::string, std::string>(), true);
@@ -972,9 +973,9 @@ public:
   void test_Input_With_A_Group_And_A_Single_Workspace_Gives_Type_Mismatch() {
     const std::string groupName("CheckWorkspacesMatch_TestGroup");
     WorkspaceGroup_sptr group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupName);
     Mantid::API::MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     const std::string wsName("CheckWorkspacesMatch_TestWS");
     Mantid::API::AnalysisDataService::Instance().add(wsName, ws2);
 
@@ -991,10 +992,10 @@ public:
     // Create a group
     const std::string groupOneName("TestGroupOne");
     WorkspaceGroup_sptr groupOne =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupOneName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupOneName);
     const std::string groupTwoName("TestGroupTwo");
     WorkspaceGroup_sptr groupTwo =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 2, 2, groupTwoName);
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 2, 2, groupTwoName);
     Mantid::API::AnalysisDataServiceImpl &dataStore =
         Mantid::API::AnalysisDataService::Instance();
     // Extract the zeroth element of groupTwo and add a spurious log
diff --git a/Framework/Algorithms/test/ConjoinWorkspacesTest.h b/Framework/Algorithms/test/ConjoinWorkspacesTest.h
index b4ad9f165c2c39bbb6cd30d3cd41531a44aa8b3b..d4f4a140aeaa1786d561259c60644151b7ae9609 100644
--- a/Framework/Algorithms/test/ConjoinWorkspacesTest.h
+++ b/Framework/Algorithms/test/ConjoinWorkspacesTest.h
@@ -5,6 +5,8 @@
 
 #include "MantidAlgorithms/ConjoinWorkspaces.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataHandling/LoadRaw3.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
@@ -73,8 +75,10 @@ public:
 
     // Mask a spectrum and check it is carried over
     const size_t maskTop(5), maskBottom(10);
-    in1->maskWorkspaceIndex(maskTop);
-    in2->maskWorkspaceIndex(maskBottom);
+    in1->getSpectrum(maskTop).clearData();
+    in2->getSpectrum(maskBottom).clearData();
+    in1->mutableSpectrumInfo().setMasked(maskTop, true);
+    in2->mutableSpectrumInfo().setMasked(maskBottom, true);
 
     // Check it fails if properties haven't been set
     TS_ASSERT_THROWS(conj.execute(), std::runtime_error);
@@ -111,8 +115,9 @@ public:
                      in2->getAxis(1)->spectraNo(2));
 
     // Check masking
-    TS_ASSERT_EQUALS(output->getDetector(maskTop)->isMasked(), true);
-    TS_ASSERT_EQUALS(output->getDetector(10 + maskBottom)->isMasked(), true);
+    const auto &spectrumInfo = output->spectrumInfo();
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(maskTop), true);
+    TS_ASSERT_EQUALS(spectrumInfo.isMasked(10 + maskBottom), true);
 
     // Check that 2nd input workspace no longer exists
     TS_ASSERT_THROWS(AnalysisDataService::Instance().retrieve("bottom"),
@@ -125,7 +130,7 @@ public:
   //----------------------------------------------------------------------------------------------
   void testExecMismatchedWorkspaces() {
     MatrixWorkspace_sptr ews =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace(10, 10);
 
     // Check it fails if input overlap
     ConjoinWorkspaces conj;
@@ -138,7 +143,7 @@ public:
     // Check it fails if mixing event workspaces and workspace 2Ds
     TS_ASSERT_THROWS_NOTHING(conj.setProperty("InputWorkspace1", ews));
     TS_ASSERT_THROWS_NOTHING(conj.setProperty(
-        "InputWorkspace2", WorkspaceCreationHelper::Create2DWorkspace(10, 10)));
+        "InputWorkspace2", WorkspaceCreationHelper::create2DWorkspace(10, 10)));
     conj.execute();
     TS_ASSERT(!conj.isExecuted());
   }
@@ -147,10 +152,10 @@ public:
     MatrixWorkspace_sptr ws1, ws2;
     int numPixels = 10;
     int numBins = 20;
-    ws1 = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins);
+    ws1 = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins);
     const std::string ws1_name = "ConjoinWorkspaces_testDoCheckForOverlap";
     AnalysisDataService::Instance().add(ws1_name, ws1);
-    ws2 = WorkspaceCreationHelper::CreateEventWorkspace(5, numBins);
+    ws2 = WorkspaceCreationHelper::createEventWorkspace(5, numBins);
 
     ConjoinWorkspaces conj;
     conj.initialize();
@@ -196,12 +201,12 @@ public:
     int numBins = 20;
 
     if (event) {
-      ws1 = WorkspaceCreationHelper::CreateEventWorkspace2(
+      ws1 = WorkspaceCreationHelper::createEventWorkspace2(
           10, numBins); // 2 events per bin
-      ws2 = WorkspaceCreationHelper::CreateEventWorkspace2(5, numBins);
+      ws2 = WorkspaceCreationHelper::createEventWorkspace2(5, numBins);
     } else {
-      ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, numBins);
-      ws2 = WorkspaceCreationHelper::Create2DWorkspace(5, numBins);
+      ws1 = WorkspaceCreationHelper::create2DWorkspace(10, numBins);
+      ws2 = WorkspaceCreationHelper::create2DWorkspace(5, numBins);
     }
     AnalysisDataService::Instance().addOrReplace(ws1Name, ws1);
     AnalysisDataService::Instance().addOrReplace(ws2Name, ws2);
diff --git a/Framework/Algorithms/test/ConvertAxesToRealSpaceTest.h b/Framework/Algorithms/test/ConvertAxesToRealSpaceTest.h
index e33d5dbefd8e20299b2ffeb3c2b9c19f2b833e46..fa589f57c06a75e76b776d5db96aebede3a82009 100644
--- a/Framework/Algorithms/test/ConvertAxesToRealSpaceTest.h
+++ b/Framework/Algorithms/test/ConvertAxesToRealSpaceTest.h
@@ -7,6 +7,7 @@
 
 #include "MantidAlgorithms/ConvertAxesToRealSpace.h"
 #include "MantidAPI/Axis.h"
+#include "MantidKernel/Unit.h"
 
 using Mantid::Algorithms::ConvertAxesToRealSpace;
 using namespace Mantid::API;
@@ -103,4 +104,4 @@ public:
   }
 };
 
-#endif /* MANTID_ALGORITHMS_CONVERTAXESTOREALSPACETEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_CONVERTAXESTOREALSPACETEST_H_ */
diff --git a/Framework/Algorithms/test/ConvertAxisByFormulaTest.h b/Framework/Algorithms/test/ConvertAxisByFormulaTest.h
index 479c8f6a49815d56ec6e2b9715a183d4aaf761d4..a25f5de619c632aa136b6393200037618f8d0a34 100644
--- a/Framework/Algorithms/test/ConvertAxisByFormulaTest.h
+++ b/Framework/Algorithms/test/ConvertAxisByFormulaTest.h
@@ -32,7 +32,7 @@ public:
     std::string resultWs = alg.name() + "_testPlusRefAxis_Result";
 
     AnalysisDataService::Instance().add(
-        inputWs, WorkspaceCreationHelper::Create2DWorkspace123(10, 10));
+        inputWs, WorkspaceCreationHelper::create2DWorkspace123(10, 10));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", inputWs));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", resultWs));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Formula", "x+3"));
@@ -89,7 +89,7 @@ public:
     std::string resultWs = alg.name() + "_testSquareXNumeric_Result";
 
     AnalysisDataService::Instance().add(
-        inputWs, WorkspaceCreationHelper::Create2DWorkspace123(10, 10));
+        inputWs, WorkspaceCreationHelper::create2DWorkspace123(10, 10));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", inputWs));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", resultWs));
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("Formula", "(X+2)*(x+2)"));
diff --git a/Framework/Algorithms/test/ConvertDiffCalTest.h b/Framework/Algorithms/test/ConvertDiffCalTest.h
index 9216fb96d27f36c37834573e152172ccf27e503b..1f90cf1c58bde101acc622429b58d85a19464481 100644
--- a/Framework/Algorithms/test/ConvertDiffCalTest.h
+++ b/Framework/Algorithms/test/ConvertDiffCalTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAlgorithms/ConvertDiffCal.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
diff --git a/Framework/Algorithms/test/ConvertFromDistributionTest.h b/Framework/Algorithms/test/ConvertFromDistributionTest.h
index a9073b090f020ae4cff92a7938850e38c75d761a..2ac426811e2ecab03c43de36981d061a55a1cbfe 100644
--- a/Framework/Algorithms/test/ConvertFromDistributionTest.h
+++ b/Framework/Algorithms/test/ConvertFromDistributionTest.h
@@ -19,7 +19,7 @@ public:
 
   ConvertFromDistributionTest() : dist("dist") {
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 10, 0, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 10, 0, 0.5);
     WS->setDistribution(true);
     AnalysisDataService::Instance().add(dist, WS);
   }
diff --git a/Framework/Algorithms/test/ConvertSpectrumAxis2Test.h b/Framework/Algorithms/test/ConvertSpectrumAxis2Test.h
index 6c039474a51e4224b766f6db5d34329bba8ee07c..b928b67c8e18ffa0477d9e3e29705c27282feda9 100644
--- a/Framework/Algorithms/test/ConvertSpectrumAxis2Test.h
+++ b/Framework/Algorithms/test/ConvertSpectrumAxis2Test.h
@@ -8,6 +8,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
 using namespace Mantid::API;
@@ -391,4 +392,33 @@ public:
   }
 };
 
+class ConvertSpectrumAxis2TestPerformance : public CxxTest::TestSuite {
+public:
+  static ConvertSpectrumAxis2TestPerformance *createSuite() {
+    return new ConvertSpectrumAxis2TestPerformance();
+  }
+  static void destroySuite(ConvertSpectrumAxis2TestPerformance *suite) {
+    delete suite;
+  }
+
+  ConvertSpectrumAxis2TestPerformance() {
+    m_testWS = WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(
+        20000, 20000);
+  }
+
+  void test_conversion_to_signed_theta_with_many_entries() {
+    Mantid::Algorithms::ConvertSpectrumAxis2 conv;
+    conv.initialize();
+    conv.setChild(true);
+    conv.setProperty("InputWorkspace", m_testWS);
+    conv.setPropertyValue("OutputWorkspace", "outputWS");
+    conv.setPropertyValue("Target", "SignedTheta");
+    conv.setPropertyValue("EFixed", "10.0");
+    conv.execute();
+  }
+
+private:
+  MatrixWorkspace_sptr m_testWS;
+};
+
 #endif /*CONVERTSPECTRUMAXIS2TEST_H_*/
diff --git a/Framework/Algorithms/test/ConvertSpectrumAxisTest.h b/Framework/Algorithms/test/ConvertSpectrumAxisTest.h
index fe5040c56b4bf012b15be59f85f3c6cd18574156..d117c0394f8a7c00c0c5a65c305dc9c381a269f5 100644
--- a/Framework/Algorithms/test/ConvertSpectrumAxisTest.h
+++ b/Framework/Algorithms/test/ConvertSpectrumAxisTest.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAlgorithms/ConvertSpectrumAxis.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidKernel/Unit.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidTestHelpers/HistogramDataTestHelper.h"
 #include <cxxtest/TestSuite.h>
diff --git a/Framework/Algorithms/test/ConvertTableToMatrixWorkspaceTest.h b/Framework/Algorithms/test/ConvertTableToMatrixWorkspaceTest.h
index 439af30c7ded2f70affc42c0756ce470d77a2768..788bf97cdf846ccfd28c3ff392a0bc2c73037aba 100644
--- a/Framework/Algorithms/test/ConvertTableToMatrixWorkspaceTest.h
+++ b/Framework/Algorithms/test/ConvertTableToMatrixWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/ConvertTableToMatrixWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
diff --git a/Framework/Algorithms/test/ConvertToDistributionTest.h b/Framework/Algorithms/test/ConvertToDistributionTest.h
index 73aed2000b1c094bc46e2036c5f4e01c2600adcd..ee31b3754e632d643012bbaf91b82cc202053ed1 100644
--- a/Framework/Algorithms/test/ConvertToDistributionTest.h
+++ b/Framework/Algorithms/test/ConvertToDistributionTest.h
@@ -6,6 +6,7 @@
 
 #include "MantidAlgorithms/ConvertToDistribution.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::API;
 using Mantid::Algorithms::ConvertToDistribution;
@@ -84,7 +85,7 @@ public:
 
 private:
   Workspace_sptr createTestWorkspace() {
-    return WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 10, 0, 0.5);
+    return WorkspaceCreationHelper::create2DWorkspaceBinned(1, 10, 0, 0.5);
   }
 };
 
diff --git a/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h b/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h
index 09c369422870f29c44c7a028593d2088b333ea86..b66c94b146a8ba565897713536e930efcc2f5846 100644
--- a/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h
+++ b/Framework/Algorithms/test/ConvertToEventWorkspaceTest.h
@@ -160,7 +160,7 @@ public:
   /// Workspace with infinity or NAN = don't create events there.
   void test_with_nan_and_inf() {
     // Create the input
-    Workspace2D_sptr inWS = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    Workspace2D_sptr inWS = WorkspaceCreationHelper::create2DWorkspace(1, 10);
 
     double nan = std::numeric_limits<double>::quiet_NaN();
     double inf = std::numeric_limits<double>::infinity();
@@ -211,7 +211,7 @@ public:
   /// Create events for zero-weight bins
   void test_GenerateZeros() {
     // Create the input
-    Workspace2D_sptr inWS = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    Workspace2D_sptr inWS = WorkspaceCreationHelper::create2DWorkspace(1, 10);
 
     // Clear the vector
     inWS->dataY(0).assign(10, 0.0);
diff --git a/Framework/Algorithms/test/ConvertToHistogramTest.h b/Framework/Algorithms/test/ConvertToHistogramTest.h
index 8ad63562c082a91799abccc09f546a4be8237485..0af9416c715ef295b7019e352fe57a6c4103b763 100644
--- a/Framework/Algorithms/test/ConvertToHistogramTest.h
+++ b/Framework/Algorithms/test/ConvertToHistogramTest.h
@@ -29,7 +29,7 @@ public:
   test_That_Output_Is_The_Same_As_Input_If_Input_Contains_Histogram_Data() {
     // True indicates a non histogram workspace
     Workspace2D_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspace123(5, 10, true);
+        WorkspaceCreationHelper::create2DWorkspace123(5, 10, true);
 
     MatrixWorkspace_sptr outputWS = runAlgorithm(testWS);
     TS_ASSERT(outputWS);
@@ -45,7 +45,7 @@ public:
     // Creates a workspace with 10 points
     const int numYPoints(10);
     const int numSpectra(2);
-    Workspace2D_sptr testWS = WorkspaceCreationHelper::Create2DWorkspace123(
+    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace123(
         numSpectra, numYPoints, false);
     // Reset the X data to something reasonable
     Points x(numYPoints, LinearGenerator(0.0, 1.0));
@@ -137,7 +137,7 @@ public:
 
   void setUp() override {
     inputWS =
-        WorkspaceCreationHelper::Create2DWorkspace123(20000, 10000, false);
+        WorkspaceCreationHelper::create2DWorkspace123(20000, 10000, false);
   }
 
   void tearDown() override {
diff --git a/Framework/Algorithms/test/ConvertToMatrixWorkspaceTest.h b/Framework/Algorithms/test/ConvertToMatrixWorkspaceTest.h
index d1f53b5ca7c0e1590f28b9f514bcee87bf900c10..4f260a314ee203b3c7e68023fffeab00616aa912 100644
--- a/Framework/Algorithms/test/ConvertToMatrixWorkspaceTest.h
+++ b/Framework/Algorithms/test/ConvertToMatrixWorkspaceTest.h
@@ -39,7 +39,7 @@ public:
     cloner.initialize();
     // create 2D input workspace
     Mantid::API::MatrixWorkspace_sptr in =
-        WorkspaceCreationHelper::Create2DWorkspace(5, 10);
+        WorkspaceCreationHelper::create2DWorkspace(5, 10);
     // add instance to variable 'in'
 
     Mantid::API::MatrixWorkspace_sptr out;
diff --git a/Framework/Algorithms/test/ConvertToPointDataTest.h b/Framework/Algorithms/test/ConvertToPointDataTest.h
index 574e30b846e9c14524beb68e35b8e6241c913c6d..287621e1ecb944169405ce0425df9be9f515d458 100644
--- a/Framework/Algorithms/test/ConvertToPointDataTest.h
+++ b/Framework/Algorithms/test/ConvertToPointDataTest.h
@@ -6,6 +6,7 @@
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAPI/NumericAxis.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 using Mantid::Algorithms::ConvertToPointData;
 using Mantid::API::IAlgorithm_sptr;
@@ -25,7 +26,7 @@ public:
   void test_That_Output_Is_The_Same_As_Input_If_Input_Contains_Point_Data() {
     // False indicates a non histogram workspace
     Workspace2D_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspace123(5, 10, false);
+        WorkspaceCreationHelper::create2DWorkspace123(5, 10, false);
 
     MatrixWorkspace_sptr outputWS = runAlgorithm(testWS);
     TS_ASSERT(outputWS);
@@ -44,7 +45,7 @@ public:
     const int numBins(10);
     const int numSpectra(2);
     Workspace2D_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(numSpectra, numBins);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(numSpectra, numBins);
     TS_ASSERT_EQUALS(testWS->isHistogramData(), true);
     // add a new vertical axis
     Mantid::API::Axis *const verticalAxis =
@@ -102,7 +103,7 @@ 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(
+    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspaceBinned(
         numSpectra, 11, xBoundaries);
     const size_t numBins = testWS->blocksize();
     TS_ASSERT_EQUALS(testWS->isHistogramData(), true);
@@ -172,7 +173,7 @@ public:
   }
 
   void setUp() override {
-    inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(20000, 10000);
+    inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(20000, 10000);
   }
 
   void tearDown() override {
diff --git a/Framework/Algorithms/test/ConvertUnitsTest.h b/Framework/Algorithms/test/ConvertUnitsTest.h
index 4deba8f33b5b3deef9a73a4f86458d4fa2ec2df0..c24fd2c1b48ebadca72234dfd7436e13d504f6c6 100644
--- a/Framework/Algorithms/test/ConvertUnitsTest.h
+++ b/Framework/Algorithms/test/ConvertUnitsTest.h
@@ -16,6 +16,7 @@
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidKernel/UnitFactory.h"
 
 using namespace Mantid::Kernel;
@@ -411,7 +412,7 @@ public:
 
   void testConvertQuicklyCommonBins() {
     Workspace2D_sptr input =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     input->getAxis(0)->unit() =
         UnitFactory::Instance().create("MomentumTransfer");
     AnalysisDataService::Instance().add("quickIn", input);
@@ -455,7 +456,7 @@ public:
     // the scaling of Y and E for the distribution case is not testable.
     double deltax = 0.123;
     Workspace2D_sptr input =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 10, x0, deltax);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 10, x0, deltax);
     input->getAxis(0)->unit() =
         UnitFactory::Instance().create("MomentumTransfer");
     // Y must have units, otherwise ConvertUnits does not treat data as
@@ -527,11 +528,10 @@ public:
 
   void testDeltaE() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 2663, 5, 7.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 2663, 5, 7.5);
     ws->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
 
     Instrument_sptr testInst(new Instrument);
-    ws->setInstrument(testInst);
     // Make it look like MARI (though not bin boundaries are different to the
     // real MARI file used before)
     // Define a source and sample position
@@ -551,6 +551,7 @@ public:
     physicalPixel->setPos(-0.34732, -3.28797, -2.29022);
     testInst->add(physicalPixel);
     testInst->markAsDetector(physicalPixel);
+    ws->setInstrument(testInst);
     ws->getSpectrum(0).addDetectorID(physicalPixel->getID());
 
     ConvertUnits conv;
diff --git a/Framework/Algorithms/test/CopyDetectorMappingTest.h b/Framework/Algorithms/test/CopyDetectorMappingTest.h
index 20885801e0533a956f77900edefd7e21e1f5bc24..82c3f73f6cdd911730698616440ddd67c485e766 100644
--- a/Framework/Algorithms/test/CopyDetectorMappingTest.h
+++ b/Framework/Algorithms/test/CopyDetectorMappingTest.h
@@ -22,7 +22,7 @@ public:
     Mantid::Algorithms::CopyDetectorMapping copyMapping;
     TS_ASSERT_THROWS_NOTHING(copyMapping.initialize())
 
-    auto toMatch = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto toMatch = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     // Set the detector map for a spectra in the to match workspace
     std::set<detid_t> detIDs;
@@ -35,7 +35,7 @@ public:
     // Add workspaces to ADS
     AnalysisDataService::Instance().add("to_match", toMatch);
     AnalysisDataService::Instance().add(
-        "to_remap", WorkspaceCreationHelper::Create2DWorkspace(10, 10));
+        "to_remap", WorkspaceCreationHelper::create2DWorkspace(10, 10));
 
     // Run algorithm
     TS_ASSERT_THROWS_NOTHING(
@@ -66,9 +66,9 @@ public:
 
     // Add workspaces to ADS
     AnalysisDataService::Instance().add(
-        "to_match", WorkspaceCreationHelper::Create2DWorkspace(10, 10));
+        "to_match", WorkspaceCreationHelper::create2DWorkspace(10, 10));
     AnalysisDataService::Instance().add(
-        "to_remap", WorkspaceCreationHelper::Create2DWorkspace(20, 10));
+        "to_remap", WorkspaceCreationHelper::create2DWorkspace(20, 10));
 
     // Run algorithm
     TS_ASSERT_THROWS_NOTHING(
diff --git a/Framework/Algorithms/test/CopyLogsTest.h b/Framework/Algorithms/test/CopyLogsTest.h
index 609448ba99406e44336da1e1d00698752049fd68..09b8212b47e9fabb8875e71ca563f7c97a76518d 100644
--- a/Framework/Algorithms/test/CopyLogsTest.h
+++ b/Framework/Algorithms/test/CopyLogsTest.h
@@ -26,9 +26,9 @@ public:
 
   void test_exec() {
     MatrixWorkspace_sptr inputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr outputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     WorkspaceCreationHelper::storeWS("alpha", outputWs);
 
@@ -42,9 +42,9 @@ public:
 
   void test_mergeReplaceExisting() {
     MatrixWorkspace_sptr inputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr outputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     WorkspaceCreationHelper::storeWS("alpha", outputWs);
 
@@ -72,9 +72,9 @@ public:
 
   void test_mergeKeepExisting() {
     MatrixWorkspace_sptr inputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr outputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     WorkspaceCreationHelper::storeWS("alpha", outputWs);
 
@@ -102,9 +102,9 @@ public:
 
   void test_wipeExisting() {
     MatrixWorkspace_sptr inputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     MatrixWorkspace_sptr outputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     WorkspaceCreationHelper::storeWS("alpha", outputWs);
 
diff --git a/Framework/Algorithms/test/CopySampleTest.h b/Framework/Algorithms/test/CopySampleTest.h
index 52bd203a20433efcb6a48d1323a812ad536d841e..ed4aad9bd5cd43e0323e0c3c3bde69fa2e0cfc6d 100644
--- a/Framework/Algorithms/test/CopySampleTest.h
+++ b/Framework/Algorithms/test/CopySampleTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/WorkspaceSingleValue.h"
 #include "MantidKernel/Material.h"
 #include "MantidKernel/NeutronAtom.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
diff --git a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
index 99c1705d69bb69bc787dfce95b76465d35983dc0..db417481bdfcddaf7fbf11a03dee6f66f577518d 100644
--- a/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
+++ b/Framework/Algorithms/test/CorelliCrossCorrelateTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/CorelliCrossCorrelate.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/Run.h"
 #include "MantidKernel/DateAndTime.h"
diff --git a/Framework/Algorithms/test/CorrectKiKfTest.h b/Framework/Algorithms/test/CorrectKiKfTest.h
index a8c73460a8737e5dccefd8410c767dbc8ab91f53..672376272f87c1d09bcebe66a4952840dce411e1 100644
--- a/Framework/Algorithms/test/CorrectKiKfTest.h
+++ b/Framework/Algorithms/test/CorrectKiKfTest.h
@@ -280,7 +280,7 @@ private:
 
   void createEventWorkspace() {
     EventWorkspace_sptr event =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 5, 5, 0, 0.9, 2, 0);
+        WorkspaceCreationHelper::createEventWorkspace(1, 5, 5, 0, 0.9, 2, 0);
     event->getAxis(0)->unit() = UnitFactory::Instance().create("DeltaE");
     AnalysisDataService::Instance().add(inputEvWSname, event);
   }
diff --git a/Framework/Algorithms/test/CorrectToFileTest.h b/Framework/Algorithms/test/CorrectToFileTest.h
index 817a1d0ed49d45b16df1d2b9603023220e8226ce..c6e4d350de31e7932460bcb26fd3806a05bf56b1 100644
--- a/Framework/Algorithms/test/CorrectToFileTest.h
+++ b/Framework/Algorithms/test/CorrectToFileTest.h
@@ -36,7 +36,7 @@ public:
   void testExec2D() {
     // Need a workspace to correct
     MatrixWorkspace_sptr testInput =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 102, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 102, 1.5);
     testInput->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
 
@@ -63,7 +63,7 @@ public:
   void testExecEvent() {
     // Need a workspace to correct
     MatrixWorkspace_sptr testInput =
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 102, 100, 1.5);
+        WorkspaceCreationHelper::createEventWorkspace(10, 102, 100, 1.5);
     testInput->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
 
@@ -89,7 +89,7 @@ public:
 
   void testSpectraDivide() { // Need a workspace to correct
     MatrixWorkspace_sptr testInput =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(102, 32, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(102, 32, 1.5);
 
     MatrixWorkspace_sptr data =
         executeAlgorithm(testInput, "SpectrumNumber", "Divide");
@@ -114,7 +114,7 @@ public:
 
   void testSpectraMultip() { // Need a workspace to correct
     MatrixWorkspace_sptr testInput =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(102, 32, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(102, 32, 1.5);
 
     MatrixWorkspace_sptr data =
         executeAlgorithm(testInput, "SpectrumNumber", "Multiply", false);
diff --git a/Framework/Algorithms/test/CreateFlatEventWorkspaceTest.h b/Framework/Algorithms/test/CreateFlatEventWorkspaceTest.h
index 565a98e2761a5a45a0e5fe6fd4589b5139fe0406..985a3ab9317ca39d4830dfa087570ad101ad8183 100644
--- a/Framework/Algorithms/test/CreateFlatEventWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateFlatEventWorkspaceTest.h
@@ -4,8 +4,8 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/CreateFlatEventWorkspace.h"
-
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using Mantid::Algorithms::CreateFlatEventWorkspace;
 
diff --git a/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h b/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h
index 4072e06dd8372e78b490fc451dc2da4e83e1207a..542ab62bb7a6763e2a99cd47025a8f93a44359de 100644
--- a/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateGroupingWorkspaceTest.h
@@ -5,6 +5,7 @@
 #include "MantidDataObjects/GroupingWorkspace.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include <cxxtest/TestSuite.h>
 
diff --git a/Framework/Algorithms/test/CreateLogPropertyTableTest.h b/Framework/Algorithms/test/CreateLogPropertyTableTest.h
index 64ffbef2e182ebf4216a8d705e1f92dd8ee886d2..2a631f790ac568e2b1b57d57b642b0421fb54718 100644
--- a/Framework/Algorithms/test/CreateLogPropertyTableTest.h
+++ b/Framework/Algorithms/test/CreateLogPropertyTableTest.h
@@ -109,7 +109,7 @@ private:
     using namespace WorkspaceCreationHelper;
 
     MatrixWorkspace_sptr eventws =
-        WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+        WorkspaceCreationHelper::create2DWorkspace(1, 1);
 
     int64_t runstoptime_ns = runStart + 1000000;
     int64_t pulsetime_ns(100000);
diff --git a/Framework/Algorithms/test/CreateLogTimeCorrectionTest.h b/Framework/Algorithms/test/CreateLogTimeCorrectionTest.h
index af260e4fd845d407b70d510a8f008e67e6af947d..3ac2ac3ce28d3c37e2294452d40b7311ce3a830e 100644
--- a/Framework/Algorithms/test/CreateLogTimeCorrectionTest.h
+++ b/Framework/Algorithms/test/CreateLogTimeCorrectionTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/CreateLogTimeCorrection.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataHandling/LoadInstrument.h"
diff --git a/Framework/Algorithms/test/CreatePSDBleedMaskTest.h b/Framework/Algorithms/test/CreatePSDBleedMaskTest.h
index 3dee02ac06177765b52550d425eec49088594bf1..96ba1ee3f63fac40e77e7b1162691964737060a5 100644
--- a/Framework/Algorithms/test/CreatePSDBleedMaskTest.h
+++ b/Framework/Algorithms/test/CreatePSDBleedMaskTest.h
@@ -97,7 +97,7 @@ private:
     // YLength = nTubes * nPixelsPerTube
     const int nSpectra(nTubes * nPixelsPerTube);
     Workspace2D_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nSpectra, nBins);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nSpectra, nBins);
     testWS->setInstrument(createTestInstrument(nTubes, nPixelsPerTube));
     // Set a spectra to have high count such that the fail the test
     const int failedTube(1);
diff --git a/Framework/Algorithms/test/CreateSampleWorkspaceTest.h b/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
index ba9751051bd35c00d5064bdd8f37ea77ce2e31da..d24cd31c8648791feecbe0ffecf9a9bd62cb437f 100644
--- a/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateSampleWorkspaceTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/IComponent.h"
@@ -12,6 +13,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidKernel/Unit.h"
 
 using Mantid::Algorithms::CreateSampleWorkspace;
 using namespace Mantid::Kernel;
diff --git a/Framework/Algorithms/test/CreateTransmissionWorkspaceAutoTest.h b/Framework/Algorithms/test/CreateTransmissionWorkspaceAutoTest.h
index 733ae98fc67d2aed9aca874a4f92d78961b441c8..b4dd34ca8db59bfdb48eaba635c39e9aee502f4e 100644
--- a/Framework/Algorithms/test/CreateTransmissionWorkspaceAutoTest.h
+++ b/Framework/Algorithms/test/CreateTransmissionWorkspaceAutoTest.h
@@ -2,10 +2,15 @@
 #define MANTID_ALGORITHMS_CREATETRANSMISSIONWORKSPACEAUTOTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAlgorithms/CreateTransmissionWorkspaceAuto.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceHistory.h"
+
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
 #include <boost/lexical_cast.hpp>
 
 using Mantid::Algorithms::CreateTransmissionWorkspaceAuto;
diff --git a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
index 9f76c3eddf8537b61a7100f8b8c636c630a48588..6b1f814bc643e6b4f8f924c0db3d5e816a0f8a74 100644
--- a/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateTransmissionWorkspaceTest.h
@@ -17,6 +17,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidKernel/Unit.h"
 
 using namespace Mantid;
 using namespace Mantid::Kernel;
diff --git a/Framework/Algorithms/test/CreateUserDefinedBackgroundTest.h b/Framework/Algorithms/test/CreateUserDefinedBackgroundTest.h
index 61cb415db20b6eff761b6c4641b9dd768640a9ca..1dfed0fb9df03a3e55463df7bc0c889c5460a61a 100644
--- a/Framework/Algorithms/test/CreateUserDefinedBackgroundTest.h
+++ b/Framework/Algorithms/test/CreateUserDefinedBackgroundTest.h
@@ -271,7 +271,7 @@ public:
 private:
   /// Create workspace containing test data
   MatrixWorkspace_sptr createTestData(bool isHisto) {
-    return WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    return WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         dataFunction, 1, 0.0, 10.0, 0.1, isHisto);
   }
 
@@ -374,4 +374,4 @@ private:
   const std::string m_key;
 };
 
-#endif /* MANTID_ALGORITHMS_CREATEUSERDEFINEDBACKGROUNDTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_CREATEUSERDEFINEDBACKGROUNDTEST_H_ */
diff --git a/Framework/Algorithms/test/CreateWorkspaceTest.h b/Framework/Algorithms/test/CreateWorkspaceTest.h
index cac8183e92f8b65b0b133ece9651ed861b1f4994..8a46393d9f5df348d61065acade6e8de42a8e1e0 100644
--- a/Framework/Algorithms/test/CreateWorkspaceTest.h
+++ b/Framework/Algorithms/test/CreateWorkspaceTest.h
@@ -126,8 +126,8 @@ public:
 
   void testParenting() {
     MatrixWorkspace_sptr parent =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 1, 1);
-    WorkspaceCreationHelper::AddTSPEntry(parent->mutableRun(), "ALogEntry",
+        WorkspaceCreationHelper::createEventWorkspace(1, 1, 1);
+    WorkspaceCreationHelper::addTSPEntry(parent->mutableRun(), "ALogEntry",
                                          99.0);
 
     Mantid::Algorithms::CreateWorkspace alg;
diff --git a/Framework/Algorithms/test/CropWorkspaceTest.h b/Framework/Algorithms/test/CropWorkspaceTest.h
index 83a43b361fecb9be6a78172d38d61d1eac654e1e..bc679ee1aafd583242cb700041d0a6fa8146b701 100644
--- a/Framework/Algorithms/test/CropWorkspaceTest.h
+++ b/Framework/Algorithms/test/CropWorkspaceTest.h
@@ -96,7 +96,7 @@ public:
   void makeFakeEventWorkspace(std::string wsName) {
     // Make an event workspace with 2 events in each bin.
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateEventWorkspace(36, 50, 50, 0.0, 2., 2);
+        WorkspaceCreationHelper::createEventWorkspace(36, 50, 50, 0.0, 2., 2);
     // Fake a unit in the data.
     test_in->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
     test_in->setInstrument(
@@ -230,7 +230,7 @@ public:
 
   void testWithPointData() {
     AnalysisDataService::Instance().add(
-        "point", WorkspaceCreationHelper::Create2DWorkspace123(5, 5));
+        "point", WorkspaceCreationHelper::create2DWorkspace123(5, 5));
     CropWorkspace crop3;
     TS_ASSERT_THROWS_NOTHING(crop3.initialize());
     TS_ASSERT_THROWS_NOTHING(crop3.setPropertyValue("InputWorkspace", "point"));
@@ -310,7 +310,7 @@ public:
   void testRagged_events() {
     // Event workspace with 10 bins from 0 to 10
     EventWorkspace_sptr input =
-        WorkspaceCreationHelper::CreateEventWorkspace(5, 10, 10, 0.0, 1.0);
+        WorkspaceCreationHelper::createEventWorkspace(5, 10, 10, 0.0, 1.0);
     // Change the first X vector to 3, 4, 5 ..
     for (int k = 0; k <= 10; ++k) {
       input->dataX(0)[k] = k + 3;
@@ -348,7 +348,7 @@ public:
   void testNegativeBinBoundaries() {
     const std::string wsName("neg");
     AnalysisDataService::Instance().add(
-        wsName, WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 5, -6));
+        wsName, WorkspaceCreationHelper::create2DWorkspaceBinned(1, 5, -6));
     CropWorkspace crop4;
     TS_ASSERT_THROWS_NOTHING(crop4.initialize());
     TS_ASSERT_THROWS_NOTHING(crop4.setPropertyValue("InputWorkspace", wsName));
@@ -380,7 +380,7 @@ public:
   // Public so it can be used within ExtractSingleSpectrum test
   static void doTestWithTextAxis(Algorithm *alg) {
     Workspace2D_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspace(3, 10);
+        WorkspaceCreationHelper::create2DWorkspace(3, 10);
     // Change the data so we know we've cropped the correct one
     const size_t croppedIndex(1);
     const double flagged(100.0);
@@ -437,7 +437,7 @@ public:
 
   void setUp() override {
     AnalysisDataService::Instance().add(
-        "ToCrop", WorkspaceCreationHelper::CreateEventWorkspace(
+        "ToCrop", WorkspaceCreationHelper::createEventWorkspace(
                       5000, 10000, 8000, 0.0, 1.0, 3));
   }
 
diff --git a/Framework/Algorithms/test/CuboidGaugeVolumeAbsorptionTest.h b/Framework/Algorithms/test/CuboidGaugeVolumeAbsorptionTest.h
index 776a7e23b8e058b054e1f973443915d3de055166..c49e3b2ea8540adb3fd9e3d62aef412566ed2a06 100644
--- a/Framework/Algorithms/test/CuboidGaugeVolumeAbsorptionTest.h
+++ b/Framework/Algorithms/test/CuboidGaugeVolumeAbsorptionTest.h
@@ -28,7 +28,7 @@ public:
 
   void testFailsIfNoInstrument() {
     // Create a simple test workspace that has no instrument
-    Workspace2D_sptr testWS = WorkspaceCreationHelper::Create2DWorkspace(10, 5);
+    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace(10, 5);
     // Needs to have units of wavelength
     testWS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
diff --git a/Framework/Algorithms/test/DeleteLogTest.h b/Framework/Algorithms/test/DeleteLogTest.h
index 09d86ac23b453d497d25899063799842f5947ec5..8bd866cb162a53e7bb38264be418c4dc5794179e 100644
--- a/Framework/Algorithms/test/DeleteLogTest.h
+++ b/Framework/Algorithms/test/DeleteLogTest.h
@@ -28,7 +28,7 @@ public:
     alg.setChild(true); // no ADS storage
     alg.setRethrows(true);
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("Name", "NotALog"));
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     alg.setProperty("Workspace", ws);
     TS_ASSERT_THROWS_NOTHING(alg.execute());
   }
@@ -38,7 +38,7 @@ public:
     alg.initialize();
     alg.setChild(true); // no ADS storage
     alg.setRethrows(true);
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     std::string logName("SingleValue");
     ws->mutableRun().addProperty<double>(logName, 1.0);
     alg.setProperty("Workspace", ws);
@@ -54,7 +54,7 @@ public:
     alg.initialize();
     alg.setChild(true); // no ADS storage
     alg.setRethrows(true);
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     std::string logName("TimeSeries");
 
     auto *tsp = new Mantid::Kernel::TimeSeriesProperty<double>(logName);
diff --git a/Framework/Algorithms/test/DeleteWorkspaceTest.h b/Framework/Algorithms/test/DeleteWorkspaceTest.h
index f22fae8a61ce15956de8e164dfabfc494e93a296..3ae2eb059826db4f2092ff59ed7b1ff4395e8c3a 100644
--- a/Framework/Algorithms/test/DeleteWorkspaceTest.h
+++ b/Framework/Algorithms/test/DeleteWorkspaceTest.h
@@ -17,10 +17,10 @@ public:
     // Need a test workspace registered within the ADS
     const int yLength1 = 10;
     Workspace2D_sptr testWS1 =
-        WorkspaceCreationHelper::Create2DWorkspace(yLength1, 10);
+        WorkspaceCreationHelper::create2DWorkspace(yLength1, 10);
     const int yLength2 = 20;
     Workspace2D_sptr testWS2 =
-        WorkspaceCreationHelper::Create2DWorkspace(yLength2, 10);
+        WorkspaceCreationHelper::create2DWorkspace(yLength2, 10);
     AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
     const size_t storeSizeAtStart(dataStore.size());
     const std::string testName1 = "DeleteWorkspace_testWS1";
@@ -56,10 +56,10 @@ public:
     // Need a test workspace registered within the ADS
     const int yLength1 = 10;
     Workspace2D_sptr testWS1 =
-        WorkspaceCreationHelper::Create2DWorkspace(yLength1, 10);
+        WorkspaceCreationHelper::create2DWorkspace(yLength1, 10);
     const int yLength2 = 20;
     Workspace2D_sptr testWS2 =
-        WorkspaceCreationHelper::Create2DWorkspace(yLength2, 10);
+        WorkspaceCreationHelper::create2DWorkspace(yLength2, 10);
     AnalysisDataServiceImpl &dataStore = AnalysisDataService::Instance();
     dataStore.clear();
 
diff --git a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
index b50ab80cdc17266f27a67b16a2520e9a919620a6..a367e53279ad2cd63d54f2435d37f5a234762737 100644
--- a/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
+++ b/Framework/Algorithms/test/DetectorEfficiencyCorTest.h
@@ -137,20 +137,23 @@ private:
         ShapeFactory().createShape(xmlShape, addTypeTag);
 
     boost::shared_ptr<Instrument> instrument = boost::make_shared<Instrument>();
+    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->setPos(i * 0.2, i * 0.2, 5);
+      instrument->markAsDetector(detector);
+      detectors.push_back(detector);
+    }
     space2D->setInstrument(instrument);
     ObjComponent *sample = new ObjComponent("sample", shape, NULL);
     sample->setPos(0, 0, 0);
     instrument->markAsSamplePos(sample);
 
     ParameterMap &pmap = space2D->instrumentParameters();
-    // Detector info
-    const int ndets(2);
-    for (int i = 0; i < ndets; ++i) {
-      Detector *detector = new Detector("det", i + 1, shape, NULL);
-      detector->setPos(i * 0.2, i * 0.2, 5);
+    for (const auto detector : detectors) {
       pmap.add("double", detector, "TubePressure", 10.0);
       pmap.add("double", detector, "TubeThickness", 0.0008);
-      instrument->markAsDetector(detector);
     }
     return space2D;
   }
diff --git a/Framework/Algorithms/test/DiffractionFocussingTest.h b/Framework/Algorithms/test/DiffractionFocussingTest.h
index 2b1ebb342b197366bacada0bdecdcb65019e7a42..eae24368d3d19662adf497ff05c4dede6584bc7d 100644
--- a/Framework/Algorithms/test/DiffractionFocussingTest.h
+++ b/Framework/Algorithms/test/DiffractionFocussingTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/DiffractionFocussing.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataHandling/LoadNexus.h"
 
diff --git a/Framework/Algorithms/test/ElasticWindowTest.h b/Framework/Algorithms/test/ElasticWindowTest.h
index 1b18b2e167e3742a45dad43fd8b69789569b9104..fc5a591aa36dd1364de9261eb38d93a49d6efbff 100644
--- a/Framework/Algorithms/test/ElasticWindowTest.h
+++ b/Framework/Algorithms/test/ElasticWindowTest.h
@@ -9,6 +9,7 @@
 #include "MantidAlgorithms/ElasticWindow.h"
 #include "MantidAlgorithms/Rebin.h"
 #include "MantidAlgorithms/SetInstrumentParameter.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidKernel/System.h"
diff --git a/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h b/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h
index 6ae958d9bf905ee01a782143965c09fe161f5b9c..b409f3710e8c3120d2b1c8f526dcf01ec25d10d3 100644
--- a/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h
+++ b/Framework/Algorithms/test/EstimateResolutionDiffractionTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAlgorithms/EstimateResolutionDiffraction.h"
diff --git a/Framework/Algorithms/test/ExponentialCorrectionTest.h b/Framework/Algorithms/test/ExponentialCorrectionTest.h
index 8e331f08db243ea9ccfa22b1d9e01794fb241cff..bb98354e2019411550c8916d0048644bc03b8acb 100644
--- a/Framework/Algorithms/test/ExponentialCorrectionTest.h
+++ b/Framework/Algorithms/test/ExponentialCorrectionTest.h
@@ -50,7 +50,7 @@ public:
 
   void testDivide() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::ExponentialCorrection expon3;
@@ -88,7 +88,7 @@ public:
 
   void testMultiply() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::ExponentialCorrection expon3;
@@ -126,7 +126,7 @@ public:
   }
 
   void testEvents() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     AnalysisDataService::Instance().add("test_ev_ec", evin);
diff --git a/Framework/Algorithms/test/ExponentialTest.h b/Framework/Algorithms/test/ExponentialTest.h
index e9d3e88406d32fbf1e459642f7b854bb05849c5b..5acc38d4a239ee1a02683f9367c06acf9f76cfa4 100644
--- a/Framework/Algorithms/test/ExponentialTest.h
+++ b/Framework/Algorithms/test/ExponentialTest.h
@@ -30,7 +30,7 @@ public:
     int sizex = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(sizex);
+        WorkspaceCreationHelper::create1DWorkspaceFib(sizex);
 
     AnalysisDataService::Instance().add("test_in11", work_in1);
     setError(work_in1);
@@ -56,7 +56,7 @@ public:
 
   void testEvents() {
     // evin has 0 events per bin in pixel0, 1 in pixel 1, 2 in pixel2, ...
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             5, 3, 1000, 0, 1, 4),
                         evout;
     AnalysisDataService::Instance().add("test_ev_exp", evin);
diff --git a/Framework/Algorithms/test/ExtractFFTSpectrumTest.h b/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
index 3e3a52b7cafda622c2e0f75342ecd32b16e44f44..b9a5f848529fac8ea85e6aaafe5b34125392cb96 100644
--- a/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
+++ b/Framework/Algorithms/test/ExtractFFTSpectrumTest.h
@@ -8,6 +8,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidDataHandling/LoadNexus.h"
 #include "MantidAlgorithms/Rebin.h"
+#include "MantidKernel/Unit.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/Algorithms/test/ExtractMaskTest.h b/Framework/Algorithms/test/ExtractMaskTest.h
index 54a782c8aacde56fb97e436e9a614f7909411cfd..d7fbb44bc96ba8272af511b34436a450d48d502b 100644
--- a/Framework/Algorithms/test/ExtractMaskTest.h
+++ b/Framework/Algorithms/test/ExtractMaskTest.h
@@ -1,10 +1,8 @@
 #ifndef EXTRACTMASKINGTEST_H_
 #define EXTRACTMASKINGTEST_H_
 
-//------------------------------------------------------------------------------
-// Includes
-//------------------------------------------------------------------------------
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAlgorithms/ExtractMask.h"
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -36,7 +34,7 @@ public:
     // Create a simple test workspace
     const int nvectors(50), nbins(10);
     Workspace2D_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspace(nvectors, nbins);
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
     // Mask every 10th spectra
     std::set<int64_t> maskedIndices;
     for (int i = 0; i < 50; i += 10) {
@@ -89,6 +87,8 @@ private:
     TS_ASSERT_EQUALS(outputWS->blocksize(), 1);
     size_t nOutputHists(outputWS->getNumberHistograms());
     TS_ASSERT_EQUALS(nOutputHists, inputWS->getNumberHistograms());
+    const auto &iSpecInfo = inputWS->spectrumInfo();
+    const auto &oSpecInfo = outputWS->spectrumInfo();
     for (size_t i = 0; i < nOutputHists; ++i) {
       // Sizes
       TS_ASSERT_EQUALS(outputWS->readX(i).size(), 1);
@@ -97,17 +97,11 @@ private:
       // Data
       double expectedValue(-1.0);
       bool outputMasked(false);
-      IDetector_const_sptr inputDet, outputDet;
-      try {
-        inputDet = inputWS->getDetector(i);
-        outputDet = outputWS->getDetector(i);
-      } catch (Mantid::Kernel::Exception::NotFoundError &) {
+      if (!iSpecInfo.hasDetectors(i) || !oSpecInfo.hasDetectors(i)) {
         expectedValue = 1.0;
-        inputDet = IDetector_sptr();
-        outputDet = IDetector_sptr();
       }
 
-      if (inputDet && inputDet->isMasked()) {
+      if (iSpecInfo.hasDetectors(i) && iSpecInfo.isMasked(i)) {
         expectedValue = 1.0;
         outputMasked = true;
       } else {
@@ -118,8 +112,8 @@ private:
       TS_ASSERT_EQUALS(outputWS->dataY(i)[0], expectedValue);
       TS_ASSERT_EQUALS(outputWS->dataE(i)[0], expectedValue);
       TS_ASSERT_EQUALS(outputWS->dataX(i)[0], 0.0);
-      if (inputDet) {
-        TS_ASSERT_EQUALS(outputDet->isMasked(), outputMasked);
+      if (iSpecInfo.hasDetectors(i)) {
+        TS_ASSERT_EQUALS(oSpecInfo.isMasked(i), outputMasked);
       }
     }
   }
diff --git a/Framework/Algorithms/test/ExtractMaskToTableTest.h b/Framework/Algorithms/test/ExtractMaskToTableTest.h
index 78b338148bc4bcebb09b6bdef335d1b83d0f1f11..56f25ea6e7a1e1677e9a7261da5d06b2328a3a45 100644
--- a/Framework/Algorithms/test/ExtractMaskToTableTest.h
+++ b/Framework/Algorithms/test/ExtractMaskToTableTest.h
@@ -7,6 +7,7 @@
 #include "MantidAlgorithms/ExtractMask.h"
 #include "MantidAlgorithms/SumNeighbours.h"
 #include "MantidAlgorithms/MaskDetectorsIf.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidDataObjects/Workspace2D.h"
@@ -104,7 +105,7 @@ public:
     // Create a workspace with some detectors masked
     const int nvectors(50), nbins(10);
     Workspace2D_sptr inputws =
-        WorkspaceCreationHelper::Create2DWorkspace(nvectors, nbins);
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
 
     //   Mask every 10th spectra
     std::set<int64_t> maskedIndices;
@@ -167,7 +168,7 @@ public:
     // Create a workspace with some detectors masked
     const int nvectors(50), nbins(10);
     Workspace2D_sptr inputws =
-        WorkspaceCreationHelper::Create2DWorkspace(nvectors, nbins);
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
 
     //   Mask every 10th spectra
     std::set<int64_t> maskedIndices;
@@ -268,7 +269,7 @@ public:
     // Create a workspace with some detectors masked
     const int nvectors(50), nbins(10);
     Workspace2D_sptr inputws =
-        WorkspaceCreationHelper::Create2DWorkspace(nvectors, nbins);
+        WorkspaceCreationHelper::create2DWorkspace(nvectors, nbins);
 
     //   Mask every 10th spectra
     std::set<int64_t> maskedIndices;
@@ -375,12 +376,11 @@ public:
       cout << "Workspace masked."
            << "\n";
 
-    Instrument_const_sptr instrument = inputws->getInstrument();
-    for (size_t i = 0; i < instrument->getDetectorIDs().size(); ++i) {
-      if (instrument->getDetector(instrument->getDetectorIDs()[i])->isMasked())
-        cout << "Detector : " << instrument->getDetectorIDs()[i]
-             << " is masked."
-             << "\n";
+    const auto &detectorInfo = inputws->detectorInfo();
+    for (size_t i = 0; i < detectorInfo.size(); ++i) {
+      if (detectorInfo.isMasked(i))
+        cout << "Detector : " << detectorInfo.detectorIDs()[i]
+             << " is masked.\n";
     }
 
     /*
diff --git a/Framework/Algorithms/test/ExtractSingleSpectrumTest.h b/Framework/Algorithms/test/ExtractSingleSpectrumTest.h
index 704ffca52c6e01c1f17c5d3c726bad0f6a773a27..1073b97166fe75703902b0bce21de2a8e94b707b 100644
--- a/Framework/Algorithms/test/ExtractSingleSpectrumTest.h
+++ b/Framework/Algorithms/test/ExtractSingleSpectrumTest.h
@@ -66,7 +66,7 @@ public:
     // Create and input event workspace
     const int eventsPerPixel(25);
     const int numPixels(10);
-    EventWorkspace_sptr eventWS = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr eventWS = WorkspaceCreationHelper::createEventWorkspace(
         numPixels, 50, eventsPerPixel, 0.0, 1.0, 1 /*EventPattern=1*/);
     TS_ASSERT(eventWS);
     const int wsIndex(4);
diff --git a/Framework/Algorithms/test/ExtractSpectraTest.h b/Framework/Algorithms/test/ExtractSpectraTest.h
index 1e16115d6a22914f8e35351d9fd1ba2edcc70465..b76a91d627a6da72bf7ccac2e89df73f308f63ff 100644
--- a/Framework/Algorithms/test/ExtractSpectraTest.h
+++ b/Framework/Algorithms/test/ExtractSpectraTest.h
@@ -454,7 +454,7 @@ private:
   }
 
   MatrixWorkspace_sptr createInputWorkspaceEvent() const {
-    EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr ws = WorkspaceCreationHelper::createEventWorkspace(
         int(nSpec), int(nBins), 50, 0.0, 1., 2);
     ws->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
     ws->setInstrument(
@@ -716,9 +716,9 @@ public:
   }
 
   ExtractSpectraTestPerformance() {
-    input = WorkspaceCreationHelper::Create2DWorkspaceBinned(40000, 10000);
+    input = WorkspaceCreationHelper::create2DWorkspaceBinned(40000, 10000);
     inputEvent =
-        WorkspaceCreationHelper::CreateEventWorkspace(40000, 10000, 2000);
+        WorkspaceCreationHelper::createEventWorkspace(40000, 10000, 2000);
   }
 
   void testExec2D() {
diff --git a/Framework/Algorithms/test/FFTSmooth2Test.h b/Framework/Algorithms/test/FFTSmooth2Test.h
index c97eb18174bcab81d5d340a5f88323f7a34b24ea..cd93b1d12a455db3307c799aacd707a68af6cb8e 100644
--- a/Framework/Algorithms/test/FFTSmooth2Test.h
+++ b/Framework/Algorithms/test/FFTSmooth2Test.h
@@ -172,10 +172,10 @@ public:
 
     // Make workspaces where Y value == workspace index
     if (event)
-      ws1 = WorkspaceCreationHelper::CreateEventWorkspace(10, numBins, numBins,
+      ws1 = WorkspaceCreationHelper::createEventWorkspace(10, numBins, numBins,
                                                           0, 1.0, 4);
     else
-      ws1 = WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(
+      ws1 = WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(
           numPixels, numBins);
 
     std::string outName = "SmoothedWS";
diff --git a/Framework/Algorithms/test/FFTTest.h b/Framework/Algorithms/test/FFTTest.h
index f00fb4d764367972510b649f5c1f585c9a76ecad..01100624c558052aa4a25c04f953ec6891ff5724 100644
--- a/Framework/Algorithms/test/FFTTest.h
+++ b/Framework/Algorithms/test/FFTTest.h
@@ -9,6 +9,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAlgorithms/FFT.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/UnitFactory.h"
diff --git a/Framework/Algorithms/test/FilterByLogValueTest.h b/Framework/Algorithms/test/FilterByLogValueTest.h
index 4b38f70af64bb97f8668b3a58a9389fe0b396b2d..1d9ea52bc630560525cfafb57b404ec2c0556906 100644
--- a/Framework/Algorithms/test/FilterByLogValueTest.h
+++ b/Framework/Algorithms/test/FilterByLogValueTest.h
@@ -33,10 +33,10 @@ public:
     // InputWorkspace has to be an EventWorkspace
     TS_ASSERT_THROWS(
         alg.setProperty("InputWorkspace",
-                        WorkspaceCreationHelper::Create2DWorkspace(1, 1)),
+                        WorkspaceCreationHelper::create2DWorkspace(1, 1)),
         std::invalid_argument);
     TS_ASSERT_THROWS_NOTHING(alg.setProperty(
-        "InputWorkspace", WorkspaceCreationHelper::CreateEventWorkspace()));
+        "InputWorkspace", WorkspaceCreationHelper::createEventWorkspace()));
 
     // LogName must not be empty
     TS_ASSERT_THROWS(alg.setProperty("LogName", ""), std::invalid_argument);
@@ -57,7 +57,7 @@ public:
 
   void test_validateInputs() {
     // Create and event workspace. We don't care what data is in it.
-    EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace();
+    EventWorkspace_sptr ws = WorkspaceCreationHelper::createEventWorkspace();
     // Add a single-number log
     ws->mutableRun().addProperty("SingleValue", 5);
     // Add a time-series property
@@ -106,7 +106,7 @@ public:
    */
   EventWorkspace_sptr createInputWS(bool add_proton_charge = true) {
     // Default Event Workspace with times from 0-99
-    EventWorkspace_sptr ew = WorkspaceCreationHelper::CreateEventWorkspace2();
+    EventWorkspace_sptr ew = WorkspaceCreationHelper::createEventWorkspace2();
 
     DateAndTime run_start("2010-01-01T00:00:00"); // NOTE This run_start is
                                                   // hard-coded in
@@ -151,7 +151,7 @@ public:
     ew->mutableRun().addProperty(single);
 
     // Finalize the needed stuff
-    WorkspaceCreationHelper::EventWorkspace_Finalize(ew);
+    WorkspaceCreationHelper::eventWorkspace_Finalize(ew);
 
     return ew;
   }
diff --git a/Framework/Algorithms/test/FilterByTime2Test.h b/Framework/Algorithms/test/FilterByTime2Test.h
index 8408c283b5deb8b628d5bbf54bcf42b4d0a04ae0..04daad3b22453ebc033ce02aa760f02f768c063d 100644
--- a/Framework/Algorithms/test/FilterByTime2Test.h
+++ b/Framework/Algorithms/test/FilterByTime2Test.h
@@ -44,7 +44,7 @@ public:
    */
   void NtestTooManyParams() {
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 1);
+        WorkspaceCreationHelper::createEventWorkspace(1, 1);
     AnalysisDataService::Instance().addOrReplace("eventWS", ws);
 
     // Do the filtering now.
diff --git a/Framework/Algorithms/test/FilterByTimeTest.h b/Framework/Algorithms/test/FilterByTimeTest.h
index 3f7105857061e5b5ccf3445cf90fdd170e43c247..a304c4dcda3c1b177a50f59027a7edca33a32a19 100644
--- a/Framework/Algorithms/test/FilterByTimeTest.h
+++ b/Framework/Algorithms/test/FilterByTimeTest.h
@@ -33,7 +33,7 @@ public:
   FilterByTimeTest() {
     inWS = "filterbytime_input";
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateEventWorkspace(4, 1);
+        WorkspaceCreationHelper::createEventWorkspace(4, 1);
     // Add proton charge
     TimeSeriesProperty<double> *pc =
         new TimeSeriesProperty<double>("proton_charge");
@@ -53,7 +53,7 @@ public:
 
   void testTooManyParams() {
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateEventWorkspace(1, 1);
+        WorkspaceCreationHelper::createEventWorkspace(1, 1);
     AnalysisDataService::Instance().addOrReplace("eventWS", ws);
 
     // Do the filtering now.
diff --git a/Framework/Algorithms/test/FilterByXValueTest.h b/Framework/Algorithms/test/FilterByXValueTest.h
index 1b01bb2cdd82982d678b1a6a758f0d637db59105..9db6417cb3ef4adf929fca54ca17392f1aad20fd 100644
--- a/Framework/Algorithms/test/FilterByXValueTest.h
+++ b/Framework/Algorithms/test/FilterByXValueTest.h
@@ -23,10 +23,10 @@ public:
     // InputWorkspace has to be an EventWorkspace
     TS_ASSERT_THROWS(
         alg.setProperty("InputWorkspace",
-                        WorkspaceCreationHelper::Create2DWorkspace(1, 1)),
+                        WorkspaceCreationHelper::create2DWorkspace(1, 1)),
         std::invalid_argument);
     TS_ASSERT_THROWS_NOTHING(alg.setProperty(
-        "InputWorkspace", WorkspaceCreationHelper::CreateEventWorkspace()));
+        "InputWorkspace", WorkspaceCreationHelper::createEventWorkspace()));
 
     // At least one of XMin & XMax must be specified
     auto errorMap = alg.validateInputs();
@@ -48,7 +48,7 @@ public:
   void test_exec() {
     using Mantid::DataObjects::EventWorkspace_sptr;
     EventWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::CreateEventWorkspace2(5, 1);
+        WorkspaceCreationHelper::createEventWorkspace2(5, 1);
     // Add the workspace to the ADS so that it gets a name (stops validation
     // complaints)
     Mantid::API::AnalysisDataService::Instance().add("inWS", inputWS);
@@ -80,7 +80,7 @@ public:
 
   void setUp() override {
     Mantid::API::AnalysisDataService::Instance().add(
-        "ToFilter", WorkspaceCreationHelper::CreateEventWorkspace(
+        "ToFilter", WorkspaceCreationHelper::createEventWorkspace(
                         5000, 1000, 8000, 0.0, 1.0, 3));
   }
 
diff --git a/Framework/Algorithms/test/FilterEventsTest.h b/Framework/Algorithms/test/FilterEventsTest.h
index ccf0402a3e8d7177e331f37fb99df393d3309878..9d0185849632649cd6daf5892db30848e5b69804 100644
--- a/Framework/Algorithms/test/FilterEventsTest.h
+++ b/Framework/Algorithms/test/FilterEventsTest.h
@@ -13,6 +13,7 @@
 #include "MantidDataObjects/SplittersWorkspace.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/PhysicalConstants.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/TimeSplitter.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
diff --git a/Framework/Algorithms/test/FindCenterOfMassPosition2Test.h b/Framework/Algorithms/test/FindCenterOfMassPosition2Test.h
index 8cc2d27968179812ccc9409daae8178c3f17afa1..af79181947bac5e41f463222bc675eca677c6b74 100644
--- a/Framework/Algorithms/test/FindCenterOfMassPosition2Test.h
+++ b/Framework/Algorithms/test/FindCenterOfMassPosition2Test.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataObjects/TableWorkspace.h"
 
diff --git a/Framework/Algorithms/test/FindCenterOfMassPositionTest.h b/Framework/Algorithms/test/FindCenterOfMassPositionTest.h
index f14d8de2f3021cd87e19736d9bd023fb6c63b188..1f19170fa9291d6f02d524697183241e711d2ea2 100644
--- a/Framework/Algorithms/test/FindCenterOfMassPositionTest.h
+++ b/Framework/Algorithms/test/FindCenterOfMassPositionTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataObjects/TableWorkspace.h"
 
diff --git a/Framework/Algorithms/test/FindDeadDetectorsTest.h b/Framework/Algorithms/test/FindDeadDetectorsTest.h
index 81c7108785a77535f3478b4acbfdff263079a7f0..ff7805e6efe49a519707d8f8c9dac9f19e8b0cd5 100644
--- a/Framework/Algorithms/test/FindDeadDetectorsTest.h
+++ b/Framework/Algorithms/test/FindDeadDetectorsTest.h
@@ -38,10 +38,9 @@ public:
     // data
     Workspace2D_sptr work_in =
         // the x values look like this -1, 2, 5, 8, 11, 14, 17, 20, 23, 26
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(sizey, sizex, -1, 3.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(sizey, sizex, -1, 3.0);
 
     Instrument_sptr instr(new Instrument);
-    work_in->setInstrument(instr);
 
     // yVeryDead is a detector that never responds and produces no counts
     Counts yVeryDead(sizex, 0);
@@ -78,6 +77,7 @@ public:
       instr->markAsDetector(det);
       work_in->getSpectrum(i).setDetectorID(i);
     }
+    work_in->setInstrument(instr);
 
     FindDeadDetectors alg;
 
diff --git a/Framework/Algorithms/test/FindDetectorsOutsideLimitsTest.h b/Framework/Algorithms/test/FindDetectorsOutsideLimitsTest.h
index a3b03243c337c4bfb50364f208a62a4f444adb14..9c6b0ea835879a855d34c172dc36a74fe294385c 100644
--- a/Framework/Algorithms/test/FindDetectorsOutsideLimitsTest.h
+++ b/Framework/Algorithms/test/FindDetectorsOutsideLimitsTest.h
@@ -38,10 +38,9 @@ public:
     // data
     Workspace2D_sptr work_in =
         // the x values look like this -1, 2, 5, 8, 11, 14, 17, 20, 23, 26
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(sizey, sizex, -1, 3.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(sizey, sizex, -1, 3.0);
 
     Instrument_sptr instr(new Instrument);
-    work_in->setInstrument(instr);
 
     // yVeryDead is a detector with low counts
     Counts yVeryDead(sizex, 0.1);
@@ -78,6 +77,7 @@ public:
       instr->markAsDetector(det);
       work_in->getSpectrum(i).setDetectorID(i);
     }
+    work_in->setInstrument(instr);
 
     FindDetectorsOutsideLimits alg;
 
@@ -153,7 +153,7 @@ public:
 
   void testExec_Event() {
     // Make a workspace with 50 pixels, 200 events per pixel.
-    EventWorkspace_sptr work_in = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr work_in = WorkspaceCreationHelper::createEventWorkspace(
         50, 100, 100, 0.0, 1.0, 2, 1);
     Instrument_sptr inst =
         ComponentCreationHelper::createTestInstrumentCylindrical(10);
diff --git a/Framework/Algorithms/test/FindPeakBackgroundTest.h b/Framework/Algorithms/test/FindPeakBackgroundTest.h
index cf9b571571b8e0fac3480d7993f4ebc56d690a94..fe421b5cfb80aede4f43583a1b43419ba38053ef 100644
--- a/Framework/Algorithms/test/FindPeakBackgroundTest.h
+++ b/Framework/Algorithms/test/FindPeakBackgroundTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/FindPeakBackground.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
diff --git a/Framework/Algorithms/test/FitPeakTest.h b/Framework/Algorithms/test/FitPeakTest.h
index ca3b79ae1d207b8e8e49c6bb2c822ebdab565a9f..333ec2fe645114389a87490cf5bc19fa176b5de0 100644
--- a/Framework/Algorithms/test/FitPeakTest.h
+++ b/Framework/Algorithms/test/FitPeakTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/FitPeak.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/Algorithms/test/GeneralisedSecondDifferenceTest.h b/Framework/Algorithms/test/GeneralisedSecondDifferenceTest.h
index db41133460d98600342b30cc10385a5e9f22415e..2496d91bda7f3aaae20cfe9dcdc0ca48d86ba7a6 100644
--- a/Framework/Algorithms/test/GeneralisedSecondDifferenceTest.h
+++ b/Framework/Algorithms/test/GeneralisedSecondDifferenceTest.h
@@ -79,9 +79,9 @@ public:
   }
 
   void setUp() override {
-    inputMatrix = WorkspaceCreationHelper::Create2DWorkspaceBinned(10000, 1000);
+    inputMatrix = WorkspaceCreationHelper::create2DWorkspaceBinned(10000, 1000);
     inputEvent =
-        WorkspaceCreationHelper::CreateEventWorkspace(10000, 1000, 5000);
+        WorkspaceCreationHelper::createEventWorkspace(10000, 1000, 5000);
   }
 
   void tearDown() override {
diff --git a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
index feeb64359c0f7736674a6085b904f645074725df..161da6b66676e8cdb6a629117882ae84222db436 100644
--- a/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
+++ b/Framework/Algorithms/test/GenerateIPythonNotebookTest.h
@@ -14,6 +14,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/make_unique.h"
 #include <Poco/File.h>
 
diff --git a/Framework/Algorithms/test/GeneratePeaksTest.h b/Framework/Algorithms/test/GeneratePeaksTest.h
index 570b26760c52ba2c95c3fd2355e535cc7a06339e..ae60baf4145b7266ec5fb6894f1fcc4fbf16c167 100644
--- a/Framework/Algorithms/test/GeneratePeaksTest.h
+++ b/Framework/Algorithms/test/GeneratePeaksTest.h
@@ -7,6 +7,7 @@
 
 #include "MantidAlgorithms/GeneratePeaks.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Column.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -575,4 +576,4 @@ private:
   API::MatrixWorkspace_sptr inputws;
 };
 
-#endif /* MANTID_ALGORITHMS_GENERATEPEAKSTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_GENERATEPEAKSTEST_H_ */
diff --git a/Framework/Algorithms/test/GeneratePythonScriptTest.h b/Framework/Algorithms/test/GeneratePythonScriptTest.h
index 1192374f2b6c9db682f819958f450def6c220e7c..67ac94d0a325c0b133ba0c14d194724bd09ecf18 100644
--- a/Framework/Algorithms/test/GeneratePythonScriptTest.h
+++ b/Framework/Algorithms/test/GeneratePythonScriptTest.h
@@ -10,6 +10,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
diff --git a/Framework/Algorithms/test/GetAllEiTest.h b/Framework/Algorithms/test/GetAllEiTest.h
index 2365239cc9f39add70f91a4ec9d0d8e269d013d5..0693b03e9d25f4dc3fe59f8a49ce418928d563bb 100644
--- a/Framework/Algorithms/test/GetAllEiTest.h
+++ b/Framework/Algorithms/test/GetAllEiTest.h
@@ -4,6 +4,7 @@
 #include <memory>
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/GetAllEi.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -39,12 +40,11 @@ DataObjects::Workspace2D_sptr createTestingWS(bool noLogs = false) {
   paramMap.add<bool>("bool", chopper.get(), "filter_with_derivative", false);
 
   // test instrument parameters (obtained from workspace):
-  auto moderator = pInstrument->getSource();
-  auto detector1 = ws->getDetector(0);
-  auto detector2 = ws->getDetector(1);
-  double l_chop = chopper->getDistance(*moderator);
-  double l_mon1 = detector1->getDistance(*moderator);
-  double l_mon2 = detector2->getDistance(*moderator);
+  auto moderatorPosition = pInstrument->getSource()->getPos();
+  auto &spectrumInfo = ws->spectrumInfo();
+  double l_chop = chopper->getPos().distance(moderatorPosition);
+  double l_mon1 = spectrumInfo.position(0).distance(moderatorPosition);
+  double l_mon2 = spectrumInfo.position(1).distance(moderatorPosition);
   //,l_mon1(20-9),l_mon2(20-2);
   double t_chop(delay + inital_chop_phase / chopSpeed);
   double Period =
@@ -409,8 +409,9 @@ public:
     Mantid::DataObjects::Workspace2D_sptr tws =
         WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(5, 100,
                                                                      true);
-    auto det1 = tws->getDetector(0);
-    auto det2 = tws->getDetector(4);
+    auto &spectrumInfoT = tws->spectrumInfo();
+    auto det1TPosition = spectrumInfoT.position(0);
+    auto det2TPosition = spectrumInfoT.position(4);
     auto detID1 = tws->getSpectrum(0).getDetectorIDs();
     auto detID2 = tws->getSpectrum(4).getDetectorIDs();
 
@@ -423,12 +424,13 @@ public:
     size_t wsIndex0;
     auto wws = m_getAllEi.buildWorkspaceToFit(tws, wsIndex0);
 
-    auto det1p = wws->getDetector(0);
-    auto det2p = wws->getDetector(1);
+    auto &spectrumInfoW = wws->spectrumInfo();
+    auto det1WPosition = spectrumInfoW.position(0);
+    auto det2WPosition = spectrumInfoW.position(1);
     TSM_ASSERT_EQUALS("should be the same first detector position",
-                      det1p->getRelativePos(), det1->getRelativePos());
+                      det1WPosition, det1TPosition);
     TSM_ASSERT_EQUALS("should be the same second detector position",
-                      det2p->getRelativePos(), det2->getRelativePos());
+                      det2WPosition, det2TPosition);
 
     TSM_ASSERT_EQUALS("Detector's ID for the first spectrum and new workspace "
                       "should coincide",
diff --git a/Framework/Algorithms/test/GetDetOffsetsMultiPeaksTest.h b/Framework/Algorithms/test/GetDetOffsetsMultiPeaksTest.h
index 9721c6548d7a69a478ecb619770433f776c40a66..09bf98918e8cbf5ddc6a5796dac2fd88ad1ae056 100644
--- a/Framework/Algorithms/test/GetDetOffsetsMultiPeaksTest.h
+++ b/Framework/Algorithms/test/GetDetOffsetsMultiPeaksTest.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
@@ -88,7 +89,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   //----------------------------------------------------------------------------------------------
@@ -97,7 +98,7 @@ public:
   void testExecWithGroup() {
     // --------- Workspace with summed spectra -------
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateGroupedWorkspace2D(3, 200, 1.0);
+        WorkspaceCreationHelper::createGroupedWorkspace2D(3, 200, 1.0);
     WS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
 
@@ -143,7 +144,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   //----------------------------------------------------------------------------------------------
@@ -214,7 +215,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   //----------------------------------------------------------------------------------------------
@@ -285,7 +286,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   //----------------------------------------------------------------------------------------------
@@ -355,7 +356,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   //----------------------------------------------------------------------------------------------
@@ -416,7 +417,7 @@ public:
     TS_ASSERT_THROWS_NOTHING(
         mask = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
             maskWS));
-    TS_ASSERT(mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(mask->detectorInfo().isMasked(0));
 
     return;
   }
diff --git a/Framework/Algorithms/test/GetDetectorOffsetsTest.h b/Framework/Algorithms/test/GetDetectorOffsetsTest.h
index 510063e9e5cac33fcc9bf616be0b90b9687d638a..0a319d79f8fe67ff1dc44a1b4a3d5ef8c0d743ec 100644
--- a/Framework/Algorithms/test/GetDetectorOffsetsTest.h
+++ b/Framework/Algorithms/test/GetDetectorOffsetsTest.h
@@ -9,6 +9,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidDataObjects/OffsetsWorkspace.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FrameworkManager.h"
 
 using namespace Mantid::API;
@@ -85,13 +86,13 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   void testExecWithGroup() {
     // --------- Workspace with summed spectra -------
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateGroupedWorkspace2D(3, 200, 1.0);
+        WorkspaceCreationHelper::createGroupedWorkspace2D(3, 200, 1.0);
     WS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
 
@@ -136,7 +137,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
   void testExecAbsolute() {
@@ -191,7 +192,7 @@ public:
             maskWS));
     if (!mask)
       return;
-    TS_ASSERT(!mask->getInstrument()->getDetector(1)->isMasked());
+    TS_ASSERT(!mask->detectorInfo().isMasked(0));
   }
 
 private:
diff --git a/Framework/Algorithms/test/GetEiMonDet2Test.h b/Framework/Algorithms/test/GetEiMonDet2Test.h
index f43bfbdb25a0fd239074fb52fcb1e777c49002a7..2e782a2442914eae90ac6113ba2560a13dfe3460 100644
--- a/Framework/Algorithms/test/GetEiMonDet2Test.h
+++ b/Framework/Algorithms/test/GetEiMonDet2Test.h
@@ -315,7 +315,7 @@ private:
   static MatrixWorkspace_sptr createWorkspace() {
     const size_t nDetectors = 1;
     // Number of spectra = detectors + monitor.
-    auto ws = Create2DWorkspace(nDetectors + 1, 2);
+    auto ws = create2DWorkspace(nDetectors + 1, 2);
     ws->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
     attachInstrument(ws);
     ws->mutableRun().addProperty("Ei", EI, true);
diff --git a/Framework/Algorithms/test/GroupWorkspacesTest.h b/Framework/Algorithms/test/GroupWorkspacesTest.h
index a1f0cbfd1b90a2c6f894db09c1988f3d532d6cb2..0b9fa7e31c0bb1bba51c9b562e415d4be0c32ae7 100644
--- a/Framework/Algorithms/test/GroupWorkspacesTest.h
+++ b/Framework/Algorithms/test/GroupWorkspacesTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/GroupWorkspaces.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 class GroupWorkspacesTest : public CxxTest::TestSuite {
@@ -202,12 +203,12 @@ private:
 
   void addTestMatrixWorkspaceToADS(const std::string &name) {
     auto &ads = Mantid::API::AnalysisDataService::Instance();
-    ads.add(name, WorkspaceCreationHelper::Create2DWorkspace(1, 1));
+    ads.add(name, WorkspaceCreationHelper::create2DWorkspace(1, 1));
   }
 
   void addTestEventWorkspaceToADS(const std::string &name) {
     auto &ads = Mantid::API::AnalysisDataService::Instance();
-    ads.add(name, WorkspaceCreationHelper::CreateEventWorkspace());
+    ads.add(name, WorkspaceCreationHelper::createEventWorkspace());
   }
 
   void addTestTableWorkspaceToADS(const std::string &name) {
diff --git a/Framework/Algorithms/test/HRPDSlabCanAbsorptionTest.h b/Framework/Algorithms/test/HRPDSlabCanAbsorptionTest.h
index 15cf3386b69f0601af987b5ac85c4ce6c0cdff48..c765aefbdd0f9df1e50181fa6ebcf29821037976 100644
--- a/Framework/Algorithms/test/HRPDSlabCanAbsorptionTest.h
+++ b/Framework/Algorithms/test/HRPDSlabCanAbsorptionTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using namespace Mantid::Geometry;
@@ -29,14 +30,13 @@ public:
       atten.initialize();
 
     MatrixWorkspace_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(3, 10, 0.25, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 0.25, 0.5);
     // Needs to have units of wavelength
     testWS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
 
     boost::shared_ptr<Instrument> testInst =
         boost::make_shared<Instrument>("testInst");
-    testWS->setInstrument(testInst);
 
     // Define a source and sample position
     // Define a source component
@@ -68,6 +68,8 @@ public:
     testInst->add(det3);
     testInst->markAsDetector(det3);
 
+    testWS->setInstrument(testInst);
+
     TS_ASSERT_THROWS_NOTHING(
         atten.setProperty<MatrixWorkspace_sptr>("InputWorkspace", testWS));
     std::string outputWS("factors");
diff --git a/Framework/Algorithms/test/He3TubeEfficiencyTest.h b/Framework/Algorithms/test/He3TubeEfficiencyTest.h
index 84c3b77f9e2fdd92de3f49ec1bd9e45dc9500f51..6cbe36ada6d806523974c108842948f5e5431309 100644
--- a/Framework/Algorithms/test/He3TubeEfficiencyTest.h
+++ b/Framework/Algorithms/test/He3TubeEfficiencyTest.h
@@ -195,7 +195,7 @@ private:
 
   void createEventWorkspace() {
     EventWorkspace_sptr event =
-        WorkspaceCreationHelper::CreateEventWorkspace(4, 5, 5, 0, 0.9, 3, 0);
+        WorkspaceCreationHelper::createEventWorkspace(4, 5, 5, 0, 0.9, 3, 0);
     event->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength");
     AnalysisDataService::Instance().add(inputEvWS, event);
 
diff --git a/Framework/Algorithms/test/IQTransformTest.h b/Framework/Algorithms/test/IQTransformTest.h
index e6eb6943def48ff52d1f28a271a0e3e28d76fb9b..96c82adcdc3bef23dc7ed7f02c35823893509068 100644
--- a/Framework/Algorithms/test/IQTransformTest.h
+++ b/Framework/Algorithms/test/IQTransformTest.h
@@ -6,6 +6,7 @@
 
 #include "MantidAlgorithms/IQTransform.h"
 #include "MantidAPI/Axis.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
 class IQTransformTest : public CxxTest::TestSuite {
@@ -17,12 +18,12 @@ public:
     iq.setChild(
         true); // This means the ADS is not involved anywhere in this test
 
-    inWS_hist = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 2);
+    inWS_hist = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 2);
     inWS_hist->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("MomentumTransfer");
     inWS_hist->setDistribution(true);
 
-    inWS_point = WorkspaceCreationHelper::Create2DWorkspace154(1, 1);
+    inWS_point = WorkspaceCreationHelper::create2DWorkspace154(1, 1);
     inWS_point->dataX(0)[0] = 3.0; // 1 is not a good number to test with
     inWS_point->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("MomentumTransfer");
@@ -228,7 +229,7 @@ public:
     TS_ASSERT_THROWS_NOTHING(iq.setPropertyValue("TransformType", "Holtzer"));
     TS_ASSERT_THROWS_NOTHING(iq.setProperty<Mantid::API::MatrixWorkspace_sptr>(
         "BackgroundWorkspace",
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 1)));
+        WorkspaceCreationHelper::create2DWorkspace123(1, 1)));
     TS_ASSERT(iq.execute());
 
     // Remember that a constant value of 1.5 will also be subtracted because
diff --git a/Framework/Algorithms/test/IdentifyNoisyDetectorsTest.h b/Framework/Algorithms/test/IdentifyNoisyDetectorsTest.h
index b295914329142e50670f190fc2bfdb965bda7ef7..5a8d998ad3e9e59c21955dae1b6cde08217d27ca 100644
--- a/Framework/Algorithms/test/IdentifyNoisyDetectorsTest.h
+++ b/Framework/Algorithms/test/IdentifyNoisyDetectorsTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/IdentifyNoisyDetectors.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Algorithms;
diff --git a/Framework/Algorithms/test/ImggTomographicReconstructionTest.h b/Framework/Algorithms/test/ImggTomographicReconstructionTest.h
index a6d196ddc4b9ea0f997c9b2df42ba3088a1536a6..878c21dc91234bde38d01dd8c6ffedc824bef778 100644
--- a/Framework/Algorithms/test/ImggTomographicReconstructionTest.h
+++ b/Framework/Algorithms/test/ImggTomographicReconstructionTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/ImggTomographicReconstruction.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Exception.h"
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -63,7 +64,7 @@ public:
 
   void test_exec_fails_wrong_workspace() {
     API::MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(3);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(3);
 
     ImggTomographicReconstruction alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize());
@@ -74,7 +75,7 @@ public:
     TS_ASSERT(!alg.isExecuted());
 
     API::MatrixWorkspace_sptr wsSingle =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     ImggTomographicReconstruction algTwo;
     TS_ASSERT_THROWS_NOTHING(algTwo.initialize());
@@ -88,7 +89,7 @@ public:
   void test_exec_fails_single_proj() {
     const std::string projectionsGrpName("only_one_projection");
     API::WorkspaceGroup_sptr projectionsGrp =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(1, 4, 4,
+        WorkspaceCreationHelper::createWorkspaceGroup(1, 4, 4,
                                                       projectionsGrpName);
 
     ImggTomographicReconstruction alg;
@@ -107,7 +108,7 @@ public:
   void test_exec_fails_wrong_center() {
     const std::string projectionsGrpName("only_two_small_projections");
     API::WorkspaceGroup_sptr projectionsGrp =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(2, 4, 4,
+        WorkspaceCreationHelper::createWorkspaceGroup(2, 4, 4,
                                                       projectionsGrpName);
 
     ImggTomographicReconstruction alg;
@@ -130,7 +131,7 @@ public:
     int xsize = 16;
     int numProj = 4;
     API::WorkspaceGroup_sptr projectionsGrp =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(numProj, ysize, xsize,
+        WorkspaceCreationHelper::createWorkspaceGroup(numProj, ysize, xsize,
                                                       projectionsGrpName);
 
     for (size_t proj = 0; proj < static_cast<size_t>(proj); ++proj) {
@@ -197,7 +198,7 @@ public:
     int xsize = 8;
     int numProj = 2;
     API::WorkspaceGroup_sptr projectionsGrp =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(numProj, ysize, xsize,
+        WorkspaceCreationHelper::createWorkspaceGroup(numProj, ysize, xsize,
                                                       projectionsGrpName);
 
     for (size_t proj = 0; proj < static_cast<size_t>(proj); ++proj) {
diff --git a/Framework/Algorithms/test/IntegrateByComponentTest.h b/Framework/Algorithms/test/IntegrateByComponentTest.h
index 18bfc9580e9ead8474643230f421cb230e9b1db0..5e97930a18c7cb07cc8b8c0dd11416935c926559 100644
--- a/Framework/Algorithms/test/IntegrateByComponentTest.h
+++ b/Framework/Algorithms/test/IntegrateByComponentTest.h
@@ -3,6 +3,8 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/DetectorInfo.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAlgorithms/IntegrateByComponent.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
@@ -223,11 +225,12 @@ public:
     TS_ASSERT(result);
     if (!result)
       return;
+    const auto &spectrumInfo = result->spectrumInfo();
     for (size_t i = 0; i < result->getNumberHistograms() / 4; i++) {
       TS_ASSERT_DELTA(result->readY(4 * i + 1)[0], 8 * i + 4, 1e-10);
       TS_ASSERT_DELTA(result->readY(4 * i + 2)[0], 8 * i + 4, 1e-10);
       TS_ASSERT_DELTA(result->readY(4 * i + 3)[0], 8 * i + 4, 1e-10);
-      TS_ASSERT(result->getDetector(4 * i)->isMasked());
+      TS_ASSERT(spectrumInfo.isMasked(4 * i));
     }
 
     // Remove workspace from the data service.
@@ -239,17 +242,16 @@ private:
   void ABCtestWorkspace(std::string inputWSname, bool mask) {
     int nSpectra(12);
     Workspace2D_sptr ws2D =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(
             nSpectra, 2);
     ws2D->setInstrument(
         ComponentCreationHelper::createTestInstrumentRectangular(3, 2, 0));
 
-    Mantid::Geometry::ParameterMap &pmap = ws2D->instrumentParameters();
+    auto &detectorInfo = ws2D->mutableDetectorInfo();
     for (int i = 0; i < nSpectra; i++) {
       ws2D->getSpectrum(i).setDetectorID(i + 4);
       if (mask && (i % 4 == 0)) {
-        Mantid::Geometry::IDetector_const_sptr det = ws2D->getDetector(i);
-        pmap.addBool(det.get(), "masked", true);
+        detectorInfo.setMasked(i, true);
       }
     }
 
diff --git a/Framework/Algorithms/test/IntegrationTest.h b/Framework/Algorithms/test/IntegrationTest.h
index 923a0fd3587512d315e2a8a19f1111ae8143ca31..06321633d382c4f53550de98c78f30e4e098b36c 100644
--- a/Framework/Algorithms/test/IntegrationTest.h
+++ b/Framework/Algorithms/test/IntegrationTest.h
@@ -221,7 +221,7 @@ public:
                    int StartWorkspaceIndex, int EndWorkspaceIndex) {
     int numPixels = 100;
     int numBins = 50;
-    EventWorkspace_sptr inWS = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr inWS = WorkspaceCreationHelper::createEventWorkspace(
         numPixels, numBins, numBins, 0.0, 1.0, 2);
     AnalysisDataService::Instance().addOrReplace(inName, inWS);
 
@@ -287,7 +287,7 @@ public:
                       const bool IncludePartialBins, const int expectedNumHists,
                       const double expectedVals[]) {
     RebinnedOutput_sptr inWS =
-        WorkspaceCreationHelper::CreateRebinnedOutputWorkspace();
+        WorkspaceCreationHelper::createRebinnedOutputWorkspace();
     std::string inName = inWS->getName();
     AnalysisDataService::Instance().addOrReplace(inName, inWS);
     std::string outName = "rebinInt";
diff --git a/Framework/Algorithms/test/LogarithmTest.h b/Framework/Algorithms/test/LogarithmTest.h
index 86bbd36497927f8100ffe46afc98c547a2b04db5..9d58b03c18054f60602997773bfbac379125659e 100644
--- a/Framework/Algorithms/test/LogarithmTest.h
+++ b/Framework/Algorithms/test/LogarithmTest.h
@@ -30,7 +30,7 @@ public:
 
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(sizex);
+        WorkspaceCreationHelper::create1DWorkspaceFib(sizex);
     AnalysisDataService::Instance().add("test_inLn", work_in1);
 
     Logarithm alg;
@@ -59,9 +59,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     Workspace2D_sptr work_ou2 =
-        WorkspaceCreationHelper::Create2DWorkspace(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace(nHist, nBins);
 
     Logarithm alg;
     AnalysisDataService::Instance().add("test_inLn2", work_in2);
@@ -89,7 +89,7 @@ public:
 
   void testEvents() {
     // evin has 0 events per bin in pixel0, 1 in pixel 1, 2 in pixel2, ...
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             5, 3, 1000, 0, 1, 4),
                         evout;
     AnalysisDataService::Instance().add("test_ev_log", evin);
diff --git a/Framework/Algorithms/test/LorentzCorrectionTest.h b/Framework/Algorithms/test/LorentzCorrectionTest.h
index 1703fd8c1815b77afbfcfd9e216dbe645d0991f8..e9621a61d86af246c98c9b784ead7f829d03f1a7 100644
--- a/Framework/Algorithms/test/LorentzCorrectionTest.h
+++ b/Framework/Algorithms/test/LorentzCorrectionTest.h
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidGeometry/Instrument/ObjComponent.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/V3D.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <cmath>
@@ -65,7 +66,7 @@ private:
     const int nSpectra = 1;
     const double deltaX = 10;
     const double startX = 0;
-    auto workspace = Create2DWorkspaceBinned(nSpectra, nBins, startX,
+    auto workspace = create2DWorkspaceBinned(nSpectra, nBins, startX,
                                              deltaX); // Creates histogram data
     workspace->mutableY(0) = 1.0;
     workspace->mutableE(0) = 1.0;
diff --git a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
index 0b703dedf4fffba164463197e14b7756cee76dbf..c352450a75e2761d2adc9628323145c909371834 100644
--- a/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
+++ b/Framework/Algorithms/test/MCAbsorptionStrategyTest.h
@@ -35,14 +35,10 @@ public:
 
     MockRNG rng;
     auto mcabsorb = createTestObject();
-    // Expectations
-    Sequence rand;
-    const double step = static_cast<double>(1) / static_cast<double>(m_nevents);
-    const double start = step;
-    for (size_t i = 0; i < m_nevents; ++i) {
-      double next = start + static_cast<double>(i) * step;
-      EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(next));
-    }
+    // 3 random numbers per event expected
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(30))
+        .WillRepeatedly(Return(0.5));
     const Mantid::Algorithms::IBeamProfile::Ray testRay = {V3D(-2, 0, 0),
                                                            V3D(1, 0, 0)};
     EXPECT_CALL(m_testBeamProfile, generatePoint(_, _))
@@ -54,7 +50,7 @@ public:
     double factor(0.0), error(0.0);
     std::tie(factor, error) =
         mcabsorb.calculate(rng, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(8.05621154e-03, factor, 1e-08);
+    TS_ASSERT_DELTA(0.0043828472, factor, 1e-08);
     TS_ASSERT_DELTA(1.0 / std::sqrt(m_nevents), error, 1e-08);
   }
 
@@ -72,10 +68,16 @@ private:
     MOCK_CONST_METHOD2(generatePoint,
                        Ray(Mantid::Kernel::PseudoRandomNumberGenerator &,
                            const Mantid::Geometry::BoundingBox &));
+    MOCK_CONST_METHOD1(defineActiveRegion, Mantid::Geometry::BoundingBox(
+                                               const Mantid::API::Sample &));
     GCC_DIAG_ON_SUGGEST_OVERRIDE
   };
 
   MCAbsorptionStrategy createTestObject() {
+    using namespace ::testing;
+
+    EXPECT_CALL(m_testBeamProfile, defineActiveRegion(_))
+        .WillOnce(Return(m_testSample.getShape().getBoundingBox()));
     return MCAbsorptionStrategy(m_testBeamProfile, m_testSample, m_nevents);
   }
 
diff --git a/Framework/Algorithms/test/MCInteractionVolumeTest.h b/Framework/Algorithms/test/MCInteractionVolumeTest.h
index ce32e772b139be86c3facfcf1392ce467be29eb2..fff2c55c0369fb80a7abae932521b504102a7767 100644
--- a/Framework/Algorithms/test/MCInteractionVolumeTest.h
+++ b/Framework/Algorithms/test/MCInteractionVolumeTest.h
@@ -25,9 +25,9 @@ public:
   void test_Bounding_Volume_Matches_Sample() {
     using namespace MonteCarloTesting;
     auto sample = createTestSample(TestSampleType::SolidSphere);
-    MCInteractionVolume interactor(sample);
-
     const auto sampleBox = sample.getShape().getBoundingBox();
+    MCInteractionVolume interactor(sample, sampleBox);
+
     const auto interactionBox = interactor.getBoundingBox();
     TS_ASSERT_EQUALS(sampleBox.minPoint(), interactionBox.minPoint());
     TS_ASSERT_EQUALS(sampleBox.maxPoint(), interactionBox.maxPoint());
@@ -39,18 +39,18 @@ public:
     using namespace ::testing;
 
     // Testing inputs
-    const V3D startPos(-2.0, 0.0, 0.0), direc(1.0, 0.0, 0.0),
-        endPos(0.7, 0.7, 1.4);
+    const V3D startPos(-2.0, 0.0, 0.0), endPos(0.7, 0.7, 1.4);
     const double lambdaBefore(2.5), lambdaAfter(3.5);
     MockRNG rng;
-    EXPECT_CALL(rng, nextInt(1, 1)).Times(Exactly(0));
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(1)).WillOnce(Return(0.25));
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(3))
+        .WillRepeatedly(Return(0.25));
 
     auto sample = createTestSample(TestSampleType::SolidSphere);
-    MCInteractionVolume interactor(sample);
+    MCInteractionVolume interactor(sample, sample.getShape().getBoundingBox());
     const double factor = interactor.calculateAbsorption(
-        rng, startPos, direc, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(1.06797501e-02, factor, 1e-8);
+        rng, startPos, endPos, lambdaBefore, lambdaAfter);
+    TS_ASSERT_DELTA(0.0028357258, factor, 1e-8);
   }
 
   void test_Absorption_In_Sample_With_Hole_Container_Scatter_In_All_Segments() {
@@ -59,28 +59,29 @@ public:
     using namespace ::testing;
 
     // Testing inputs
-    const V3D startPos(-2.0, 0.0, 0.0), direc(1.0, 0.0, 0.0),
-        endPos(2.0, 0.0, 0.0);
+    const V3D startPos(-2.0, 0.0, 0.0), endPos(2.0, 0.0, 0.0);
     const double lambdaBefore(2.5), lambdaAfter(3.5);
     auto sample = createTestSample(TestSampleType::Annulus);
 
     MockRNG rng;
     // force scatter in segment 1
-    EXPECT_CALL(rng, nextInt(1, 2)).Times(Exactly(1)).WillOnce(Return(1));
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(1)).WillOnce(Return(0.25));
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(3))
+        .WillRepeatedly(Return(0.25));
 
-    MCInteractionVolume interactor(sample);
+    MCInteractionVolume interactor(sample, sample.getShape().getBoundingBox());
     const double factorSeg1 = interactor.calculateAbsorption(
-        rng, startPos, direc, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(5.35624555e-02, factorSeg1, 1e-8);
+        rng, startPos, endPos, lambdaBefore, lambdaAfter);
+    TS_ASSERT_DELTA(0.030489479, factorSeg1, 1e-8);
     Mock::VerifyAndClearExpectations(&rng);
 
     // force scatter in segment 2
-    EXPECT_CALL(rng, nextInt(1, 2)).Times(Exactly(1)).WillOnce(Return(2));
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(1)).WillOnce(Return(0.35));
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(3))
+        .WillRepeatedly(Return(0.75));
     const double factorSeg2 = interactor.calculateAbsorption(
-        rng, startPos, direc, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(7.30835693e-02, factorSeg2, 1e-8);
+        rng, startPos, endPos, lambdaBefore, lambdaAfter);
+    TS_ASSERT_DELTA(0.033119242, factorSeg2, 1e-8);
     Mock::VerifyAndClearExpectations(&rng);
   }
 
@@ -91,50 +92,38 @@ public:
     using namespace ::testing;
 
     // Testing inputs
-    const V3D startPos(-2.0, 0.0, 0.0), direc(1.0, 0.0, 0.0),
-        endPos(2.0, 0.0, 0.0);
+    const V3D startPos(-2.0, 0.0, 0.0), endPos(2.0, 0.0, 0.0);
     const double lambdaBefore(2.5), lambdaAfter(3.5);
 
     auto sample = createTestSample(TestSampleType::SamplePlusContainer);
     MockRNG rng;
     // force scatter in segment can
-    EXPECT_CALL(rng, nextInt(1, 3)).Times(Exactly(1)).WillOnce(Return(1));
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(1)).WillOnce(Return(0.3));
-
-    MCInteractionVolume interactor(sample);
+    EXPECT_CALL(rng, nextInt(1, 1)).Times(Exactly(1)).WillOnce(Return(1));
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(4))
+        .WillOnce(Return(0.75))
+        .WillOnce(Return(0.02))
+        .WillOnce(Return(0.5))
+        .WillOnce(Return(0.5));
+
+    MCInteractionVolume interactor(sample,
+                                   sample.getEnvironment().boundingBox());
     const double factorContainer = interactor.calculateAbsorption(
-        rng, startPos, direc, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(6.919239804e-01, factorContainer, 1e-8);
+        rng, startPos, endPos, lambdaBefore, lambdaAfter);
+    TS_ASSERT_DELTA(0.69223681, factorContainer, 1e-8);
     Mock::VerifyAndClearExpectations(&rng);
 
     // force scatter in sample
-    EXPECT_CALL(rng, nextInt(1, 3)).Times(Exactly(1)).WillOnce(Return(2));
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(1)).WillOnce(Return(0.35));
-
+    EXPECT_CALL(rng, nextValue())
+        .Times(Exactly(4))
+        .WillOnce(Return(0.25))
+        .WillRepeatedly(Return(0.25));
     const double factorSample = interactor.calculateAbsorption(
-        rng, startPos, direc, endPos, lambdaBefore, lambdaAfter);
-    TS_ASSERT_DELTA(6.9620991317e-01, factorSample, 1e-8);
+        rng, startPos, endPos, lambdaBefore, lambdaAfter);
+    TS_ASSERT_DELTA(0.73100698, factorSample, 1e-8);
     Mock::VerifyAndClearExpectations(&rng);
   }
 
-  void test_Track_With_Zero_Intersections_Returns_Negative_Factor() {
-    using Mantid::Kernel::V3D;
-    using namespace MonteCarloTesting;
-    using namespace ::testing;
-
-    // Testing inputs
-    const V3D startPos(-2.0, 0.0, 0.0), direc(0.0, 1.0, 0.0),
-        endPos(0.7, 0.7, 1.4);
-    const double lambdaBefore(2.5), lambdaAfter(3.5);
-    MockRNG rng;
-    EXPECT_CALL(rng, nextValue()).Times(Exactly(0));
-
-    auto sample = createTestSample(TestSampleType::SolidSphere);
-    MCInteractionVolume interactor(sample);
-    TS_ASSERT(interactor.calculateAbsorption(rng, startPos, direc, endPos,
-                                             lambdaBefore, lambdaAfter) < 0.0);
-  }
-
   //----------------------------------------------------------------------------
   // Failure cases
   //----------------------------------------------------------------------------
@@ -143,10 +132,13 @@ public:
 
     Sample sample;
     // nothing
-    TS_ASSERT_THROWS(MCInteractionVolume mcv(sample), std::invalid_argument);
+    TS_ASSERT_THROWS(
+        MCInteractionVolume mcv(sample, sample.getShape().getBoundingBox()),
+        std::invalid_argument);
     // valid shape
     sample.setShape(*ComponentCreationHelper::createSphere(1));
-    TS_ASSERT_THROWS_NOTHING(MCInteractionVolume mcv(sample));
+    TS_ASSERT_THROWS_NOTHING(
+        MCInteractionVolume mcv(sample, sample.getShape().getBoundingBox()));
   }
 };
 
diff --git a/Framework/Algorithms/test/MaskBinsFromTableTest.h b/Framework/Algorithms/test/MaskBinsFromTableTest.h
index c6476453d23efdff5a3306c53ae4437085084cb4..b40be104933f9a1b4be3f219127c4a7554a72dd5 100644
--- a/Framework/Algorithms/test/MaskBinsFromTableTest.h
+++ b/Framework/Algorithms/test/MaskBinsFromTableTest.h
@@ -36,7 +36,7 @@ public:
     const std::string workspaceName("raggedMask");
     int nBins = 10;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     // 2. Generate a TableWorskpace
@@ -84,7 +84,7 @@ public:
     const std::string opWSName("maskedWorkspace");
     int nBins = 10;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     // 2. Generate a TableWorskpace
@@ -134,7 +134,7 @@ public:
     int nBins = 10;
     int nHist = 12;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nHist, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     // 2. Generate a TableWorskpace
@@ -221,7 +221,7 @@ public:
     const std::string workspaceName("raggedMask");
     int nBins = 10;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     // 2. Generate a TableWorskpace
@@ -268,7 +268,7 @@ public:
     const std::string workspaceName("raggedMask5");
     int nBins = 10;
     MatrixWorkspace_sptr dataws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, dataws);
 
     // Find out mapping between spectra/workspace indexes and detectors IDs
diff --git a/Framework/Algorithms/test/MaskBinsTest.h b/Framework/Algorithms/test/MaskBinsTest.h
index 4b8e92be5af2fa6bc7eb988b273be47982b1342d..4214b82b453a24f9666ea64fa4e69ffc399fb9ce 100644
--- a/Framework/Algorithms/test/MaskBinsTest.h
+++ b/Framework/Algorithms/test/MaskBinsTest.h
@@ -34,7 +34,7 @@ public:
     const std::string resultWorkspaceName("masked");
     AnalysisDataServiceImpl &ads = AnalysisDataService::Instance();
     ads.add(workspaceName,
-            WorkspaceCreationHelper::Create2DWorkspaceBinned(5, 25, 0.0));
+            WorkspaceCreationHelper::create2DWorkspaceBinned(5, 25, 0.0));
 
     TS_ASSERT_THROWS_NOTHING(
         masker.setPropertyValue("InputWorkspace", workspaceName));
@@ -90,7 +90,7 @@ public:
     // Create a dummy workspace
     const std::string workspaceName("raggedMask");
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(3, 10, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 0.0);
     // Now change one set of bin boundaries so that the don't match the others
     WS->mutableX(1) += -10;
     AnalysisDataService::Instance().add(workspaceName, WS);
@@ -129,7 +129,7 @@ public:
     // Create a dummy workspace
     const std::string workspaceName("raggedMask");
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 10, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     Mantid::Algorithms::MaskBins masker2;
@@ -150,7 +150,7 @@ public:
     const std::string workspaceName("raggedMask");
     int nBins = 10;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     Mantid::Algorithms::MaskBins masker2;
@@ -182,7 +182,7 @@ public:
 
     int nBins = 10;
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, nBins, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, nBins, 0.0);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     Mantid::Algorithms::MaskBins masker2;
@@ -224,7 +224,7 @@ public:
     int nBins = 10;
     int numHist = 5;
     EventWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateEventWorkspace(numHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(numHist, nBins);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     Mantid::Algorithms::MaskBins masker2;
@@ -259,7 +259,7 @@ public:
     int nBins = 10;
     int numHist = 5;
     EventWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateEventWorkspace(numHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(numHist, nBins);
     AnalysisDataService::Instance().add(workspaceName, WS);
 
     Mantid::Algorithms::MaskBins masker2;
@@ -299,7 +299,7 @@ public:
     int nBins = 10;
     int numHist = 5;
     EventWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateEventWorkspace(numHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(numHist, nBins);
     AnalysisDataService::Instance().add(workspaceName, WS);
     std::size_t events_before = WS->getNumberEvents();
 
@@ -334,7 +334,7 @@ public:
     int nBins = 10;
     int numHist = 5;
     EventWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateEventWorkspace(numHist, nBins);
+        WorkspaceCreationHelper::createEventWorkspace(numHist, nBins);
     AnalysisDataService::Instance().add(workspaceName, WS);
     std::size_t events_before = WS->getNumberEvents();
 
diff --git a/Framework/Algorithms/test/MaxEntTest.h b/Framework/Algorithms/test/MaxEntTest.h
index 0f4a83f63435ff3b1c2668faaee945e4af2a9a33..54777091115be58d830efe04902042e1b2ac422e 100644
--- a/Framework/Algorithms/test/MaxEntTest.h
+++ b/Framework/Algorithms/test/MaxEntTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAlgorithms/MaxEnt.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -44,7 +45,7 @@ public:
     // Run one iteration, we just want to test the output workspaces' dimensions
     int nHist = 5;
     int nBins = 10;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(nHist, nBins);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(nHist, nBins);
 
     IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt");
     alg->initialize();
@@ -78,7 +79,7 @@ public:
     // Run one iteration, we just want to test the output workspaces' dimensions
     int nHist = 6;
     int nBins = 10;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(nHist, nBins);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(nHist, nBins);
 
     IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt");
     alg->initialize();
@@ -111,7 +112,7 @@ public:
 
   void test_bad_complex_data() {
 
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(5, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(5, 10);
 
     IAlgorithm_sptr alg = AlgorithmManager::Instance().create("MaxEnt");
     alg->initialize();
@@ -421,9 +422,9 @@ public:
    */
   void testValidateInputsWithWSGroup() {
     auto ws1 = boost::static_pointer_cast<Workspace>(
-        WorkspaceCreationHelper::Create2DWorkspace(5, 10));
+        WorkspaceCreationHelper::create2DWorkspace(5, 10));
     auto ws2 = boost::static_pointer_cast<Workspace>(
-        WorkspaceCreationHelper::Create2DWorkspace(5, 10));
+        WorkspaceCreationHelper::create2DWorkspace(5, 10));
     AnalysisDataService::Instance().add("workspace1", ws1);
     AnalysisDataService::Instance().add("workspace2", ws2);
     auto group = boost::make_shared<WorkspaceGroup>();
@@ -656,7 +657,7 @@ public:
   static void destroySuite(MaxEntTestPerformance *suite) { delete suite; }
 
   MaxEntTestPerformance() {
-    input = WorkspaceCreationHelper::Create2DWorkspaceBinned(10000, 100);
+    input = WorkspaceCreationHelper::create2DWorkspaceBinned(10000, 100);
     alg = AlgorithmManager::Instance().create("MaxEnt");
   }
 
diff --git a/Framework/Algorithms/test/MaxMinTest.h b/Framework/Algorithms/test/MaxMinTest.h
index c1e57993479048a2dad2e4418320181d73718b9b..fdbcfa4144b53551b20c937abd396f692a2edf4d 100644
--- a/Framework/Algorithms/test/MaxMinTest.h
+++ b/Framework/Algorithms/test/MaxMinTest.h
@@ -1,6 +1,7 @@
 #ifndef MAXMINTEST_H_
 #define MAXMINTEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAlgorithms/CreateWorkspace.h"
 #include "MantidAlgorithms/Max.h"
diff --git a/Framework/Algorithms/test/MayersSampleCorrectionTest.h b/Framework/Algorithms/test/MayersSampleCorrectionTest.h
index cf786e43669ae71563d47ad806add42c0c10b9bc..42052382c30e0d1953648489a7b8dc3a811cf901 100644
--- a/Framework/Algorithms/test/MayersSampleCorrectionTest.h
+++ b/Framework/Algorithms/test/MayersSampleCorrectionTest.h
@@ -109,12 +109,12 @@ private:
     using Mantid::Kernel::Material;
     using Mantid::Kernel::V3D;
     using Mantid::PhysicalConstants::getNeutronAtom;
-    using WorkspaceCreationHelper::Create2DWorkspaceBinned;
+    using WorkspaceCreationHelper::create2DWorkspaceBinned;
 
     const int nhist(1), nbins(100);
     const double xstart(99.5), deltax(1.0);
     // Filled Y with 2.0 and E with sqrt(2)
-    auto testWS = Create2DWorkspaceBinned(nhist, nbins, xstart, deltax);
+    auto testWS = create2DWorkspaceBinned(nhist, nbins, xstart, deltax);
 
     const int nbanks(1);
     // Ids 1->9
@@ -147,7 +147,7 @@ private:
   MatrixWorkspace_sptr createTestWorkspaceWithNoInstrument() {
     const int nhist(1), nbins(1);
     const double xstart(99.5), deltax(1.0);
-    return WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, nbins,
+    return WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins,
                                                             xstart, deltax);
   }
 
@@ -156,11 +156,11 @@ private:
     using Mantid::Geometry::ObjComponent;
     using Mantid::Geometry::Object;
     using Mantid::Kernel::V3D;
-    using WorkspaceCreationHelper::Create2DWorkspaceBinned;
+    using WorkspaceCreationHelper::create2DWorkspaceBinned;
 
     const int nhist(1), nbins(1);
     const double xstart(99.5), deltax(1.0);
-    auto testWS = Create2DWorkspaceBinned(nhist, nbins, xstart, deltax);
+    auto testWS = create2DWorkspaceBinned(nhist, nbins, xstart, deltax);
 
     const int nbanks(1);
     auto testInst = createTestInstrumentCylindrical(nbanks, V3D(0., 0., -14.));
diff --git a/Framework/Algorithms/test/MedianDetectorTestTest.h b/Framework/Algorithms/test/MedianDetectorTestTest.h
index 359fe092b8758787758ab4b92f59f3930f5a18de..474e58505f4663e873a2d6225861f505cfb52540 100644
--- a/Framework/Algorithms/test/MedianDetectorTestTest.h
+++ b/Framework/Algorithms/test/MedianDetectorTestTest.h
@@ -9,10 +9,10 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataHandling/LoadInstrument.h"
-//#include "MantidDataHandling/LoadEmptyInstrument.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/lexical_cast.hpp>
 #include <Poco/File.h>
@@ -230,7 +230,8 @@ public:
     m_2DWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
 
     // mask the detector
-    m_2DWS->maskWorkspaceIndex(THEMASKED);
+    m_2DWS->getSpectrum(THEMASKED).clearData();
+    m_2DWS->mutableSpectrumInfo().setMasked(THEMASKED, true);
   }
 
 private:
diff --git a/Framework/Algorithms/test/MergeRunsTest.h b/Framework/Algorithms/test/MergeRunsTest.h
index 8a6c76ae12501d6da3e410d985f3529f6fd74e07..c4c733eeb321aa99c46642dd11b20db03daf3941 100644
--- a/Framework/Algorithms/test/MergeRunsTest.h
+++ b/Framework/Algorithms/test/MergeRunsTest.h
@@ -55,9 +55,9 @@ private:
   /// matrixworkspaces. BUT WITHOUT MULTIPERIOD LOGS.
   WorkspaceGroup_sptr create_good_workspace_group() {
     MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     MatrixWorkspace_sptr b =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     // a->setName("a1");
     // b->setName("b1");
     WorkspaceGroup_sptr group = boost::make_shared<WorkspaceGroup>();
@@ -74,9 +74,9 @@ private:
   /// matrixworkspaces. BUT WITHOUT MULTIPERIOD LOGS AT ZERO.
   WorkspaceGroup_sptr create_good_zerod_multiperiod_workspace_group() {
     MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     MatrixWorkspace_sptr b =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     // a->setName("a2");
     // b->setName("b2");
     WorkspaceGroup_sptr group = boost::make_shared<WorkspaceGroup>();
@@ -99,9 +99,9 @@ private:
   /// 5
   WorkspaceGroup_sptr create_corrupted_multiperiod_workspace_group() {
     MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     MatrixWorkspace_sptr b =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     // a->setName("a4");
     // b->setName("b4");
     WorkspaceGroup_sptr group = boost::make_shared<WorkspaceGroup>();
@@ -124,9 +124,9 @@ private:
   /// matrixworkspaces.
   WorkspaceGroup_sptr create_good_multiperiod_workspace_group() {
     MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     MatrixWorkspace_sptr b =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     // a->setName("a3");
     // b->setName("b3");
     WorkspaceGroup_sptr group = boost::make_shared<WorkspaceGroup>();
@@ -263,17 +263,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) {
@@ -334,48 +334,48 @@ public:
 
   void EventSetup() {
     ev1 =
-        WorkspaceCreationHelper::CreateEventWorkspace(3, 10, 100, 0.0, 1.0, 3);
+        WorkspaceCreationHelper::createEventWorkspace(3, 10, 100, 0.0, 1.0, 3);
     AnalysisDataService::Instance().addOrReplace(
         "ev1", boost::dynamic_pointer_cast<MatrixWorkspace>(ev1)); // 100 ev
     AnalysisDataService::Instance().addOrReplace(
         "ev2", boost::dynamic_pointer_cast<MatrixWorkspace>(
-                   WorkspaceCreationHelper::CreateEventWorkspace(
+                   WorkspaceCreationHelper::createEventWorkspace(
                        3, 10, 100, 0.0, 1.0, 2))); // 200 ev
     AnalysisDataService::Instance().addOrReplace(
         "ev3", boost::dynamic_pointer_cast<MatrixWorkspace>(
-                   WorkspaceCreationHelper::CreateEventWorkspace(
+                   WorkspaceCreationHelper::createEventWorkspace(
                        3, 10, 100, 0.0, 1.0, 2, 100))); // 200 events per
                                                         // spectrum, but the
                                                         // spectra are at
                                                         // different pixel ids
     // Make one with weird units
     MatrixWorkspace_sptr ev4 = boost::dynamic_pointer_cast<MatrixWorkspace>(
-        WorkspaceCreationHelper::CreateEventWorkspace(3, 10, 100, 0.0, 1.0, 2,
+        WorkspaceCreationHelper::createEventWorkspace(3, 10, 100, 0.0, 1.0, 2,
                                                       100));
     ev4->setYUnit("Microfurlongs per Megafortnights");
     AnalysisDataService::Instance().addOrReplace("ev4_weird_units", ev4);
     AnalysisDataService::Instance().addOrReplace(
         "ev5", boost::dynamic_pointer_cast<MatrixWorkspace>(
-                   WorkspaceCreationHelper::CreateEventWorkspace(
+                   WorkspaceCreationHelper::createEventWorkspace(
                        5, 10, 100, 0.0, 1.0, 2, 100))); // 200 events per
                                                         // spectrum, but the
                                                         // spectra are at
                                                         // different pixel ids
-    ev6 = WorkspaceCreationHelper::CreateEventWorkspace(6, 10, 100, 0.0, 1.0,
+    ev6 = WorkspaceCreationHelper::createEventWorkspace(6, 10, 100, 0.0, 1.0,
                                                         3); // ids 0-5
     AnalysisDataService::Instance().addOrReplace(
         "ev6", boost::dynamic_pointer_cast<MatrixWorkspace>(ev6));
     // a 2d workspace with the value 2 in each bin
     AnalysisDataService::Instance().addOrReplace(
         "in2D",
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(3, 10, 0.0, 1.0));
+        WorkspaceCreationHelper::create2DWorkspaceBinned(3, 10, 0.0, 1.0));
 
     std::vector<std::vector<int>> groups;
 
     groups.clear();
     groups.push_back(makeVector(3, 0, 1, 2));
     groups.push_back(makeVector(3, 3, 4, 5));
-    evg1 = WorkspaceCreationHelper::CreateGroupedEventWorkspace(groups, 100);
+    evg1 = WorkspaceCreationHelper::createGroupedEventWorkspace(groups, 100);
     AnalysisDataService::Instance().addOrReplace(
         "evg1", boost::dynamic_pointer_cast<MatrixWorkspace>(evg1));
 
@@ -391,7 +391,7 @@ public:
     groups.push_back(makeVector(2, 3, 4));
     groups.push_back(makeVector(3, 0, 1, 2));
     groups.push_back(makeVector(1, 15));
-    evg2 = WorkspaceCreationHelper::CreateGroupedEventWorkspace(groups, 100);
+    evg2 = WorkspaceCreationHelper::createGroupedEventWorkspace(groups, 100);
     AnalysisDataService::Instance().addOrReplace(
         "evg2", boost::dynamic_pointer_cast<MatrixWorkspace>(evg2));
   }
@@ -736,7 +736,7 @@ public:
     TS_ASSERT_THROWS(merge2.execute(), std::runtime_error);
     TS_ASSERT(!merge2.isExecuted());
     MatrixWorkspace_sptr badIn =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     badIn->mutableX(0) = 2.0;
     AnalysisDataService::Instance().add("badIn", badIn);
     TS_ASSERT_THROWS_ANYTHING(
diff --git a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
index e649c9e93b206e9afc08db7d91fbf3ff34d4805d..702ff7361a4615842e9e74fa7f0f8e3014755aa6 100644
--- a/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
+++ b/Framework/Algorithms/test/MonteCarloAbsorptionTest.h
@@ -98,15 +98,15 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.019012, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0021002, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.00010066, outputWS->y(0).back(), delta);
-    TS_ASSERT_DELTA(0.019074, outputWS->y(2).front(), delta);
-    TS_ASSERT_DELTA(0.001629, outputWS->y(2)[middle_index], delta);
-    TS_ASSERT_DELTA(9.4268e-05, outputWS->y(2).back(), delta);
-    TS_ASSERT_DELTA(0.019256, outputWS->y(4).front(), delta);
-    TS_ASSERT_DELTA(0.0014369, outputWS->y(4)[middle_index], delta);
-    TS_ASSERT_DELTA(9.8238e-05, outputWS->y(4).back(), delta);
+    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);
   }
 
   void test_Workspace_With_Just_Sample_For_Direct() {
@@ -119,9 +119,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0087756, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0031353, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.00087368, outputWS->y(0).back(), delta);
+    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);
   }
 
   void test_Workspace_With_Just_Sample_For_Indirect() {
@@ -134,9 +134,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.0038337, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0013434, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.00019552, outputWS->y(0).back(), delta);
+    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);
   }
 
   void test_Workspace_With_Sample_And_Container() {
@@ -149,9 +149,9 @@ public:
     const double delta(1e-05);
     const size_t middle_index(4);
 
-    TS_ASSERT_DELTA(0.016547, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0022329, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(0.00024214, outputWS->y(0).back(), delta);
+    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);
   }
 
   void test_Workspace_Beam_Size_Set() {
@@ -163,10 +163,10 @@ public:
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
     const size_t middle_index(4);
-
-    TS_ASSERT_DELTA(0.0045478, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.00036224, outputWS->y(0)[middle_index], delta);
-    TS_ASSERT_DELTA(6.5735e-05, outputWS->y(0).back(), delta);
+    TS_ASSERT_DELTA(0.004365258, outputWS->y(0).front(), delta);
+    TS_ASSERT_DELTA(9.8703289e-05, outputWS->y(0)[middle_index], delta);
+    const double delta2(1e-08);
+    TS_ASSERT_DELTA(1.7373459e-08, outputWS->y(0).back(), delta2);
   }
 
   void test_Linear_Interpolation() {
@@ -179,10 +179,10 @@ public:
 
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
-    TS_ASSERT_DELTA(0.019012, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0044149, outputWS->y(0)[3], delta);
-    TS_ASSERT_DELTA(0.0026940, outputWS->y(0)[4], delta);
-    TS_ASSERT_DELTA(0.00042886, outputWS->y(0).back(), delta);
+    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);
   }
 
   void test_CSpline_Interpolation() {
@@ -195,10 +195,11 @@ public:
 
     verifyDimensions(wsProps, outputWS);
     const double delta(1e-05);
-    TS_ASSERT_DELTA(0.019012, outputWS->y(0).front(), delta);
-    TS_ASSERT_DELTA(0.0036653, outputWS->y(0)[3], delta);
-    TS_ASSERT_DELTA(0.0026940, outputWS->y(0)[4], delta);
-    TS_ASSERT_DELTA(0.00042886, outputWS->y(0).back(), delta);
+    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);
   }
 
   //---------------------------------------------------------------------------
@@ -209,7 +210,7 @@ public:
 
     auto mcAbsorb = createAlgorithm();
     // Create a simple test workspace that has no instrument
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace(1, 1);
 
     TS_ASSERT_THROWS(mcAbsorb->setProperty("InputWorkspace", testWS),
                      std::invalid_argument);
diff --git a/Framework/Algorithms/test/MonteCarloTesting.h b/Framework/Algorithms/test/MonteCarloTesting.h
index 7d9e296a4e05d4bf9be50075e530e52bbda7dd22..249d477724744ade2eb0ee478bbf7d0ef1950acb 100644
--- a/Framework/Algorithms/test/MonteCarloTesting.h
+++ b/Framework/Algorithms/test/MonteCarloTesting.h
@@ -8,6 +8,7 @@
 #include "MantidKernel/Material.h"
 #include "MantidKernel/PseudoRandomNumberGenerator.h"
 #include "MantidKernel/WarningSuppressions.h"
+#include "MantidKernel/make_unique.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
 #include <gmock/gmock.h>
diff --git a/Framework/Algorithms/test/MultipleScatteringCylinderAbsorptionTest.h b/Framework/Algorithms/test/MultipleScatteringCylinderAbsorptionTest.h
index 61c675dc867704ade168a81cfb7d89d0b742042c..eaafc4b956cb5093ec13ed2ec68ba0fc5088c46e 100644
--- a/Framework/Algorithms/test/MultipleScatteringCylinderAbsorptionTest.h
+++ b/Framework/Algorithms/test/MultipleScatteringCylinderAbsorptionTest.h
@@ -64,7 +64,7 @@ public:
   void testCalculationHist() {
     // setup the test workspace
     Workspace2D_sptr wksp =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(9, 16, 1000, 1000);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(9, 16, 1000, 1000);
     wksp->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(1));
     wksp->getAxis(0)->setUnit("TOF");
diff --git a/Framework/Algorithms/test/MultiplyDivideTest.in.h b/Framework/Algorithms/test/MultiplyDivideTest.in.h
index 37e0b89832f1666850256d671c46f6491cf204fb..c185ea41dc7bcc1c77db57916a46401142609f55 100644
--- a/Framework/Algorithms/test/MultiplyDivideTest.in.h
+++ b/Framework/Algorithms/test/MultiplyDivideTest.in.h
@@ -11,6 +11,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidDataObjects/EventWorkspaceHelpers.h"
@@ -23,7 +24,7 @@ using Mantid::Geometry::IDetector_const_sptr;
 
 /*****************************************************************************************/
 /********** PLEASE NOTE! THIS FILE WAS AUTO-GENERATED FROM CMAKE.  ***********************/
-/********** Source = MultiplyDivideTest.h.in *********************************************/
+/********** Source = MultiplyDivideTest.in.h *********************************************/
 /*****************************************************************************************/
 
 class @MULTIPLYDIVIDETEST_CLASS@ : public CxxTest::TestSuite
@@ -42,11 +43,11 @@ public:
   {
     DO_DIVIDE = @MULTIPLYDIVIDETEST_DO_DIVIDE@;
 
-    fibWS1d = WorkspaceCreationHelper::Create1DWorkspaceFib(5);
-    histWS_5x10_123 = WorkspaceCreationHelper::Create2DWorkspace123(5,10);
-    histWS_5x10_154 = WorkspaceCreationHelper::Create2DWorkspace154(5,10);
-    histWS_5x10_bin = WorkspaceCreationHelper::Create2DWorkspace(5,10);
-    eventWS_5x10_50 = WorkspaceCreationHelper::CreateEventWorkspace(5,10,50,0.0,1.0,2);
+    fibWS1d = WorkspaceCreationHelper::create1DWorkspaceFib(5);
+    histWS_5x10_123 = WorkspaceCreationHelper::create2DWorkspace123(5,10);
+    histWS_5x10_154 = WorkspaceCreationHelper::create2DWorkspace154(5,10);
+    histWS_5x10_bin = WorkspaceCreationHelper::create2DWorkspace(5,10);
+    eventWS_5x10_50 = WorkspaceCreationHelper::createEventWorkspace(5,10,50,0.0,1.0,2);
   }
 
 
@@ -84,9 +85,9 @@ public:
   void testCompoundAssignment()
   {
 
-    MatrixWorkspace_sptr a = WorkspaceCreationHelper::CreateWorkspaceSingleValue(3);
+    MatrixWorkspace_sptr a = WorkspaceCreationHelper::createWorkspaceSingleValue(3);
     const Workspace_const_sptr b = a;
-    MatrixWorkspace_sptr c = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2);
+    MatrixWorkspace_sptr c = WorkspaceCreationHelper::createWorkspaceSingleValue(2);
     if (DO_DIVIDE)
     {
       a /= 5;
@@ -125,7 +126,7 @@ public:
 
   void test_2D_2D_inPlace()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(5,10);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(5,10);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_bin;
     performTest(work_in1,work_in2, false /*not event*/,
         DO_DIVIDE ? 1.0 : 4.0, DO_DIVIDE ? 1.0 : 4.0, false, false, true /*in place*/);
@@ -136,8 +137,8 @@ public:
     if(DO_DIVIDE)
     {
     int nHist = 5,nBins=5;
-    MatrixWorkspace_sptr numerator  = WorkspaceCreationHelper::Create2DWorkspace123(nHist-1,nBins); // Cropped
-    MatrixWorkspace_sptr denominator = WorkspaceCreationHelper::Create2DWorkspace123(nHist, 1); // Integrated
+    MatrixWorkspace_sptr numerator  = WorkspaceCreationHelper::create2DWorkspace123(nHist-1,nBins); // Cropped
+    MatrixWorkspace_sptr denominator = WorkspaceCreationHelper::create2DWorkspace123(nHist, 1); // Integrated
     Divide alg;
     alg.initialize();
     alg.setChild(true);
@@ -156,8 +157,8 @@ public:
     for (int inplace=0; inplace<2; inplace++)
     {
       int nHist = 5,nBins=10;
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(nHist,1);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(nHist,1);
       performTest(work_in1,work_in2, false /*not event*/,
           DO_DIVIDE ? 1.0 : 4.0, DO_DIVIDE ? 1.0 : 4.0, false, false, inplace!=0 /*in place*/);
     }
@@ -166,15 +167,15 @@ public:
   void test_1D_Rand2D()
   {
     int nHist = 5,nBins=5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace154(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create1DWorkspaceRand(nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace154(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create1DWorkspaceRand(nBins);
     performTest(work_in1,work_in2);
   }
 
   void test_2D_1DVertical()
   {
     MatrixWorkspace_sptr work_in1 = histWS_5x10_154;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace123(1,10);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace123(1,10);
     performTest(work_in1,work_in2);
   }
 
@@ -182,8 +183,8 @@ public:
   {
     //In 2D workspaces, the X bins have to match
     int nHist = 20,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace123(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace154(1,nBins*5);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace123(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace154(1,nBins*5);
     performTest_fails(work_in1, work_in2);
   }
 
@@ -218,7 +219,7 @@ public:
 
   void test_2D_2DbyOperatorOverload_inPlace()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(5,10);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(5,10);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_bin;
     MatrixWorkspace_sptr work_out1;
     if (DO_DIVIDE)
@@ -237,15 +238,15 @@ public:
   void test_1D_SingleValue()
   {
     MatrixWorkspace_sptr work_in1 = fibWS1d;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.2);
     performTest(work_in1,work_in2);
   }
 
   void test_SingleValue_1D()
   {
     int nBins = 5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(10.0);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(10.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1,nBins);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2,false,
           5.0, 3.8729, false, true /*commutes*/);
@@ -258,8 +259,8 @@ public:
     for (int inplace=0; inplace<2; inplace++)
     {
       int nHist = 5,nBins=10;
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
       performTest(work_in1,work_in2, false /*not event*/,
           DO_DIVIDE ? 1.0 : 4.0, DO_DIVIDE ? 1.0 : 4.0, false, false, inplace!=0 /*in place*/);
     }
@@ -267,7 +268,7 @@ public:
 
   void test_SingleValue_2D()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(10.0);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(10.0);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_bin;
     if (DO_DIVIDE)
       performTest(work_in1,work_in2,false,
@@ -279,7 +280,7 @@ public:
   void test_2D_SingleValueNoError()
   {
     MatrixWorkspace_sptr work_in1 = histWS_5x10_bin;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValueWithError(5.0, 0.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValueWithError(5.0, 0.0);
     performTest(work_in1,work_in2);
   }
 
@@ -299,8 +300,8 @@ public:
   void test_1DVertical_EventWithOneBin_willCommute()
   {
     int nBins=1,nHist=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist, nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist, nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event */, 1.0, 1.0, false, false, false /* not in place */);
     else
@@ -310,8 +311,8 @@ public:
   void test_1DVertical_EventWithOneBin_willCommute_inplace()
   {
     int nBins=1,nHist=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist, nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist, nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event */, 1.0, 1.0, false, false, true /*in place*/);
     else
@@ -320,7 +321,7 @@ public:
 
   void test_2D_Event_inPlace()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(5,10);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(5,10);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event */, 1.0, sqrt(1.0), false, false, true);
@@ -331,7 +332,7 @@ public:
   void test_2D_Event_RHSEventWorkspaceHasOnebin()
   {
     MatrixWorkspace_sptr work_in1 = histWS_5x10_bin;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(5, 1,50,0.0,100.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(5, 1,50,0.0,100.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event */, 1.0, sqrt(1.0), false, false, false);
     else
@@ -341,8 +342,8 @@ public:
   void test_2D_Event_inPlace_RHSEventWorkspaceHasOnebin()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist, 1,50,0.0,100.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist, 1,50,0.0,100.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event */, 1.0, sqrt(1.0), false, false, true);
     else
@@ -352,8 +353,8 @@ public:
   void test_2D_Event_inPlace_RHSEventWorkspaceHasOnebinAndOneSpectrum()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(1, 1,50,0.0,100.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(1, 1,50,0.0,100.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*output is not Event*/, 1.0, sqrt(1.0), false, false, true);
     else
@@ -363,8 +364,8 @@ public:
   void test_Event_2D_inplace_LHSEventWorkspaceHasOnebin()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist, 1, 2, 0.0, 1.0, 2); // Events are at 0.5
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist, 1, 2, 0.0, 1.0, 2); // Events are at 0.5
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true /*output is Event */, 1.0, 0.8660, false, false, true);
     else
@@ -375,8 +376,8 @@ public:
   void test_Event_2D_inplace_LHSEventWorkspaceHasOnebinAndOneSpectrum()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(1, 1, 2, 0.0, 1.0, 2); // Events are at 0.5
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(1, 1, 2, 0.0, 1.0, 2); // Events are at 0.5
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
     if (DO_DIVIDE)
       performTest_fails(work_in1,work_in2); // Incompatible sizes
     else
@@ -397,8 +398,8 @@ public:
   void test_Event_2D_inPlace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75), false, false, true);
     else
@@ -412,7 +413,7 @@ public:
   void test_Event_2DSingleSpectrum()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75));
     else
@@ -422,8 +423,8 @@ public:
   void test_Event_2DSingleSpectrum_inPlace()
   {
     int nHist = 10,nBins=20;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,100,0.0,1.0,2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1, nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,100,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1, nBins);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75), false, false, true /* in-place */);
     else
@@ -434,7 +435,7 @@ public:
   {
     //Unlike 2D workspaces, you can divide by a single spectrum with different X bins!
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1, 5*2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1, 5*2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75));
     else
@@ -443,7 +444,7 @@ public:
 
   void test_2DSingleSpectrum_Event()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     if (DO_DIVIDE)
       performTest_fails(work_in1,work_in2); /* Fails for dividing, since you can't commute */
@@ -454,8 +455,8 @@ public:
   void test_2DSingleSpectrum_Event_inPlace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(1, nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(1, nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest_fails(work_in1,work_in2); /* Fails for dividing, since you can't commute */
     else
@@ -466,8 +467,8 @@ public:
   {
     //Unlike 2D workspaces, you can divide by a single spectrum with different X bins!
     int nBins = 5,nHist=5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(1, nHist*2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nBins,nHist,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(1, nHist*2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nBins,nHist,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest_fails(work_in1,work_in2); /* Fails for dividing, since you can't commute */
     else
@@ -478,8 +479,8 @@ public:
   {
     //Unlike 2D workspaces, you can divide by a single spectrum with different X bins!
     int nBins = 5,nHist=5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(1, nBins*2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nBins,nHist,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(1, nBins*2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nBins,nHist,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest_fails(work_in1,work_in2); /* Fails for dividing, since you can't commute */
     else
@@ -489,7 +490,7 @@ public:
   void test_Event_SingleValue()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75));
     else
@@ -499,8 +500,8 @@ public:
   void test_Event_SingleValue_inPlace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75), false, false, true /* in-place */);
     else
@@ -510,8 +511,8 @@ public:
   void test_SingleValue_Event()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(10.0);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(10.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*NOT events*/,
           5.0, 3.8729, false, true /*commutes*/);
@@ -523,8 +524,8 @@ public:
   {
     // Doing in-place on a single value is silly since it just gets overwritten, but it works!
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, false /*NOT events*/,
           1.0, 1.0, false, true /*commutes*/);
@@ -535,7 +536,7 @@ public:
   void test_Event_SingleValueNoError()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValueWithError(2.0, 0.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValueWithError(2.0, 0.0);
     performTest(work_in1,work_in2, true);
   }
 
@@ -552,8 +553,8 @@ public:
   void test_Event_Event_inPlace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
     if (DO_DIVIDE)
       performTest(work_in1,work_in2, true, 1.0, sqrt(0.75), false, false, true /* in-place */);
     else
@@ -585,13 +586,13 @@ public:
       rhs[i/rhs_grouping].push_back(i);
     }
     // Grouped workspace will have lhs_grouping events in each bin (also).
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateGroupedEventWorkspace(lhs, 10, 1.0);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createGroupedEventWorkspace(lhs, 10, 1.0);
     if (lhs2D)
       work_in1 = EventWorkspaceHelpers::convertEventTo2D(work_in1);
     TS_ASSERT_DELTA( work_in1->readE(0)[0], sqrt( double(lhs_grouping*1.0) ), 1e-5);
 
     // Grouped workspace will have rhs_grouping events in each bin (also).
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateGroupedEventWorkspace(rhs, 10, 1.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createGroupedEventWorkspace(rhs, 10, 1.0);
     if (rhs2D)
       work_in2 = EventWorkspaceHelpers::convertEventTo2D(work_in2);
     TS_ASSERT_DELTA( work_in2->readE(0)[0], sqrt( double(rhs_grouping*1.0) ), 1e-5);
@@ -917,8 +918,8 @@ public:
     masking.insert(2);
     masking.insert(7);
 
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace123(nHist,nBins, 0, masking);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace154(nHist,nBins, 0, masking);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace123(nHist,nBins, 0, masking);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace154(nHist,nBins, 0, masking);
     const std::string lhs("work_in1"), rhs("work_in2");
     AnalysisDataService::Instance().add(lhs, work_in1);
     AnalysisDataService::Instance().add(rhs, work_in2);
@@ -956,18 +957,17 @@ public:
     MatrixWorkspace_sptr output = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>("work_in1");
     TS_ASSERT(output);
 
+    const auto &spectrumInfo = output->spectrumInfo();
     for( int i = 0; i < nHist; ++i )
     {
-      IDetector_const_sptr det = output->getDetector(i);
-      TS_ASSERT(det);
-      if( !det ) TS_FAIL("No detector found");
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if( masking.count(i) == 0 )
       {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
       }
       else
       {
-        TS_ASSERT_EQUALS(det->isMasked(), true);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
         double yValue = output->readY(i)[0];
         TS_ASSERT_EQUALS(yValue, yValue );
         TS_ASSERT( !std::isinf(yValue) );
diff --git a/Framework/Algorithms/test/MultiplyRangeTest.h b/Framework/Algorithms/test/MultiplyRangeTest.h
index 0f5af7a9b103748cb1e17cdcf058713f70a52a9c..95bc78af4f70b6bcfbb745ee2d1554b6b7af1a03 100644
--- a/Framework/Algorithms/test/MultiplyRangeTest.h
+++ b/Framework/Algorithms/test/MultiplyRangeTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/MultiplyRange.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
diff --git a/Framework/Algorithms/test/MuonGroupDetectorsTest.h b/Framework/Algorithms/test/MuonGroupDetectorsTest.h
index cb318bf170d63f9022a077f633fd2c7279a7f329..b59025c97719804a48a288349d16a781a8ef509c 100644
--- a/Framework/Algorithms/test/MuonGroupDetectorsTest.h
+++ b/Framework/Algorithms/test/MuonGroupDetectorsTest.h
@@ -35,7 +35,7 @@ public:
     const std::string outWSName("MuonGroupDetectorsTest_OutputWS");
 
     MatrixWorkspace_sptr inWS =
-        WorkspaceCreationHelper::Create2DWorkspace123(5, 3);
+        WorkspaceCreationHelper::create2DWorkspace123(5, 3);
 
     for (size_t i = 0; i < inWS->getNumberHistograms(); ++i)
       inWS->getSpectrum(i).setDetectorID(static_cast<detid_t>(
diff --git a/Framework/Algorithms/test/NormaliseByCurrentTest.h b/Framework/Algorithms/test/NormaliseByCurrentTest.h
index 33d772f65e5ecb0d08079f1b25d44eafdda4d7e5..aec6785889a70e7514d372e424c528d5fae4f41b 100644
--- a/Framework/Algorithms/test/NormaliseByCurrentTest.h
+++ b/Framework/Algorithms/test/NormaliseByCurrentTest.h
@@ -139,7 +139,7 @@ public:
 
   void test_exec() {
     AnalysisDataService::Instance().add(
-        "normIn", WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 3, 1));
+        "normIn", WorkspaceCreationHelper::create2DWorkspaceBinned(10, 3, 1));
     doTest("normIn", "normOut", 1.0, 0.5 * M_SQRT2);
     AnalysisDataService::Instance().remove("normIn");
     AnalysisDataService::Instance().remove("normOut");
@@ -152,17 +152,17 @@ public:
     // uniform error value of 3.0.
 
     MatrixWorkspace_sptr a =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     a->setYUnit("Counts");
     addMultiPeriodLogsTo(a, 1, protonChargeByPeriod);
 
     MatrixWorkspace_sptr b =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     b->setYUnit("Counts");
     addMultiPeriodLogsTo(b, 2, protonChargeByPeriod);
 
     MatrixWorkspace_sptr c =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     c->setYUnit("Counts");
     addMultiPeriodLogsTo(c, 3, protonChargeByPeriod);
 
@@ -177,7 +177,7 @@ public:
     const std::string protonChargeByPeriod = "2.0, 4.0, 8.0";
 
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     ws->setYUnit("Counts");
     addMultiPeriodLogsTo(ws, 1, protonChargeByPeriod); // If this worked, we
                                                        // would be normalising
@@ -194,7 +194,7 @@ public:
     const std::string protonChargeByPeriod = "2.0, 4.0, 8.0";
 
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     ws->setYUnit("Counts");
     addMultiPeriodLogsTo(ws, 1, protonChargeByPeriod); // If this worked, we
                                                        // would be normalising
@@ -212,7 +212,7 @@ public:
     const std::string protonChargeByPeriod = "2.0, 4.0";
 
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     ws->setYUnit("Counts");
     addMultiPeriodLogsTo(ws, 1, protonChargeByPeriod); // If this worked, we
                                                        // would be normalising
@@ -229,7 +229,7 @@ public:
   void testThrowsWithoutCURRENT_PERIOD_Log() {
     const std::string protonChargeByPeriod = "2.0, 4.0, 8.0";
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     ws->setYUnit("Counts");
     addMultiPeriodLogsTo(ws, 1, protonChargeByPeriod); // If this worked, we
                                                        // would be normalising
@@ -252,7 +252,7 @@ public:
   void testThrowsWithoutPROTON_CHARGE_BY_PERIOD_Log() {
     const std::string protonChargeByPeriod = "2.0, 4.0, 8.0";
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     ws->setYUnit("Counts");
     addMultiPeriodLogsTo(ws, 1, protonChargeByPeriod); // If this worked, we
                                                        // would be normalising
@@ -277,7 +277,7 @@ public:
 
   void test_execInPlace() {
     AnalysisDataService::Instance().add(
-        "normIn", WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 3, 1));
+        "normIn", WorkspaceCreationHelper::create2DWorkspaceBinned(10, 3, 1));
     doTest("normIn", "normIn", 1.0, 0.5 * M_SQRT2);
     AnalysisDataService::Instance().remove("normIn");
   }
@@ -285,7 +285,7 @@ public:
   void test_execEvent() {
     AnalysisDataService::Instance().add(
         "normInEvent",
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 3, 100, 0.0, 1.0, 2));
+        WorkspaceCreationHelper::createEventWorkspace(10, 3, 100, 0.0, 1.0, 2));
 
     EventWorkspace_const_sptr outputEvent;
     outputEvent = boost::dynamic_pointer_cast<const EventWorkspace>(
@@ -300,7 +300,7 @@ public:
   void test_execEventInPlace() {
     AnalysisDataService::Instance().add(
         "normInEvent",
-        WorkspaceCreationHelper::CreateEventWorkspace(10, 3, 100, 0.0, 1.0, 2));
+        WorkspaceCreationHelper::createEventWorkspace(10, 3, 100, 0.0, 1.0, 2));
 
     EventWorkspace_const_sptr outputEvent;
     outputEvent = boost::dynamic_pointer_cast<const EventWorkspace>(
@@ -313,7 +313,7 @@ public:
 
   void test_execZero() {
     AnalysisDataService::Instance().add(
-        "normIn", WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1));
+        "normIn", WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1));
 
     NormaliseByCurrent norm1;
     norm1.initialize();
@@ -359,21 +359,21 @@ public:
     // test_execPerformance
     AnalysisDataService::Instance().add(
         execWSIn,
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist, nBins, 1));
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nHist, nBins, 1));
 
     // test_execInPlacePerformance
     AnalysisDataService::Instance().add(
         execInPlaceWSIn,
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist, nBins, 1));
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nHist, nBins, 1));
 
     // test_execEventPerformance
     AnalysisDataService::Instance().add(
-        execEventWSIn, WorkspaceCreationHelper::CreateEventWorkspace(
+        execEventWSIn, WorkspaceCreationHelper::createEventWorkspace(
                            nHist, nBins, nPixels, 0.0, 1.0, 2));
 
     // test_execEventInPlacePerformance
     AnalysisDataService::Instance().add(
-        execEventInPlaceWSIn, WorkspaceCreationHelper::CreateEventWorkspace(
+        execEventInPlaceWSIn, WorkspaceCreationHelper::createEventWorkspace(
                                   nHist, nBins, nPixels, 0.0, 1.0, 2));
 
     // test_multiPeriodDataPerformance
@@ -382,17 +382,17 @@ public:
     // Note that CreateWorkspace123 creates uniform signal value of 2.0, and
     // uniform error value of 3.0.
     multiPeriodWS1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins, 1);
     multiPeriodWS1->setYUnit("Counts");
     addMultiPeriodLogsTo(multiPeriodWS1, 1, protonChargeByPeriod);
 
     multiPeriodWS2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins, 1);
     multiPeriodWS2->setYUnit("Counts");
     addMultiPeriodLogsTo(multiPeriodWS2, 2, protonChargeByPeriod);
 
     multiPeriodWS3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins, 1);
     multiPeriodWS3->setYUnit("Counts");
     addMultiPeriodLogsTo(multiPeriodWS3, 3, protonChargeByPeriod);
   }
diff --git a/Framework/Algorithms/test/NormaliseToMonitorTest.h b/Framework/Algorithms/test/NormaliseToMonitorTest.h
index d25254cc9933d206e58da00a49ae110ec564161c..13f0ff9d816b07c3f607e243f14479b0564f97d8 100644
--- a/Framework/Algorithms/test/NormaliseToMonitorTest.h
+++ b/Framework/Algorithms/test/NormaliseToMonitorTest.h
@@ -20,7 +20,7 @@ using Mantid::Geometry::Instrument;
 namespace {
 void setUpWorkspace(int histograms = 3, int bins = 10) {
   MatrixWorkspace_sptr input =
-      WorkspaceCreationHelper::Create2DWorkspace123(histograms, bins, 1);
+      WorkspaceCreationHelper::create2DWorkspace123(histograms, bins, 1);
   // Change the data in the monitor spectrum
   input->mutableY(0).assign(bins, 10.0);
   // Need to change bins
@@ -42,7 +42,6 @@ void setUpWorkspace(int histograms = 3, int bins = 10) {
   input->getSpectrum(1).setSpectrumNo(1);
   input->getSpectrum(2).setSpectrumNo(2);
   boost::shared_ptr<Instrument> instr = boost::make_shared<Instrument>();
-  input->setInstrument(instr);
   Mantid::Geometry::Detector *mon =
       new Mantid::Geometry::Detector("monitor", 0, NULL);
   instr->add(mon);
@@ -51,12 +50,13 @@ void setUpWorkspace(int histograms = 3, int bins = 10) {
       new Mantid::Geometry::Detector("NOTmonitor", 1, NULL);
   instr->add(det);
   instr->markAsDetector(det);
+  input->setInstrument(instr);
 
   AnalysisDataService::Instance().addOrReplace("normMon", input);
 
   // Create a single spectrum workspace to be the monitor one
   MatrixWorkspace_sptr monWS =
-      WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 20, 0.1, 0.5);
+      WorkspaceCreationHelper::create2DWorkspaceBinned(1, 20, 0.1, 0.5);
   monWS->getAxis(0)->unit() =
       Mantid::Kernel::UnitFactory::Instance().create("Wavelength");
   // Now need to set up a minimal instrument and spectra-detector map
@@ -395,7 +395,7 @@ public:
     // now deal with ws without monitors
     // create ws without monitors.
     MatrixWorkspace_sptr input =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 10, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 10, 1);
     boost::shared_ptr<Instrument> instr = boost::make_shared<Instrument>();
     input->setInstrument(instr);
     AnalysisDataService::Instance().add("someWS", input);
diff --git a/Framework/Algorithms/test/OneMinusExponentialCorTest.h b/Framework/Algorithms/test/OneMinusExponentialCorTest.h
index 87155739a4789dd704af1f5aecb17413ea6eb79d..7e478f782088289b4b34a6be85e12430ca5886fe 100644
--- a/Framework/Algorithms/test/OneMinusExponentialCorTest.h
+++ b/Framework/Algorithms/test/OneMinusExponentialCorTest.h
@@ -54,7 +54,7 @@ public:
 
   void testDivide() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::OneMinusExponentialCor expon3;
@@ -91,7 +91,7 @@ public:
 
   void testDivideWithPrefactor() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::OneMinusExponentialCor expon3;
@@ -130,7 +130,7 @@ public:
 
   void testMultiply() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::OneMinusExponentialCor expon3;
@@ -168,7 +168,7 @@ public:
 
   void testMultiplyWithPrefactor() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     Mantid::Algorithms::OneMinusExponentialCor expon3;
@@ -207,7 +207,7 @@ public:
   }
 
   void testEvents() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     AnalysisDataService::Instance().add("test_ev_omec", evin);
diff --git a/Framework/Algorithms/test/PDCalibrationTest.h b/Framework/Algorithms/test/PDCalibrationTest.h
index 650cfadc4b9bd85a643df3c5f5b31d768470c417..c9ba6ec54b2f7f6dd0281e979e8dc17b7c34a528 100644
--- a/Framework/Algorithms/test/PDCalibrationTest.h
+++ b/Framework/Algorithms/test/PDCalibrationTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/Algorithms/test/PerformIndexOperationsTest.h b/Framework/Algorithms/test/PerformIndexOperationsTest.h
index da5036892cc04d50f542b3c92b46f983e5396561..b8554d36c142268a841d26024f301a21136aa4c6 100644
--- a/Framework/Algorithms/test/PerformIndexOperationsTest.h
+++ b/Framework/Algorithms/test/PerformIndexOperationsTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/PerformIndexOperations.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 using Mantid::Algorithms::PerformIndexOperations;
diff --git a/Framework/Algorithms/test/PhaseQuadMuonTest.h b/Framework/Algorithms/test/PhaseQuadMuonTest.h
index ec8dfc94a65b43a12950ba7b39ebef118e30d0ff..0bef833612188a0b3c22b33381d26448bda8dcda 100644
--- a/Framework/Algorithms/test/PhaseQuadMuonTest.h
+++ b/Framework/Algorithms/test/PhaseQuadMuonTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataObjects/TableWorkspace.h"
@@ -133,4 +134,4 @@ private:
   IAlgorithm_sptr phaseQuad;
 };
 
-#endif /* MANTID_ALGORITHMS_PHASEQUADMUONTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_PHASEQUADMUONTEST_H_ */
diff --git a/Framework/Algorithms/test/PlusMinusTest.in.h b/Framework/Algorithms/test/PlusMinusTest.in.h
index c58ae6c369e0e266ce03d3e0a1330fe59c145c5d..2f7391d33ff1c93a12279564a388d35400de4391 100644
--- a/Framework/Algorithms/test/PlusMinusTest.in.h
+++ b/Framework/Algorithms/test/PlusMinusTest.in.h
@@ -23,7 +23,7 @@ using namespace Mantid::DataObjects;
 
 /*****************************************************************************************/
 /********** PLEASE NOTE! THIS FILE WAS AUTO-GENERATED FROM CMAKE.  ***********************/
-/********** Source = PlusMinusTest.h.in **************************************************/
+/********** Source = PlusMinusTest.in.h **************************************************/
 /*****************************************************************************************/
 
 class @PLUSMINUSTEST_CLASS@ : public CxxTest::TestSuite
@@ -43,12 +43,12 @@ public:
     wsNameOut = "MinusTest_outputWorkspace";
     DO_PLUS = @PLUSMINUSTEST_DO_PLUS@;
 
-    fibWS1d = WorkspaceCreationHelper::Create1DWorkspaceFib(5);
-    histWS_5x10_123 = WorkspaceCreationHelper::Create2DWorkspace123(5,10);
-    histWS_5x10_154 = WorkspaceCreationHelper::Create2DWorkspace154(5,10);
-    histWS_5x10_bin = WorkspaceCreationHelper::Create2DWorkspace(5,10);
-    eventWS_5x10_50 = WorkspaceCreationHelper::CreateEventWorkspace(5,10,50,0.0,1.0,2);
-    eventWS_small = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    fibWS1d = WorkspaceCreationHelper::create1DWorkspaceFib(5);
+    histWS_5x10_123 = WorkspaceCreationHelper::create2DWorkspace123(5,10);
+    histWS_5x10_154 = WorkspaceCreationHelper::create2DWorkspace154(5,10);
+    histWS_5x10_bin = WorkspaceCreationHelper::create2DWorkspace(5,10);
+    eventWS_5x10_50 = WorkspaceCreationHelper::createEventWorkspace(5,10,50,0.0,1.0,2);
+    eventWS_small = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
   }
 
   void testInit()
@@ -82,9 +82,9 @@ public:
 
   void test_CompoundAssignment()
   {
-    Workspace2D_sptr a = WorkspaceCreationHelper::Create2DWorkspace(5,5);
+    Workspace2D_sptr a = WorkspaceCreationHelper::create2DWorkspace(5,5);
     const Workspace_const_sptr b = a;
-    Workspace2D_sptr c = WorkspaceCreationHelper::Create2DWorkspace(5,5);
+    Workspace2D_sptr c = WorkspaceCreationHelper::create2DWorkspace(5,5);
     if (DO_PLUS)
     {
       a += 5;
@@ -129,9 +129,9 @@ public:
   {
     if (DO_PLUS)
     {
-      MatrixWorkspace_sptr a = WorkspaceCreationHelper::CreateWorkspaceSingleValue(3);
+      MatrixWorkspace_sptr a = WorkspaceCreationHelper::createWorkspaceSingleValue(3);
       a->mutableRun().setProtonCharge(10.);
-      MatrixWorkspace_sptr b = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2);
+      MatrixWorkspace_sptr b = WorkspaceCreationHelper::createWorkspaceSingleValue(2);
       b->mutableRun().setProtonCharge(5.);
       AnalysisDataService::Instance().add("a", a);
       AnalysisDataService::Instance().add("b", b);
@@ -167,7 +167,7 @@ public:
   {
     int nBins = 5;
     MatrixWorkspace_sptr work_in1 = fibWS1d;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create1DWorkspaceRand(nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create1DWorkspaceRand(nBins);
     performTest(work_in1,work_in2);
   }
 
@@ -182,7 +182,7 @@ public:
   void test_2D_2D_inplace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspaceBinned(nHist,nBins);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_bin;
     performTest(work_in1,work_in2, true /*inplace*/, false /*not event*/,
         DO_PLUS ? 4.0 : 0.0,   2.0);
@@ -198,16 +198,16 @@ public:
   void test_2D_2D_Histograms()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace123(nHist,nBins, true);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace154(nHist,nBins, true);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace123(nHist,nBins, true);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace154(nHist,nBins, true);
     performTest(work_in1,work_in2);
   }
 
   void test_1D_Rand2D()
   {
     int nHist = 5,nBins=5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace154(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create1DWorkspaceRand(nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace154(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create1DWorkspaceRand(nBins);
     performTest(work_in1,work_in2);
   }
 
@@ -215,14 +215,14 @@ public:
   {
     int nBins=10;
     MatrixWorkspace_sptr work_in1 = histWS_5x10_154;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace123(1,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace123(1,nBins);
     performTest(work_in1,work_in2);
   }
 
   void test_1DVertical_2D()
   {
     int nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace123(1,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace123(1,nBins);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_154;
     if (DO_PLUS)
     {
@@ -238,8 +238,8 @@ public:
   {
     //In 2D workspaces, the X bins have to match
     int nHist = 10,nBins=5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace123(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace154(1,nBins*5);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace123(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace154(1,nBins*5);
     performTest_fails(work_in1, work_in2);
   }
 
@@ -274,15 +274,15 @@ public:
   void test_1D_SingleValue()
   {
     MatrixWorkspace_sptr work_in1 = fibWS1d;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.2);
     performTest(work_in1,work_in2);
   }
 
   void test_SingleValue_1D()
   {
     int nBins = 5;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.2);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspaceBinned(1,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspaceBinned(1,nBins);
     if (DO_PLUS)
       MatrixWorkspace_sptr out = performTest(work_in1,work_in2,
           false /*in place*/, false /*not event*/,
@@ -296,22 +296,22 @@ public:
   void test_2D_SingleValue()
   {
     MatrixWorkspace_sptr work_in1 = histWS_5x10_bin;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(4.455);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(4.455);
     performTest(work_in1,work_in2);
   }
 
   void test_2D_SingleValue_InPlace()
   {
     int nHist =5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist,nBins);
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(4.455);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspaceBinned(nHist,nBins);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(4.455);
     performTest(work_in1,work_in2, true /*in place*/, false /*not event*/,
         DO_PLUS ? 6.455 : -2.455,   2.5406);
   }
 
   void test_SingleValue_2D()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(4.455);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(4.455);
     MatrixWorkspace_sptr work_in2 = histWS_5x10_bin;
     if (DO_PLUS)
     {
@@ -330,7 +330,7 @@ public:
   void test_2D_SingleValueNoError()
   {
     MatrixWorkspace_sptr work_in1 = histWS_5x10_bin;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValueWithError(5.0, 0.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValueWithError(5.0, 0.0);
     performTest(work_in1,work_in2);
   }
 
@@ -341,7 +341,7 @@ public:
   void test_Event_SingleValue()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     // Become a WS2D
     performTest(work_in1, work_in2, false, false /*output is NOT event*/ );
   }
@@ -349,13 +349,13 @@ public:
   void test_Event_SingleValue_inPlace_fails()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     performTest_fails(work_in1, work_in2, true);
   }
 
   void test_SingleValue_Event()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     // Become a WS2D
     if (DO_PLUS)
@@ -374,7 +374,7 @@ public:
   void test_SingleValue_Event_inPlace_fails()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.0);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createWorkspaceSingleValue(2.0);
     // Become a WS2D
     performTest_fails(work_in1, work_in2, true);
   }
@@ -391,7 +391,7 @@ public:
   void test_2D_Event_inPlace()
   {
     int nHist = 5, nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(nHist,nBins);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(nHist,nBins);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     // You have to specify the expected output value because in1 gets changed.
     performTest(work_in1,work_in2, true, false /*not event out*/,
@@ -417,14 +417,14 @@ public:
   void test_Event_2DSingleSpectrum()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     performTest(work_in1,work_in2, false);
   }
 
   void test_Event_2DSingleSpectrum_inPlace_fails()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     performTest_fails(work_in1,work_in2, true);
   }
 
@@ -432,7 +432,7 @@ public:
   {
     for(int inplace=0; inplace<2;inplace++)
     {
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::create2DWorkspace(1, 10);
       MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
       if (DO_PLUS)
       {
@@ -480,7 +480,7 @@ public:
   void test_Event_Event_inPlace()
   {
     int nHist = 5,nBins=10;
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     MatrixWorkspace_sptr work_out = performTest(work_in1,work_in2, true, true /*outputIsEvent*/,
         DO_PLUS ? 4.0 : 0.0,   DO_PLUS ? 2.0 : 2.0);
@@ -489,13 +489,13 @@ public:
   void test_Event_EventSingleSpectrum_fails()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(1,10,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(1,10,50,0.0,1.0,2);
     performTest_fails(work_in1,work_in2, false);
   }
 
   void test_EventSingleSpectrum_Event_fails()
   {
-    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(1,10,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(1,10,50,0.0,1.0,2);
     MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
     performTest_fails(work_in1,work_in2, false);
   }
@@ -506,8 +506,8 @@ public:
     for(int inplace=0; inplace<2;inplace++)
     {
       int nHist = 5,nBins=1;
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
       MatrixWorkspace_sptr work_out = performTest(work_in1,work_in2, inplace!=0, true /*outputIsEvent*/,
           DO_PLUS ? 4.0 : 0.0,   DO_PLUS ? 2.0 : 2.0);
     }
@@ -518,8 +518,8 @@ public:
     for(int inplace=0; inplace<2;inplace++)
     {
       int nHist = 5,nBins=10;
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,1,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,1,50,0.0,1.0,2);
       MatrixWorkspace_sptr work_out = performTest(work_in1,work_in2, inplace!=0, true /*outputIsEvent*/,
           DO_PLUS ? 4.0 : 0.0,   DO_PLUS ? 2.0 : 2.0);
     }
@@ -529,7 +529,7 @@ public:
   {
     for(int inplace=0; inplace<2;inplace++)
     {
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(5,1,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(5,1,50,0.0,1.0,2);
       MatrixWorkspace_sptr work_in2 = eventWS_5x10_50;
       MatrixWorkspace_sptr work_out = performTest(work_in1,work_in2, inplace!=0, true /*outputIsEvent*/,
           DO_PLUS ? 4.0 : 0.0,   DO_PLUS ? 2.0 : 2.0);
@@ -541,8 +541,8 @@ public:
     for(int inplace=0; inplace<2;inplace++)
     {
       int nHist=1,nBins=1;
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(nHist,nBins,50,0.0,1.0,2);
       MatrixWorkspace_sptr work_out = performTest(work_in1,work_in2, inplace!=0, true /*outputIsEvent*/,
           DO_PLUS ? 4.0 : 0.0,   DO_PLUS ? 2.0 : 2.0);
     }
@@ -556,7 +556,7 @@ public:
   void test_Event_IncompatibleUnits_fails()
   {
     MatrixWorkspace_sptr work_in1 = eventWS_5x10_50;
-    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(5,10,50,0.0,1.0,2);
+    MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(5,10,50,0.0,1.0,2);
     work_in2->setYUnit("Microfurlongs per Megafortnights");
     performTest_fails(work_in1,work_in2, false /*not inplace*/);
   }
@@ -567,8 +567,8 @@ public:
   {
     for (int inplace =0; inplace < 2; inplace++)
     {
-      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::CreateEventWorkspace(3,10,50, 0.0, 1.0, 3); // 5 ev
-      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::CreateEventWorkspace(3,10,50, 0.0, 1.0, 2, 100); //100 events per spectrum, but the spectra are at different pixel ids
+      MatrixWorkspace_sptr work_in1 = WorkspaceCreationHelper::createEventWorkspace(3,10,50, 0.0, 1.0, 3); // 5 ev
+      MatrixWorkspace_sptr work_in2 = WorkspaceCreationHelper::createEventWorkspace(3,10,50, 0.0, 1.0, 2, 100); //100 events per spectrum, but the spectra are at different pixel ids
 
       //First pixel id of rhs is 100
       TS_ASSERT( work_in2->getSpectrum(0).hasDetectorID(100) );
@@ -1049,7 +1049,7 @@ public:
   void test_EventWorkspace_EventWorkspace_clearRHS()
   {
     EventWorkspace_sptr lhs = eventWS_small;
-    EventWorkspace_sptr rhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr rhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     performTest_withClearRHS(lhs,rhs, true, true, lhs->getNumberEvents() + rhs->getNumberEvents(), true);
   }
 
@@ -1063,7 +1063,7 @@ public:
   void test_Workspace2D_EventWorkspace_clearRHS()
   {
     MatrixWorkspace_sptr lhs = histWS_5x10_bin;
-    EventWorkspace_sptr rhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr rhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     performTest_withClearRHS(lhs,rhs, true, false, 0, true);
   }
 
@@ -1077,28 +1077,28 @@ public:
   void test_EventWorkspace_Workspace2D_clearRHS()
   {
     EventWorkspace_sptr lhs = eventWS_small;
-    MatrixWorkspace_sptr rhs = WorkspaceCreationHelper::Create2DWorkspace(numPixels, numBins);
+    MatrixWorkspace_sptr rhs = WorkspaceCreationHelper::create2DWorkspace(numPixels, numBins);
     performTest_withClearRHS(lhs,rhs, true, false, 0, false);
   }
 
 
   void test_EventWorkspace_EventWorkspace_inPlace_of_lhs()
   {
-    EventWorkspace_sptr lhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
-    EventWorkspace_sptr rhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr lhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr rhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     performTest_withClearRHS(lhs,rhs, false, true, lhs->getNumberEvents() + rhs->getNumberEvents(), false, 1);
   }
 
   void test_EventWorkspace_EventWorkspace_inPlace_of_rhs()
   {
-    EventWorkspace_sptr lhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
-    EventWorkspace_sptr rhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr lhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr rhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     performTest_withClearRHS(lhs,rhs, false, true, lhs->getNumberEvents() + rhs->getNumberEvents(), false, 2);
   }
 
   void test_EventWorkspace_EventWorkspace_inPlace_AND_lhs_is_rhs()
   {
-    EventWorkspace_sptr lhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr lhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     EventWorkspace_sptr rhs = lhs;
     performTest_withClearRHS(lhs,rhs, false, true, lhs->getNumberEvents() + rhs->getNumberEvents(), false, 1);
   }
@@ -1112,15 +1112,15 @@ public:
 
   void test_EventWorkspace_EventWorkspace_lhs_is_rhs_with_clearRHS_set_doesnt_clearRHS()
   {
-    EventWorkspace_sptr lhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr lhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     EventWorkspace_sptr rhs = lhs;
     performTest_withClearRHS(lhs,rhs, false, true, lhs->getNumberEvents() + rhs->getNumberEvents(), false);
   }
 
   void test_EventWorkspace_EventWorkspace_inPlace_of_rhs_with_clearRHS_set_doesnt_clearRHS()
   {
-    EventWorkspace_sptr lhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
-    EventWorkspace_sptr rhs = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr lhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
+    EventWorkspace_sptr rhs = WorkspaceCreationHelper::createEventWorkspace(numPixels, numBins, numBins, 0.0, 1.0, 2);
     performTest_withClearRHS(lhs,rhs, false, true, lhs->getNumberEvents() + rhs->getNumberEvents(), false, 2);
   }
 
@@ -1148,8 +1148,8 @@ public:
   
   void setUp() override
   {
-  	ws2D_1 = WorkspaceCreationHelper::Create2DWorkspace(10000 /*histograms*/, 1000/*bins*/);
-   	ws2D_2 = WorkspaceCreationHelper::Create2DWorkspace(10000 /*histograms*/, 1000/*bins*/);
+  	ws2D_1 = WorkspaceCreationHelper::create2DWorkspace(10000 /*histograms*/, 1000/*bins*/);
+   	ws2D_2 = WorkspaceCreationHelper::create2DWorkspace(10000 /*histograms*/, 1000/*bins*/);
   }
   
   void test_large_2D()
diff --git a/Framework/Algorithms/test/PointByPointVCorrectionTest.h b/Framework/Algorithms/test/PointByPointVCorrectionTest.h
index 2fd6d9756f078177c191c560f07c520cc1e30263..27a3facbc81640a9fc2afc4918ede3101357a508 100644
--- a/Framework/Algorithms/test/PointByPointVCorrectionTest.h
+++ b/Framework/Algorithms/test/PointByPointVCorrectionTest.h
@@ -26,9 +26,9 @@ public:
       pbpv.initialize();
 
     MatrixWorkspace_sptr testSample =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 5, 0.5, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 5, 0.5, 1.5);
     MatrixWorkspace_sptr testVanadium =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 5, 0.5, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 5, 0.5, 1.5);
     // Make the instruments match
     Mantid::Geometry::Instrument_sptr inst(new Mantid::Geometry::Instrument);
     testSample->setInstrument(inst);
@@ -81,9 +81,9 @@ public:
 
   void setUp() override {
     MatrixWorkspace_sptr testSample =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(20000, 5, 0.5, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(20000, 5, 0.5, 1.5);
     MatrixWorkspace_sptr testVanadium =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(20000, 5, 0.5, 1.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(20000, 5, 0.5, 1.5);
     // Make the instruments match
     Mantid::Geometry::Instrument_sptr inst(new Mantid::Geometry::Instrument);
     testSample->setInstrument(inst);
diff --git a/Framework/Algorithms/test/PoissonErrorsTest.h b/Framework/Algorithms/test/PoissonErrorsTest.h
index 184450dd3b4061dc1a61a2f7966710fa9ff19b30..ddcbd42bb10b6eb56ce0286af31274d554f7062c 100644
--- a/Framework/Algorithms/test/PoissonErrorsTest.h
+++ b/Framework/Algorithms/test/PoissonErrorsTest.h
@@ -48,9 +48,9 @@ public:
     int nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
     AnalysisDataService::Instance().add("test_in11", work_in1);
     AnalysisDataService::Instance().add("test_in12", work_in2);
 
@@ -78,9 +78,9 @@ public:
     int nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceRand(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceRand(nBins);
     AnalysisDataService::Instance().add("test_in11", work_in1);
     AnalysisDataService::Instance().add("test_in12", work_in2);
 
@@ -108,9 +108,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
 
     PoissonErrors alg;
 
@@ -138,9 +138,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
 
     PoissonErrors alg;
 
@@ -162,9 +162,9 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create1DWorkspaceRand(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceRand(nBins);
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     PoissonErrors alg;
 
@@ -187,9 +187,9 @@ public:
     // Register the workspace in the data service
 
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.2);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(2.2);
     AnalysisDataService::Instance().add("test_in11", work_in1);
     AnalysisDataService::Instance().add("test_in12", work_in2);
 
@@ -211,9 +211,9 @@ public:
     int nBins = 300;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create1DWorkspaceFib(nBins);
+        WorkspaceCreationHelper::create1DWorkspaceFib(nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(4.455);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(4.455);
 
     PoissonErrors alg;
 
diff --git a/Framework/Algorithms/test/PolarizationCorrectionTest.h b/Framework/Algorithms/test/PolarizationCorrectionTest.h
index 64118deb7130cf520392197adf4a02ec10e7b611..e5e9c6ee69677d9e367ea672a0b16093b1981bb5 100644
--- a/Framework/Algorithms/test/PolarizationCorrectionTest.h
+++ b/Framework/Algorithms/test/PolarizationCorrectionTest.h
@@ -9,6 +9,7 @@
 #include <boost/make_shared.hpp>
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Algorithms;
@@ -136,7 +137,7 @@ public:
 
   MatrixWorkspace_sptr create1DWorkspace(int size, double signal,
                                          double error) {
-    auto ws = Create1DWorkspaceConstant(size, signal, error);
+    auto ws = create1DWorkspaceConstant(size, signal, error);
     ws->getAxis(0)->setUnit("Wavelength");
     return ws;
   }
diff --git a/Framework/Algorithms/test/PolynomialCorrectionTest.h b/Framework/Algorithms/test/PolynomialCorrectionTest.h
index 769385b750e38a68456e8cf1a7dfa29ee592e9f7..143e1e4539c7df55c7e6e064112ca8f7c200ae05 100644
--- a/Framework/Algorithms/test/PolynomialCorrectionTest.h
+++ b/Framework/Algorithms/test/PolynomialCorrectionTest.h
@@ -50,7 +50,7 @@ public:
     const std::string wsName = "PolynomialCorrectionTest_inputWS";
     const std::string wsNameOut = "PolynomialCorrectionTest_outputWS";
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add(wsName, inputWS);
 
     Mantid::Algorithms::PolynomialCorrection poly3;
@@ -89,7 +89,7 @@ public:
     const std::string wsName = "PolynomialCorrectionTest_inputWS";
     const std::string wsNameOut = "PolynomialCorrectionTest_outputWS";
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add(wsName, inputWS);
 
     Mantid::Algorithms::PolynomialCorrection poly3;
@@ -126,7 +126,7 @@ public:
   }
 
   void testEvents() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     AnalysisDataService::Instance().add("test_ev_polyc", evin);
diff --git a/Framework/Algorithms/test/PowerLawCorrectionTest.h b/Framework/Algorithms/test/PowerLawCorrectionTest.h
index 4f4927b4a9017f3fa0714859827ffd572a5f0425..e3565a8ff2b1f4ca6ecf6ef4ed722504b85b08b4 100644
--- a/Framework/Algorithms/test/PowerLawCorrectionTest.h
+++ b/Framework/Algorithms/test/PowerLawCorrectionTest.h
@@ -49,7 +49,7 @@ public:
 
   void testMultiply() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 0.5);
     AnalysisDataService::Instance().add("PowerLawCorrectionInputWS", inputWS);
 
     Mantid::Algorithms::PowerLawCorrection expon3;
@@ -86,7 +86,7 @@ public:
   }
 
   void testEvents() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     AnalysisDataService::Instance().add("test_ev_powlc", evin);
diff --git a/Framework/Algorithms/test/PowerTest.h b/Framework/Algorithms/test/PowerTest.h
index e8107f27f74fad6c0df3cd18168353b5728b09aa..e187dac0b6434f1a6fdcd084668a0180e59a3089 100644
--- a/Framework/Algorithms/test/PowerTest.h
+++ b/Framework/Algorithms/test/PowerTest.h
@@ -54,7 +54,7 @@ public:
 
   void testSetProperties() {
     WorkspaceSingleValue_sptr baseWs =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(2);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(2);
     AnalysisDataService::Instance().add("InputWS", baseWs);
 
     Power power;
@@ -98,7 +98,7 @@ public:
 
   void testPowerCalculation() {
     WorkspaceSingleValue_sptr baseWs =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(2);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(2);
     AnalysisDataService::Instance().add("InputWS", baseWs);
 
     Power power;
@@ -126,7 +126,7 @@ public:
 
   void testPowerCalculationWithNegativeExponent() {
     WorkspaceSingleValue_sptr baseWs =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(2);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(2);
     AnalysisDataService::Instance().add("InputWS", baseWs);
 
     Power power;
@@ -162,7 +162,7 @@ public:
     // if x = p ^ y, then err_x = y * x * err_p / p
 
     WorkspaceSingleValue_sptr baseWs =
-        WorkspaceCreationHelper::CreateWorkspaceSingleValue(4);
+        WorkspaceCreationHelper::createWorkspaceSingleValue(4);
     AnalysisDataService::Instance().add("InputWS", baseWs);
 
     Power power;
@@ -188,7 +188,7 @@ public:
 
   void testEvents() {
     // evin has 0 events per bin in pixel0, 1 in pixel 1, 2 in pixel2, ...
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             5, 3, 1000, 0, 1, 4),
                         evout;
     AnalysisDataService::Instance().add("test_ev_pow", evin);
diff --git a/Framework/Algorithms/test/Q1D2Test.h b/Framework/Algorithms/test/Q1D2Test.h
index 95192a24e8970b792ad3a05201f1adc6bd782902..b7e7f20235dbb1b37f116d847ff84c1adff8c37b 100644
--- a/Framework/Algorithms/test/Q1D2Test.h
+++ b/Framework/Algorithms/test/Q1D2Test.h
@@ -590,7 +590,7 @@ void createInputWorkspaces(int start, int end,
       Mantid::API::AnalysisDataService::Instance().retrieve(wsName));
   wave = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
       Mantid::API::AnalysisDataService::Instance().retrieve(wavNorm));
-  pixels = WorkspaceCreationHelper::Create2DWorkspaceBinned(29, 1);
+  pixels = WorkspaceCreationHelper::create2DWorkspaceBinned(29, 1);
   for (int i = 0; i < 29; ++i) {
     pixels->mutableY(i)[0] = flat_cell061Ys[i];
     pixels->mutableE(i)[0] = flat_cell061Es[i];
diff --git a/Framework/Algorithms/test/Q1DWeightedTest.h b/Framework/Algorithms/test/Q1DWeightedTest.h
index e7f5fe2de36134ed0e540b2e43a733db6f2e4f97..64f974552c36326d84f16204ceb639496d410d6d 100644
--- a/Framework/Algorithms/test/Q1DWeightedTest.h
+++ b/Framework/Algorithms/test/Q1DWeightedTest.h
@@ -5,6 +5,7 @@
 #include "MantidAlgorithms/Q1DWeighted.h"
 #include "MantidDataHandling/LoadSpice2D.h"
 #include "MantidDataHandling/MoveInstrumentComponent.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
diff --git a/Framework/Algorithms/test/QxyTest.h b/Framework/Algorithms/test/QxyTest.h
index 5bade76b90cb94bd51b1ebf5829a5a53ad475c50..47d46058f4b8507c77774e31b10c2e65e1e8c9e1 100644
--- a/Framework/Algorithms/test/QxyTest.h
+++ b/Framework/Algorithms/test/QxyTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/Qxy.h"
 #include "MantidAlgorithms/ConvertUnits.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidDataHandling/LoadRaw3.h"
 
diff --git a/Framework/Algorithms/test/RRFMuonTest.h b/Framework/Algorithms/test/RRFMuonTest.h
index 0010979b6022b5cddfa8ed43d91a000c3fa29533..bd8deab5baf0b9cce469eb78bf6646e1ce91cd76 100644
--- a/Framework/Algorithms/test/RRFMuonTest.h
+++ b/Framework/Algorithms/test/RRFMuonTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/RRFMuon.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/Algorithms/test/RadiusSumTest.h b/Framework/Algorithms/test/RadiusSumTest.h
index a1b16948c93fba515470b2b465be7d234a9a935f..658732b7b3345dfb5e32d23f0bfc0515a27ec0e7 100644
--- a/Framework/Algorithms/test/RadiusSumTest.h
+++ b/Framework/Algorithms/test/RadiusSumTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAlgorithms/RadiusSum.h"
+#include "MantidKernel/Unit.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "RingProfileTest.h"
 #include <boost/shared_ptr.hpp>
diff --git a/Framework/Algorithms/test/Rebin2DTest.h b/Framework/Algorithms/test/Rebin2DTest.h
index d24a362220616e876ad1bcdfc86d71a74f2bdd24..c96f34fe799c60172321270e639933cbc0daffaa 100644
--- a/Framework/Algorithms/test/Rebin2DTest.h
+++ b/Framework/Algorithms/test/Rebin2DTest.h
@@ -39,7 +39,7 @@ MatrixWorkspace_sptr makeInputWS(const bool distribution,
     }
   }
 
-  MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspaceBinned(
+  MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspaceBinned(
       int(nhist), int(nbins), x0, deltax);
 
   // We need something other than a spectrum axis, call this one theta
diff --git a/Framework/Algorithms/test/RebinByTimeBaseTest.h b/Framework/Algorithms/test/RebinByTimeBaseTest.h
index 57ae2602819ad7ed7fd9d692afddfe8ea700afc6..2c27d7c6f9b2498f75c448db59aeea7dc22c1084 100644
--- a/Framework/Algorithms/test/RebinByTimeBaseTest.h
+++ b/Framework/Algorithms/test/RebinByTimeBaseTest.h
@@ -14,6 +14,7 @@
 #include "MantidDataObjects/Events.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/DateAndTime.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/WarningSuppressions.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <boost/make_shared.hpp>
diff --git a/Framework/Algorithms/test/RebinTest.h b/Framework/Algorithms/test/RebinTest.h
index 2cc44e8b174a6e713750ef537240ed44cb437c1b..f6b53ae6c81e11445efcdfe6e2abf09922295bd3 100644
--- a/Framework/Algorithms/test/RebinTest.h
+++ b/Framework/Algorithms/test/RebinTest.h
@@ -191,7 +191,7 @@ public:
                               bool PreserveEvents, bool expectOutputEvent) {
     // Two events per bin
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateEventWorkspace2(50, 100);
+        WorkspaceCreationHelper::createEventWorkspace2(50, 100);
     test_in->switchEventType(eventType);
 
     std::string inName("test_inEvent");
@@ -556,7 +556,7 @@ public:
   static void destroySuite(RebinTestPerformance *suite) { delete suite; }
 
   RebinTestPerformance() {
-    ws = WorkspaceCreationHelper::Create2DWorkspaceBinned(5000, 20000);
+    ws = WorkspaceCreationHelper::create2DWorkspaceBinned(5000, 20000);
   }
 
   void test_rebin() {
diff --git a/Framework/Algorithms/test/RebinToWorkspaceTest.h b/Framework/Algorithms/test/RebinToWorkspaceTest.h
index e759354bfbcd8f3dafbc39d2bc20525e876eeef2..0e1ec1c08eb2dcc6bd2c5140b08c552fe08950db 100644
--- a/Framework/Algorithms/test/RebinToWorkspaceTest.h
+++ b/Framework/Algorithms/test/RebinToWorkspaceTest.h
@@ -28,7 +28,7 @@ public:
     // Creates a workspace with 10 points
     const int numYPoints(10);
     const int numSpectra(2);
-    Workspace2D_sptr testWS = WorkspaceCreationHelper::Create2DWorkspace123(
+    Workspace2D_sptr testWS = WorkspaceCreationHelper::create2DWorkspace123(
         numSpectra, numYPoints, false);
     // Reset the X data to something reasonable
     Points x(numYPoints);
@@ -54,9 +54,9 @@ public:
     // Need to input workspaces to test this
     using namespace Mantid::DataObjects;
     Workspace2D_sptr rebinThis =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 50, 5.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 50, 5.0, 1.0);
     Workspace2D_sptr matchToThis =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(15, 30, 3.0, 2.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(15, 30, 3.0, 2.5);
     // Register them with the DataService
     using namespace Mantid::API;
     TS_ASSERT_THROWS_NOTHING(
diff --git a/Framework/Algorithms/test/RectangularBeamProfileTest.h b/Framework/Algorithms/test/RectangularBeamProfileTest.h
index 28074255f6c617993a6cac1727b5d4a9a6529fcc..973a622ca00d9708c449a1db986fc6b036147363 100644
--- a/Framework/Algorithms/test/RectangularBeamProfileTest.h
+++ b/Framework/Algorithms/test/RectangularBeamProfileTest.h
@@ -4,8 +4,11 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/SampleCorrections/RectangularBeamProfile.h"
-#include "MonteCarloTesting.h"
+#include "MantidAPI/Sample.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidTestHelpers/ComponentCreationHelper.h"
+
+#include "MonteCarloTesting.h"
 
 using Mantid::Algorithms::RectangularBeamProfile;
 
@@ -79,12 +82,27 @@ public:
     TS_ASSERT_EQUALS(V3D(1.0, 0, 0), ray.unitDir);
   }
 
+  void test_DefineActiveRegion() {
+    using Mantid::API::Sample;
+    using Mantid::Kernel::V3D;
+    const double width(0.1), height(0.2);
+    const V3D center;
+    RectangularBeamProfile profile(createTestFrame(), center, width, height);
+    Sample testSample;
+    testSample.setShape(*ComponentCreationHelper::createSphere(0.5));
+
+    auto region = profile.defineActiveRegion(testSample);
+    TS_ASSERT(region.isNonNull());
+    TS_ASSERT_EQUALS(V3D(-0.5, -0.05, -0.1), region.minPoint());
+    TS_ASSERT_EQUALS(V3D(0.5, 0.05, 0.1), region.maxPoint());
+  }
+
 private:
   Mantid::Geometry::ReferenceFrame createTestFrame() {
     using Mantid::Geometry::ReferenceFrame;
     using Mantid::Geometry::PointingAlong;
     using Mantid::Geometry::Handedness;
-
+    // up = Z, beam = X
     return ReferenceFrame(PointingAlong::Z, PointingAlong::X, Handedness::Right,
                           "source");
   }
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h b/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h
index 33a32c300c64d652d2d0dad920ab05642991bf19..082e83c04bba5dc49f4914d43d10c7d9be2fe308 100644
--- a/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h
+++ b/Framework/Algorithms/test/ReflectometryReductionOneAutoTest.h
@@ -7,6 +7,9 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
+#include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
diff --git a/Framework/Algorithms/test/ReflectometryReductionOneTest.h b/Framework/Algorithms/test/ReflectometryReductionOneTest.h
index 845c37071d55a69d848e119973053054b9ee57ca..bceb96132816315d393517030280424ea20ab8c3 100644
--- a/Framework/Algorithms/test/ReflectometryReductionOneTest.h
+++ b/Framework/Algorithms/test/ReflectometryReductionOneTest.h
@@ -11,6 +11,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/Unit.h"
 
 using namespace Mantid;
 using namespace Mantid::Kernel;
@@ -236,7 +237,7 @@ public:
   }
   void test_post_processing_rebin_step_with_params_not_provided() {
     auto alg = construct_standard_algorithm();
-    auto inWS = Create2DWorkspace154(1, 10, true);
+    auto inWS = create2DWorkspace154(1, 10, true);
     // this instrument does not have a "slit-gap" property
     // defined in the IPF, so CalculateResolution should throw.
     inWS->setInstrument(m_tinyReflWS->getInstrument());
@@ -249,7 +250,7 @@ public:
   }
   void test_post_processing_rebin_step_with_partial_params_provided() {
     auto alg = construct_standard_algorithm();
-    auto inWS = Create2DWorkspace154(1, 10, true);
+    auto inWS = create2DWorkspace154(1, 10, true);
     inWS->setInstrument(m_tinyReflWS->getInstrument());
     inWS->getAxis(0)->setUnit("Wavelength");
     alg->setProperty("InputWorkspace", inWS);
@@ -267,7 +268,7 @@ public:
   }
   void test_post_processing_rebin_step_with_logarithmic_rebinning() {
     auto alg = construct_standard_algorithm();
-    auto inWS = Create2DWorkspace154(1, 10, true);
+    auto inWS = create2DWorkspace154(1, 10, true);
     inWS->setInstrument(m_tinyReflWS->getInstrument());
     inWS->getAxis(0)->setUnit("Wavelength");
     alg->setProperty("InputWorkspace", inWS);
@@ -289,7 +290,7 @@ public:
   }
   void test_post_processing_rebin_step_with_linear_rebinning() {
     auto alg = construct_standard_algorithm();
-    auto inWS = Create2DWorkspace154(1, 10, true);
+    auto inWS = create2DWorkspace154(1, 10, true);
     inWS->setInstrument(m_tinyReflWS->getInstrument());
     inWS->getAxis(0)->setUnit("Wavelength");
     alg->setProperty("InputWorkspace", inWS);
diff --git a/Framework/Algorithms/test/RemoveBinsTest.h b/Framework/Algorithms/test/RemoveBinsTest.h
index 4b7baf49b908fdb5168f2724e437ab5d78f6d116..9dd7ce40beda10d0a6e942cc3af7b4c97bbf4e78 100644
--- a/Framework/Algorithms/test/RemoveBinsTest.h
+++ b/Framework/Algorithms/test/RemoveBinsTest.h
@@ -8,6 +8,7 @@
 #include <stdexcept>
 
 #include "MantidAlgorithms/RemoveBins.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidDataHandling/LoadMuonNexus2.h"
 #include "MantidDataHandling/LoadInstrument.h"
diff --git a/Framework/Algorithms/test/RemoveExpDecayTest.h b/Framework/Algorithms/test/RemoveExpDecayTest.h
index dfcdf1a8ad8b4b2d92679188846bdcd426ccf314..76a136302b9d7260f3e8d8b1ca7abecc2c8a474b 100644
--- a/Framework/Algorithms/test/RemoveExpDecayTest.h
+++ b/Framework/Algorithms/test/RemoveExpDecayTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/RemoveExpDecay.h"
+#include "MantidKernel/PhysicalConstants.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidHistogramData/LinearGenerator.h"
diff --git a/Framework/Algorithms/test/RemoveLowResTOFTest.h b/Framework/Algorithms/test/RemoveLowResTOFTest.h
index b3a67a4138630bf9ab56571ecc586b31c5af0d07..3eab32dccbed5532f2ed1e300612fc4ce0d7406c 100644
--- a/Framework/Algorithms/test/RemoveLowResTOFTest.h
+++ b/Framework/Algorithms/test/RemoveLowResTOFTest.h
@@ -29,7 +29,7 @@ private:
 
   void makeFakeEventWorkspace(std::string wsName) {
     // Make an event workspace with 2 events in each bin.
-    EventWorkspace_sptr test_in = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr test_in = WorkspaceCreationHelper::createEventWorkspace(
         NUMPIXELS, NUMBINS, NUMBINS, 0.0, BIN_DELTA, 2);
     // Fake a TOF unit in the data.
     test_in->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
diff --git a/Framework/Algorithms/test/RemoveMaskedSpectraTest.h b/Framework/Algorithms/test/RemoveMaskedSpectraTest.h
index 79c73b9322e8711d625d631e30d8a8c9b1594f05..bdbd9bbf38fdd326f41b956edd0066fe9a48a80d 100644
--- a/Framework/Algorithms/test/RemoveMaskedSpectraTest.h
+++ b/Framework/Algorithms/test/RemoveMaskedSpectraTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/RemoveMaskedSpectra.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidHistogramData/LinearGenerator.h"
diff --git a/Framework/Algorithms/test/RemovePromptPulseTest.h b/Framework/Algorithms/test/RemovePromptPulseTest.h
index d1a442aa97eb3ed554ecb1da37f5b53984b91e4f..7ead65949a204e934837714401b8bdf2123d94c3 100644
--- a/Framework/Algorithms/test/RemovePromptPulseTest.h
+++ b/Framework/Algorithms/test/RemovePromptPulseTest.h
@@ -30,7 +30,7 @@ private:
 
   void makeFakeEventWorkspace(std::string wsName) {
     // Make an event workspace with 2 events in each bin.
-    EventWorkspace_sptr test_in = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr test_in = WorkspaceCreationHelper::createEventWorkspace(
         NUMPIXELS, NUMBINS, NUMEVENTS, 1000., BIN_DELTA, 2);
     // Fake a TOF unit in the data.
     test_in->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
diff --git a/Framework/Algorithms/test/RemoveWorkspaceHistoryTest.h b/Framework/Algorithms/test/RemoveWorkspaceHistoryTest.h
index aa2e8cded73256e8939a3d7804aa8487c5ab45dc..4c10f4a53ccf584a88c87ba1b9b8078e75ca587c 100644
--- a/Framework/Algorithms/test/RemoveWorkspaceHistoryTest.h
+++ b/Framework/Algorithms/test/RemoveWorkspaceHistoryTest.h
@@ -4,8 +4,11 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/RemoveWorkspaceHistory.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidTestHelpers/FakeObjects.h"
 
+using namespace Mantid::Kernel;
 using Mantid::Algorithms::RemoveWorkspaceHistory;
 
 class RemoveWorkspaceHistoryTest : public CxxTest::TestSuite {
@@ -131,4 +134,4 @@ public:
   }
 };
 
-#endif /* MANTID_ALGORITHMS_REMOVEWORKSPACEHISTORYTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_ALGORITHMS_REMOVEWORKSPACEHISTORYTEST_H_ */
diff --git a/Framework/Algorithms/test/RenameWorkspaceTest.h b/Framework/Algorithms/test/RenameWorkspaceTest.h
index fa94ec20dda2ec6bc1323add4f477d6e8c945b2e..13ec396a214bbd36c52fc57efe4a5e86e2b07235 100644
--- a/Framework/Algorithms/test/RenameWorkspaceTest.h
+++ b/Framework/Algorithms/test/RenameWorkspaceTest.h
@@ -6,6 +6,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAlgorithms/RenameWorkspace.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Exception.h"
 
 using namespace Mantid::API;
@@ -224,7 +225,7 @@ public:
   }
   MatrixWorkspace_sptr createWorkspace() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(4, 4, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(4, 4, 0.5);
 
     return inputWS;
   }
diff --git a/Framework/Algorithms/test/RenameWorkspacesTest.h b/Framework/Algorithms/test/RenameWorkspacesTest.h
index 84edbac9066301f1a0f87dbd01d9610a4550f64e..f711912ce6d04403cf86a1c513028d462c49aa8c 100644
--- a/Framework/Algorithms/test/RenameWorkspacesTest.h
+++ b/Framework/Algorithms/test/RenameWorkspacesTest.h
@@ -6,6 +6,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAlgorithms/RenameWorkspaces.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
@@ -264,7 +265,7 @@ public:
 
   MatrixWorkspace_sptr createWorkspace() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(4, 4, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(4, 4, 0.5);
     return inputWS;
   }
 
diff --git a/Framework/Algorithms/test/ReplaceSpecialValuesTest.h b/Framework/Algorithms/test/ReplaceSpecialValuesTest.h
index c31a2e92d0a022908137c146008a8910bc3f8cc1..6e090cfce8abe867e6c45bb089e7c1c2cd44a6fd 100644
--- a/Framework/Algorithms/test/ReplaceSpecialValuesTest.h
+++ b/Framework/Algorithms/test/ReplaceSpecialValuesTest.h
@@ -273,7 +273,7 @@ public:
 
   MatrixWorkspace_sptr createWorkspace() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(4, 4, 0.5);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(4, 4, 0.5);
     // put some infinities and NaNs in there
     double inf = std::numeric_limits<double>::infinity();
     inputWS->dataY(0)[2] = inf;
@@ -286,7 +286,7 @@ public:
   }
 
   void testEvents() {
-    EventWorkspace_sptr evin = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr evin = WorkspaceCreationHelper::createEventWorkspace(
                             1, 5, 10, 0, 1, 3),
                         evout;
     AnalysisDataService::Instance().add("test_ev_rep", evin);
diff --git a/Framework/Algorithms/test/ResampleXTest.h b/Framework/Algorithms/test/ResampleXTest.h
index 0621a3c96240b672106fa8a48dfa6630daf56497..e50b72d4d56c162eed3ca7daddb1515745ba5c93 100644
--- a/Framework/Algorithms/test/ResampleXTest.h
+++ b/Framework/Algorithms/test/ResampleXTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/ResampleX.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using namespace Mantid::API;
 using Mantid::Algorithms::ResampleX;
diff --git a/Framework/Algorithms/test/ResetNegativesTest.h b/Framework/Algorithms/test/ResetNegativesTest.h
index c14284f079c8e616cf42e063b8f0f4a20cc5face..29281e1919d09bc0adf0d65e84d1dde6c26721b7 100644
--- a/Framework/Algorithms/test/ResetNegativesTest.h
+++ b/Framework/Algorithms/test/ResetNegativesTest.h
@@ -146,7 +146,7 @@ private:
     constexpr int nhist = 3;
     constexpr int nbins = 256;
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, nbins, 1., .2);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins, 1., .2);
     for (int i = 0; i < nhist; i++) {
       double value = offset + static_cast<double>(i);
       auto &y = inputWS->mutableY(i);
@@ -189,7 +189,7 @@ private:
     constexpr int nhist = 50000;
     constexpr int nbins = 1000;
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, nbins, 1., .2);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins, 1., .2);
     for (int i = 0; i < nhist; i++) {
       double value = offset + static_cast<double>(i);
       auto &y = inputWS->mutableY(i);
diff --git a/Framework/Algorithms/test/RingProfileTest.h b/Framework/Algorithms/test/RingProfileTest.h
index 5d2941637a503bf0368ec0064cc80bfd16e4bed4..3c3b62424dda795e6aaf503c2e7bf34a099aa5b4 100644
--- a/Framework/Algorithms/test/RingProfileTest.h
+++ b/Framework/Algorithms/test/RingProfileTest.h
@@ -110,7 +110,7 @@ public:
    */
   static MatrixWorkspace_sptr create_2d_workspace() {
     MatrixWorkspace_sptr goodWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(5, 5, -0.3, 0.12);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(5, 5, -0.3, 0.12);
     NumericAxis *yAxis = new NumericAxis(5);
 
     for (int i = 0; i < 5; ++i) {
diff --git a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
index 4eac613b723ddef3b96317eb60677d28fb81fcb4..6be6c9e16041371f99fc505b0386a09da35c18e9 100644
--- a/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
+++ b/Framework/Algorithms/test/SANSCollimationLengthEstimatorTest.h
@@ -123,7 +123,7 @@ Mantid::API::MatrixWorkspace_sptr createTestWorkspace(
     double numberOfGuides = 5, V3D sourcePosition = V3D(0.0, 0.0, -25.0),
     V3D samplePosition = V3D(0.0, 0.0, 0.0),
     std::vector<double> guideLogDetails = std::vector<double>()) {
-  auto ws2d = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+  auto ws2d = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
       ones(), static_cast<int>(nhist), x0, x1, dx);
 
   // Add the instrument with a single detector
diff --git a/Framework/Algorithms/test/SassenaFFTTest.h b/Framework/Algorithms/test/SassenaFFTTest.h
index 721b6a800efd8a4aa92b288d9ef316dd63207d0c..4c15d0aa2fc5219da2356e5a9f2e1f2b96e7434c 100644
--- a/Framework/Algorithms/test/SassenaFFTTest.h
+++ b/Framework/Algorithms/test/SassenaFFTTest.h
@@ -8,6 +8,7 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataHandling/SaveAscii.h"
 #include "MantidAPI/FileProperty.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/PhysicalConstants.h"
 
 using namespace Mantid;
diff --git a/Framework/Algorithms/test/ScaleTest.h b/Framework/Algorithms/test/ScaleTest.h
index 6d48b67eed41afb8042cccebc6d8b506e075e393..a74ffea69d3412d294fd66e42ffb1e1a7aaef864 100644
--- a/Framework/Algorithms/test/ScaleTest.h
+++ b/Framework/Algorithms/test/ScaleTest.h
@@ -27,7 +27,7 @@ public:
       scale.initialize();
 
     AnalysisDataService::Instance().add(
-        "tomultiply", WorkspaceCreationHelper::Create2DWorkspace123(10, 10));
+        "tomultiply", WorkspaceCreationHelper::create2DWorkspace123(10, 10));
     TS_ASSERT_THROWS_NOTHING(
         scale.setPropertyValue("InputWorkspace", "tomultiply"));
     TS_ASSERT_THROWS_NOTHING(
@@ -59,7 +59,7 @@ public:
     scale2.initialize();
 
     AnalysisDataService::Instance().add(
-        "toadd", WorkspaceCreationHelper::Create2DWorkspace123(10, 10));
+        "toadd", WorkspaceCreationHelper::create2DWorkspace123(10, 10));
     TS_ASSERT_THROWS_NOTHING(
         scale2.setPropertyValue("InputWorkspace", "toadd"));
     TS_ASSERT_THROWS_NOTHING(
@@ -133,7 +133,7 @@ private:
     bool isHist = true;
     std::string wsName = "input_scaling";
     Mantid::API::AnalysisDataService::Instance().add(
-        wsName, WorkspaceCreationHelper::Create2DWorkspaceWithValuesAndXerror(
+        wsName, WorkspaceCreationHelper::create2DWorkspaceWithValuesAndXerror(
                     nHist, nBins, isHist, xValue, value, error, xError));
     std::string outWorkspaceName;
     if (outIsIn) {
diff --git a/Framework/Algorithms/test/ScaleXTest.h b/Framework/Algorithms/test/ScaleXTest.h
index 5004f5de9b2b4079d6a1fd8699d997c391a53af3..4f6fbf2d8e9a348030ce85698fc61388df8062d0 100644
--- a/Framework/Algorithms/test/ScaleXTest.h
+++ b/Framework/Algorithms/test/ScaleXTest.h
@@ -34,7 +34,7 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::Kernel;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspace123(10, 10);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspace123(10, 10);
     double factor = 2.5;
     auto result = runScaleX(inputWS, "Multiply", factor);
     checkScaleFactorApplied(inputWS, result, factor, true); // multiply=true
@@ -44,7 +44,7 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::Kernel;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspace123(10, 10);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspace123(10, 10);
     double factor = 2.5;
     auto result = runScaleX(inputWS, "Add", factor);
     checkScaleFactorApplied(inputWS, result, factor, false); // multiply=false
@@ -57,7 +57,7 @@ public:
     Mantid::Algorithms::ScaleX scale;
     scale.initialize();
 
-    auto inputWS = WorkspaceCreationHelper::CreateEventWorkspace2(10, 10);
+    auto inputWS = WorkspaceCreationHelper::createEventWorkspace2(10, 10);
     double factor(2.5);
     auto result = runScaleX(inputWS, "Multiply", factor);
     TS_ASSERT_EQUALS("EventWorkspace", result->id());
@@ -71,7 +71,7 @@ public:
     Mantid::Algorithms::ScaleX scale;
     scale.initialize();
 
-    auto inputWS = WorkspaceCreationHelper::CreateEventWorkspace2(10, 10);
+    auto inputWS = WorkspaceCreationHelper::createEventWorkspace2(10, 10);
     double factor(2.5);
     auto result = runScaleX(inputWS, "Add", factor);
     TS_ASSERT_EQUALS("EventWorkspace", result->id());
@@ -393,9 +393,9 @@ public:
   static void destroySuite(ScaleXTestPerformance *suite) { delete suite; }
 
   void setUp() override {
-    inputMatrix = WorkspaceCreationHelper::Create2DWorkspaceBinned(10000, 1000);
+    inputMatrix = WorkspaceCreationHelper::create2DWorkspaceBinned(10000, 1000);
     inputEvent =
-        WorkspaceCreationHelper::CreateEventWorkspace(10000, 1000, 5000);
+        WorkspaceCreationHelper::createEventWorkspace(10000, 1000, 5000);
   }
 
   void tearDown() override {
diff --git a/Framework/Algorithms/test/SetUncertaintiesTest.h b/Framework/Algorithms/test/SetUncertaintiesTest.h
index 4faebf9124b7c94389b5530102d4859043daa065..cb727e71e085afc5ecd15b6c20f15da944440540 100644
--- a/Framework/Algorithms/test/SetUncertaintiesTest.h
+++ b/Framework/Algorithms/test/SetUncertaintiesTest.h
@@ -25,7 +25,7 @@ public:
   */
   API::MatrixWorkspace_sptr runAlg(const std::string &mode) {
     // random data mostly works
-    auto inWksp = WorkspaceCreationHelper::Create1DWorkspaceRand(30);
+    auto inWksp = WorkspaceCreationHelper::create1DWorkspaceRand(30);
     // Ensure first elements of random workspace are zero so test don't
     // pass randomly
     auto &E = inWksp->mutableE(0);
@@ -111,7 +111,7 @@ public:
     constexpr size_t wsSize(1000000);
 
     // random data mostly works
-    inputWs = WorkspaceCreationHelper::Create1DWorkspaceRand(wsSize);
+    inputWs = WorkspaceCreationHelper::create1DWorkspaceRand(wsSize);
     algZero.setProperty("InputWorkspace", inputWs);
     algZero.setProperty("SetError", "zero");
     algZero.setProperty("OutputWorkspace", wsName);
diff --git a/Framework/Algorithms/test/ShiftLogTimeTest.h b/Framework/Algorithms/test/ShiftLogTimeTest.h
index 6f65dd18ebeb24d1e205b6b97e09cf367608958e..7c7f0c77aaa1240a167178f78c8f9ee2b552b0c5 100644
--- a/Framework/Algorithms/test/ShiftLogTimeTest.h
+++ b/Framework/Algorithms/test/ShiftLogTimeTest.h
@@ -7,6 +7,7 @@
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 
 using namespace Mantid;
diff --git a/Framework/Algorithms/test/SignalOverErrorTest.h b/Framework/Algorithms/test/SignalOverErrorTest.h
index 66b47972ef7467c927796029aa53eaeb8a7f8df4..fb9096f56410f7fa1f8dc672fa19c32bc5aebe3b 100644
--- a/Framework/Algorithms/test/SignalOverErrorTest.h
+++ b/Framework/Algorithms/test/SignalOverErrorTest.h
@@ -25,7 +25,7 @@ public:
     // Name of the output workspace.
     std::string outWSName("SignalOverErrorTest_OutputWS");
 
-    Workspace2D_sptr inWS = WorkspaceCreationHelper::Create2DWorkspace(2, 10);
+    Workspace2D_sptr inWS = WorkspaceCreationHelper::create2DWorkspace(2, 10);
 
     SignalOverError alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize())
diff --git a/Framework/Algorithms/test/SmoothDataTest.h b/Framework/Algorithms/test/SmoothDataTest.h
index 10c44e51808ee99d4a70f915cc0ea4fe296f5bce..de76f00e0612f49b36e5f35bfb886f26af1dcd08 100644
--- a/Framework/Algorithms/test/SmoothDataTest.h
+++ b/Framework/Algorithms/test/SmoothDataTest.h
@@ -189,7 +189,7 @@ public:
     constexpr size_t numBins(1000000);
 
     inputWs =
-        WorkspaceCreationHelper::Create2DWorkspace(numHistograms, numBins);
+        WorkspaceCreationHelper::create2DWorkspace(numHistograms, numBins);
 
     auto &yVals = inputWs->mutableY(0);
     auto &eVals = inputWs->mutableE(0);
diff --git a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
index a13a89691303427d4b497ef7fe0b52a8a5c3d9ee..ed87aaa6f7ddbfa17ba6e7194ab8974fa7f553f6 100644
--- a/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
+++ b/Framework/Algorithms/test/SofQWNormalisedPolygonTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/SofQWNormalisedPolygon.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidKernel/Unit.h"
 
diff --git a/Framework/Algorithms/test/SofQWPolygonTest.h b/Framework/Algorithms/test/SofQWPolygonTest.h
index 14091af984018ed5a323ccc1fc6ff8ad934c43ca..0461c8819f44e43af499e859adb22829ec5741e0 100644
--- a/Framework/Algorithms/test/SofQWPolygonTest.h
+++ b/Framework/Algorithms/test/SofQWPolygonTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/SofQWPolygon.h"
+#include "MantidAPI/WorkspaceHistory.h"
 
 #include "SofQWTest.h"
 
diff --git a/Framework/Algorithms/test/SofQWTest.h b/Framework/Algorithms/test/SofQWTest.h
index dd07d12e2fcef8e4491459f16e16b37628ab0181..695e9b5dbb6361df26bfe01a4be8a52f0a32528a 100644
--- a/Framework/Algorithms/test/SofQWTest.h
+++ b/Framework/Algorithms/test/SofQWTest.h
@@ -3,8 +3,10 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/SofQW.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"
 
diff --git a/Framework/Algorithms/test/SolidAngleTest.h b/Framework/Algorithms/test/SolidAngleTest.h
index 9d42945ab1281732d53c6122ffdf2da992fe9e5b..fbd06c446c84213f2d351ba40e4b7618ae3b7f38 100644
--- a/Framework/Algorithms/test/SolidAngleTest.h
+++ b/Framework/Algorithms/test/SolidAngleTest.h
@@ -6,9 +6,11 @@
 
 #include "MantidAlgorithms/SolidAngle.h"
 #include "MantidKernel/PhysicalConstants.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataHandling/LoadInstrument.h"
@@ -58,9 +60,7 @@ public:
     space2D->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
 
     // Mark one detector dead to test that it leads to zero solid angle
-    IDetector_const_sptr det143 = space2D->getDetector(143);
-    ParameterMap &pmap = space2D->instrumentParameters();
-    pmap.addBool(det143.get(), "masked", true);
+    space2D->mutableSpectrumInfo().setMasked(143, true);
   }
 
   void testInit() {
diff --git a/Framework/Algorithms/test/SortEventsTest.h b/Framework/Algorithms/test/SortEventsTest.h
index bc49c37416f0df28fbcef297716badfa0ce32e59..a4594137bff4d0294c5ecafa5d7ff01b927776e1 100644
--- a/Framework/Algorithms/test/SortEventsTest.h
+++ b/Framework/Algorithms/test/SortEventsTest.h
@@ -35,11 +35,11 @@ public:
   void testSortByTof() {
     std::string wsName("test_inEvent3");
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::createRandomEventWorkspace(NUMBINS, NUMPIXELS);
     AnalysisDataService::Instance().add(wsName, test_in);
 
     Workspace2D_sptr test_in_ws2d =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(NUMBINS, NUMPIXELS);
     AnalysisDataService::Instance().add("workspace2d", test_in_ws2d);
 
     SortEvents sort;
@@ -70,7 +70,7 @@ public:
   void testSortByPulseTime() {
     std::string wsName("test_inEvent4");
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::createRandomEventWorkspace(NUMBINS, NUMPIXELS);
     AnalysisDataService::Instance().add(wsName, test_in);
 
     SortEvents sort;
@@ -94,7 +94,7 @@ public:
   void testSortByPulseTimeTOF() {
     std::string wsName("test_inEvent4");
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::createRandomEventWorkspace(NUMBINS, NUMPIXELS);
     AnalysisDataService::Instance().add(wsName, test_in);
 
     SortEvents sort;
diff --git a/Framework/Algorithms/test/SpatialGroupingTest.h b/Framework/Algorithms/test/SpatialGroupingTest.h
index f7e04c0c97abd8e22eae7c07a66f256b9923c7d7..32aa0cfb08d95fa3cdb576180448ac5fbe1e1308 100644
--- a/Framework/Algorithms/test/SpatialGroupingTest.h
+++ b/Framework/Algorithms/test/SpatialGroupingTest.h
@@ -38,7 +38,7 @@ public:
     const int nhist(18);
     Mantid::API::MatrixWorkspace_sptr workspace =
         boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(
-            WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, 1));
+            WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, 1));
     // Create a parameterised instrument
     Mantid::Geometry::Instrument_sptr instrument =
         boost::dynamic_pointer_cast<Mantid::Geometry::Instrument>(
diff --git a/Framework/Algorithms/test/SpecularReflectionCalculateThetaTest.h b/Framework/Algorithms/test/SpecularReflectionCalculateThetaTest.h
index 1f06f4dd00f713de8d0fc19e09ea6f6e2f71a359..1a1fa6281c8e5cdce36e5f0ae639e2538cb836f0 100644
--- a/Framework/Algorithms/test/SpecularReflectionCalculateThetaTest.h
+++ b/Framework/Algorithms/test/SpecularReflectionCalculateThetaTest.h
@@ -49,7 +49,7 @@ public:
     IAlgorithm_sptr alg = makeAlgorithm();
     alg->setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
 
     SpecularReflectionAlgorithmTest::
         test_throws_if_SpectrumNumbersOfDetectors_less_than_zero(alg);
@@ -59,7 +59,7 @@ public:
     IAlgorithm_sptr alg = makeAlgorithm();
     alg->setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
 
     SpecularReflectionAlgorithmTest::
         test_throws_if_SpectrumNumbersOfDetectors_outside_range(alg);
diff --git a/Framework/Algorithms/test/SpecularReflectionPositionCorrectTest.h b/Framework/Algorithms/test/SpecularReflectionPositionCorrectTest.h
index cffecc4535e2978c919a7bdb66cdb1184567c75a..e12557edfae065e64aad4b59aab082342794c2ad 100644
--- a/Framework/Algorithms/test/SpecularReflectionPositionCorrectTest.h
+++ b/Framework/Algorithms/test/SpecularReflectionPositionCorrectTest.h
@@ -46,7 +46,7 @@ public:
     alg.initialize();
     alg.setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
     alg.setPropertyValue("OutputWorkspace", "test_out");
     TS_ASSERT_THROWS(alg.execute(), std::runtime_error &);
   }
@@ -57,7 +57,7 @@ public:
     alg.initialize();
     alg.setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
     alg.setPropertyValue("OutputWorkspace", "test_out");
     TS_ASSERT_THROWS(alg.setProperty("TwoThetaIn", 0.0),
                      std::invalid_argument &);
@@ -69,7 +69,7 @@ public:
     alg.initialize();
     alg.setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
     alg.setPropertyValue("OutputWorkspace", "test_out");
     TS_ASSERT_THROWS(alg.setProperty("TwoThetaIn", 90.0),
                      std::invalid_argument &);
@@ -82,7 +82,7 @@ public:
     alg->initialize();
     alg->setProperty(
         "InputWorkspace",
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 1));
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 1));
     alg->setPropertyValue("OutputWorkspace", "test_out");
     alg->setProperty("TwoThetaIn", 10.0);
 
diff --git a/Framework/Algorithms/test/Stitch1DManyTest.h b/Framework/Algorithms/test/Stitch1DManyTest.h
index 4e3ba5d1ecd4f55ca8b391ee56f2dc5176e5c8cb..50a0d6095dc6ed3ed33714eab3b5a589a6b35476 100644
--- a/Framework/Algorithms/test/Stitch1DManyTest.h
+++ b/Framework/Algorithms/test/Stitch1DManyTest.h
@@ -10,6 +10,7 @@
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/UnitFactory.h"
 #include <math.h>
 
@@ -51,12 +52,12 @@ private:
 
     MatrixWorkspace_sptr ws =
         WorkspaceFactory::Instance().create("Workspace2D", 2, nbins + 1, nbins);
-    ws->dataX(0) = xData1;
-    ws->dataX(1) = xData2;
-    ws->dataY(0) = yData1;
-    ws->dataY(1) = yData2;
-    ws->dataE(0) = eData1;
-    ws->dataE(1) = eData2;
+    ws->mutableX(0) = xData1;
+    ws->mutableX(1) = xData2;
+    ws->mutableY(0) = yData1;
+    ws->mutableY(1) = yData2;
+    ws->mutableE(0) = eData1;
+    ws->mutableE(1) = eData2;
     ws->getAxis(0)->unit() = UnitFactory::Instance().create("Wavelength");
 
     return ws;
@@ -187,18 +188,18 @@ public:
     auto stitched = boost::dynamic_pointer_cast<MatrixWorkspace>(outws);
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 17);
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.77919, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 1.24316, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 1.10982, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 1.79063, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.77919, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 1.24316, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 1.10982, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 1.79063, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -221,8 +222,8 @@ public:
     alg2.execute();
     MatrixWorkspace_sptr stitched2 = alg2.getProperty("OutputWorkspace");
     TS_ASSERT_EQUALS(stitched->readX(0), stitched2->readX(0));
-    TS_ASSERT_EQUALS(stitched->readY(0), stitched2->readY(0));
-    TS_ASSERT_EQUALS(stitched->readE(0), stitched2->readE(0));
+    TS_ASSERT_EQUALS(stitched->y(0).rawData(), stitched2->y(0).rawData());
+    TS_ASSERT_EQUALS(stitched->e(0).rawData(), stitched2->e(0).rawData());
 
     // Remove workspaces from ADS
     AnalysisDataService::Instance().remove("ws1");
@@ -256,25 +257,25 @@ public:
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 25);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[24], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[24], 1, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[24], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[24], 2, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.77919, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 0.90865, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[24], 1.33144, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.77919, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 0.90865, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[24], 1.33144, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 1.10982, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 1.33430, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[24], 2.00079, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 1.10982, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 1.33430, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[24], 2.00079, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -336,21 +337,21 @@ public:
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 25);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[10], 0.55000, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[18], 0.75000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[10], 0.55000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[18], 0.75000, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[10], 1.05000, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[18], 1.25000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[10], 1.05000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[18], 1.25000, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1.00000, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[10], 0.52440, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[18], 0.61237, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1.00000, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[10], 0.52440, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[18], 0.61237, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[10], 0.72457, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[18], 0.79057, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[10], 0.72457, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[18], 0.79057, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -432,25 +433,25 @@ public:
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 25);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[24], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[24], 1, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[24], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[24], 2, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.77919, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 0.90865, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[24], 1.33144, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.77919, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 0.90865, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[24], 1.33144, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 1.10982, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 1.33430, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[24], 2.00079, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 1.10982, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 1.33430, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[24], 2.00079, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -507,42 +508,42 @@ public:
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 17);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 1, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 2, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.77919, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 1.24316, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.77919, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 1.24316, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 1.10982, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 1.79063, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 1.10982, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 1.79063, 0.00001);
 
     // Second item in the output group
     stitched = boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(1));
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 17);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 1.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 1.5, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 2.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 2.5, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1.22474, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.95883, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 1.54110, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1.22474, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.95883, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 1.54110, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.58114, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 1.24263, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 2.00959, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.58114, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 1.24263, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 2.00959, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -605,42 +606,42 @@ public:
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 17);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 0.64705, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 0.55000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 0.64705, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 0.55000, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 1.24752, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 1.05000, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 1.24752, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 1.05000, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.46442, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 0.52440, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.46442, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 0.52440, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.41421, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 0.64485, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 0.72456, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.41421, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 0.64485, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 0.72456, 0.00001);
 
     // Second item in the output group
     stitched = boost::dynamic_pointer_cast<MatrixWorkspace>(group->getItem(1));
     TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
     TS_ASSERT_EQUALS(stitched->blocksize(), 17);
     // First spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(0)[0], 1.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[9], 0.94736, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(0)[16], 0.8, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[9], 0.94736, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[16], 0.8, 0.00001);
     // Second spectrum, Y values
-    TS_ASSERT_DELTA(stitched->readY(1)[0], 2.5, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[9], 1.54762, 0.00001);
-    TS_ASSERT_DELTA(stitched->readY(1)[16], 1.3, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[9], 1.54762, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[16], 1.3, 0.00001);
     // First spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(0)[0], 1.22474, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[9], 0.56195, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(0)[16], 0.63245, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[0], 1.22474, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[9], 0.56195, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(0)[16], 0.63245, 0.00001);
     // Second spectrum, E values
-    TS_ASSERT_DELTA(stitched->readE(1)[0], 1.58114, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[9], 0.71824, 0.00001);
-    TS_ASSERT_DELTA(stitched->readE(1)[16], 0.80622, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[0], 1.58114, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[9], 0.71824, 0.00001);
+    TS_ASSERT_DELTA(stitched->e(1)[16], 0.80622, 0.00001);
 
     // Test out sclae factors
     std::vector<double> scales = alg.getProperty("OutScaleFactors");
@@ -651,6 +652,52 @@ public:
     // Clear the ADS
     AnalysisDataService::Instance().clear();
   }
+
+  void test_three_workspaces_scale_LHS_workspace() {
+    // Three matrix workspaces with two spectra each
+
+    auto ws1 = createUniformWorkspace(0.1, 0.1, 1., 2.);
+    auto ws2 = createUniformWorkspace(0.8, 0.1, 1.1, 2.1);
+    auto ws3 = createUniformWorkspace(1.6, 0.1, 1.5, 2.5);
+    // The algorithm needs the workspaces to be in the ADS
+    AnalysisDataService::Instance().addOrReplace("ws1", ws1);
+    AnalysisDataService::Instance().addOrReplace("ws2", ws2);
+    AnalysisDataService::Instance().addOrReplace("ws3", ws3);
+
+    Stitch1DMany alg;
+    alg.setChild(true);
+    alg.initialize();
+    alg.setProperty("InputWorkspaces", "ws1, ws2, ws3");
+    alg.setProperty("Params", "0.1");
+    alg.setPropertyValue("ScaleRHSWorkspace", "0");
+    alg.setPropertyValue("OutputWorkspace", "outws");
+    alg.execute();
+
+    // Test output ws
+    Workspace_sptr outws = alg.getProperty("OutputWorkspace");
+    auto stitched = boost::dynamic_pointer_cast<MatrixWorkspace>(outws);
+    TS_ASSERT_EQUALS(stitched->getNumberHistograms(), 2);
+    TS_ASSERT_EQUALS(stitched->blocksize(), 25);
+    // First spectrum, Y values
+    TS_ASSERT_DELTA(stitched->y(0)[0], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[10], 1.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(0)[18], 1.5, 0.00001);
+    // Second spectrum, Y values
+    TS_ASSERT_DELTA(stitched->y(1)[0], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[10], 2.5, 0.00001);
+    TS_ASSERT_DELTA(stitched->y(1)[18], 2.5, 0.00001);
+
+    // Test out sclae factors
+    std::vector<double> scales = alg.getProperty("OutScaleFactors");
+    TS_ASSERT_EQUALS(scales.size(), 2);
+    TS_ASSERT_DELTA(scales.front(), 1.0999, 0.0001);
+    TS_ASSERT_DELTA(scales.back(), 1.3636, 0.0001);
+
+    // Remove workspaces from ADS
+    AnalysisDataService::Instance().remove("ws1");
+    AnalysisDataService::Instance().remove("ws2");
+    AnalysisDataService::Instance().remove("ws3");
+  }
 };
 
 #endif /* MANTID_ALGORITHMS_STITCH1DMANYTEST_H_ */
diff --git a/Framework/Algorithms/test/Stitch1DTest.h b/Framework/Algorithms/test/Stitch1DTest.h
index 95d75140e46c3e9c0a793fa51093dc056b86b9a3..5c23756d31daf65d1f72cdba44108cf2940aba9d 100644
--- a/Framework/Algorithms/test/Stitch1DTest.h
+++ b/Framework/Algorithms/test/Stitch1DTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/Stitch1D.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
diff --git a/Framework/Algorithms/test/StripPeaksTest.h b/Framework/Algorithms/test/StripPeaksTest.h
index 025981db15c0cc5b4c1033675c96935c9c50f1ea..20a75c97df4ccdaf9261c3a6229e18c81a20e535 100644
--- a/Framework/Algorithms/test/StripPeaksTest.h
+++ b/Framework/Algorithms/test/StripPeaksTest.h
@@ -21,7 +21,7 @@ public:
   StripPeaksTest() {
     FrameworkManager::Instance();
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 200, 0.5, 0.02);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 200, 0.5, 0.02);
     WS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
 
@@ -111,7 +111,7 @@ public:
   void setUp() override {
     FrameworkManager::Instance();
     MatrixWorkspace_sptr WS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 200, 0.5, 0.02);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 200, 0.5, 0.02);
     WS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
 
diff --git a/Framework/Algorithms/test/SumEventsByLogValueTest.h b/Framework/Algorithms/test/SumEventsByLogValueTest.h
index 749d0587c73fde428883ff0fd78f03fbbd244c8b..c0fad83aa1fcb1e8efb04e04ba3e740dd710372d 100644
--- a/Framework/Algorithms/test/SumEventsByLogValueTest.h
+++ b/Framework/Algorithms/test/SumEventsByLogValueTest.h
@@ -28,10 +28,10 @@ public:
     // InputWorkspace has to be an EventWorkspace
     TS_ASSERT_THROWS(
         alg.setProperty("InputWorkspace",
-                        WorkspaceCreationHelper::Create2DWorkspace(1, 1)),
+                        WorkspaceCreationHelper::create2DWorkspace(1, 1)),
         std::invalid_argument);
     TS_ASSERT_THROWS_NOTHING(alg.setProperty(
-        "InputWorkspace", WorkspaceCreationHelper::CreateEventWorkspace()));
+        "InputWorkspace", WorkspaceCreationHelper::createEventWorkspace()));
 
     // LogName must not be empty
     TS_ASSERT_THROWS(alg.setProperty("LogName", ""), std::invalid_argument);
@@ -39,7 +39,7 @@ public:
 
   void test_validateInputs() {
     // Create and event workspace. We don't care what data is in it.
-    EventWorkspace_sptr ws = WorkspaceCreationHelper::CreateEventWorkspace();
+    EventWorkspace_sptr ws = WorkspaceCreationHelper::createEventWorkspace();
     // Add a single-number log
     ws->mutableRun().addProperty("SingleValue", 5);
     // Add a time-series property
@@ -145,7 +145,7 @@ private:
 
   EventWorkspace_sptr createWorkspace() {
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateEventWorkspace(3, 1);
+        WorkspaceCreationHelper::createEventWorkspace(3, 1);
     Run &run = ws->mutableRun();
 
     DateAndTime run_start("2010-01-01T00:00:00");
@@ -186,7 +186,7 @@ public:
   }
 
   SumEventsByLogValueTestPerformance() {
-    ws = WorkspaceCreationHelper::CreateEventWorkspace(100, 100, 1000);
+    ws = WorkspaceCreationHelper::createEventWorkspace(100, 100, 1000);
     // Add a bunch of logs
     std::vector<DateAndTime> times;
     std::vector<int> index;
diff --git a/Framework/Algorithms/test/SumRowColumnTest.h b/Framework/Algorithms/test/SumRowColumnTest.h
index 293087a08276ddeb091c20630b93a5602cb60ec2..a663a144df64dee5a5191f30c1c1a3b43ede908a 100644
--- a/Framework/Algorithms/test/SumRowColumnTest.h
+++ b/Framework/Algorithms/test/SumRowColumnTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/SumRowColumn.h"
 #include "MantidAPI/Axis.h"
+#include "MantidKernel/Unit.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 using namespace Mantid::API;
@@ -16,7 +17,7 @@ public:
 
   SumRowColumnTest() : inputWS("SumRowColumnTestWS") {
     AnalysisDataService::Instance().add(
-        inputWS, WorkspaceCreationHelper::Create2DWorkspaceBinned(100, 10));
+        inputWS, WorkspaceCreationHelper::create2DWorkspaceBinned(100, 10));
   }
 
   ~SumRowColumnTest() override { AnalysisDataService::Instance().clear(); }
diff --git a/Framework/Algorithms/test/SumSpectraTest.h b/Framework/Algorithms/test/SumSpectraTest.h
index 17b4481d03557ccc7c4242ff41be4dfc33b06b93..528debc48b55b6e49d5ef4536b3f266c367823a2 100644
--- a/Framework/Algorithms/test/SumSpectraTest.h
+++ b/Framework/Algorithms/test/SumSpectraTest.h
@@ -3,12 +3,15 @@
 
 #include "MantidAlgorithms/SumSpectra.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <boost/lexical_cast.hpp>
 #include <cxxtest/TestSuite.h>
+#include <limits>
+#include <cmath>
 
 using namespace Mantid;
 using namespace Mantid::API;
@@ -24,8 +27,7 @@ public:
     this->inputSpace =
         WorkspaceCreationHelper::create2DWorkspaceWithFullInstrument(nTestHist,
                                                                      102, true);
-    this->inputSpace->instrumentParameters().addBool(
-        inputSpace->getDetector(1).get(), "masked", true);
+    inputSpace->mutableSpectrumInfo().setMasked(1, true);
 
     inputSpace->mutableE(5)[38] = 0.0;
   }
@@ -38,8 +40,10 @@ public:
   }
 
   void testExecWithLimits() {
-    if (!alg.isInitialized())
+    if (!alg.isInitialized()) {
       alg.initialize();
+      alg.setRethrows(true);
+    }
 
     // Set the properties
     TS_ASSERT_THROWS_NOTHING(alg.setProperty("InputWorkspace", inputSpace));
@@ -184,7 +188,7 @@ public:
     int numPixels = 100;
     int numBins = 20;
     int numEvents = 20;
-    EventWorkspace_sptr input = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr input = WorkspaceCreationHelper::createEventWorkspace(
         numPixels, numBins, numEvents);
     AnalysisDataService::Instance().addOrReplace(inName, input);
 
@@ -219,7 +223,7 @@ public:
   void testRebinnedOutputSum() {
     AnalysisDataService::Instance().clear();
     RebinnedOutput_sptr ws =
-        WorkspaceCreationHelper::CreateRebinnedOutputWorkspace();
+        WorkspaceCreationHelper::createRebinnedOutputWorkspace();
     std::string inName = "rebinTest";
     std::string outName = "rebin_sum";
 
@@ -235,6 +239,7 @@ public:
     alg3.setPropertyValue("InputWorkspace", inName);
     alg3.setPropertyValue("OutputWorkspace", outName);
     alg3.setProperty("IncludeMonitors", false);
+    alg3.setProperty("RemoveSpecialValues", true);
     alg3.execute();
     TS_ASSERT(alg3.isExecuted());
 
@@ -246,12 +251,12 @@ public:
     TS_ASSERT_EQUALS(output->getNumberHistograms(), 1);
     TS_ASSERT_EQUALS(output->blocksize(), 6);
     // Row with full acceptance
-    TS_ASSERT_EQUALS(output->mutableY(0)[1], 1.);
-    TS_ASSERT_DELTA(output->mutableE(0)[1], 0.40824829046386296, 1.e-5);
+    TS_ASSERT_EQUALS(output->y(0)[1], 1.);
+    TS_ASSERT_DELTA(output->e(0)[1], 0.40824829046386296, 1.e-5);
     TS_ASSERT_EQUALS(output->dataF(0)[1], 6.);
     // Row with limited, but non-zero acceptance, shouldn't have nans!
-    TS_ASSERT_DELTA(output->mutableY(0)[5], 0.66666, 1.e-5);
-    TS_ASSERT_DELTA(output->mutableE(0)[5], 0.47140452079103173, 1.e-5);
+    TS_ASSERT_DELTA(output->y(0)[5], 0.66666, 1.e-5);
+    TS_ASSERT_DELTA(output->e(0)[5], 0.47140452079103173, 1.e-5);
     TS_ASSERT_EQUALS(output->dataF(0)[5], 3.);
 
     TS_ASSERT(output->run().hasProperty("NumAllSpectra"))
@@ -345,7 +350,7 @@ public:
     int nHist = 4;
 
     MatrixWorkspace_sptr tws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nHist, nBins);
     std::string inName = "rebinTest";
     std::string outName = "sumWS";
 
@@ -422,6 +427,80 @@ public:
     AnalysisDataService::Instance().remove(outName);
   }
 
+  void testRemoveSpecialValuesOn() {
+    constexpr size_t numOfHistos = 2;
+    auto inWs =
+        WorkspaceCreationHelper::create2DWorkspace123(numOfHistos, 3, true);
+    auto &yVals = inWs->mutableY(1);
+
+    yVals[0] = std::numeric_limits<double>::infinity();
+    yVals[1] = NAN;
+
+    Mantid::Algorithms::SumSpectra sumSpectraAlg;
+    sumSpectraAlg.initialize();
+    sumSpectraAlg.setRethrows(true);
+
+    sumSpectraAlg.setProperty("InputWorkspace", inWs);
+    const std::string outWsName = "testSpecialVals";
+    sumSpectraAlg.setPropertyValue("OutputWorkspace", outWsName);
+    sumSpectraAlg.setProperty("RemoveSpecialValues", true);
+
+    TS_ASSERT_THROWS_NOTHING(sumSpectraAlg.execute());
+    TS_ASSERT(sumSpectraAlg.isExecuted());
+
+    Workspace_sptr output;
+    TS_ASSERT_THROWS_NOTHING(
+        output = AnalysisDataService::Instance().retrieve(outWsName));
+    Workspace2D_const_sptr output2D =
+        boost::dynamic_pointer_cast<const Workspace2D>(output);
+
+    auto outYVals = output2D->y(0);
+    // We expect one less because of inf and NaN
+    TS_ASSERT_EQUALS(outYVals[0], 2.);
+    TS_ASSERT_EQUALS(outYVals[1], 2.);
+    // Should get the correct amount now
+    TS_ASSERT_EQUALS(outYVals[2], 4.);
+
+    AnalysisDataService::Instance().remove(outWsName);
+  }
+
+  void testRemoveSpecialValuesOff() {
+    constexpr size_t numOfHistos = 2;
+    auto inWs =
+        WorkspaceCreationHelper::create2DWorkspace123(numOfHistos, 3, true);
+    auto &yVals = inWs->mutableY(1);
+
+    yVals[0] = std::numeric_limits<double>::infinity();
+    yVals[1] = NAN;
+
+    Mantid::Algorithms::SumSpectra sumSpectraAlg;
+    sumSpectraAlg.initialize();
+    sumSpectraAlg.setRethrows(true);
+
+    sumSpectraAlg.setProperty("InputWorkspace", inWs);
+    const std::string outWsName = "testSpecialVals";
+    sumSpectraAlg.setPropertyValue("OutputWorkspace", outWsName);
+    sumSpectraAlg.setProperty("RemoveSpecialValues", false);
+
+    TS_ASSERT_THROWS_NOTHING(sumSpectraAlg.execute());
+    TS_ASSERT(sumSpectraAlg.isExecuted());
+
+    Workspace_sptr output;
+    TS_ASSERT_THROWS_NOTHING(
+        output = AnalysisDataService::Instance().retrieve(outWsName));
+    Workspace2D_const_sptr output2D =
+        boost::dynamic_pointer_cast<const Workspace2D>(output);
+
+    auto outYVals = output2D->y(0);
+    // We expect a NaN and an Inf to propagate here
+    TS_ASSERT_EQUALS(std::isnormal(outYVals[0]), false);
+    TS_ASSERT_EQUALS(std::isnormal(outYVals[1]), false);
+    // Should get the correct amount now
+    TS_ASSERT_EQUALS(outYVals[2], 4.);
+
+    AnalysisDataService::Instance().remove(outWsName);
+  }
+
 private:
   int nTestHist;
   Mantid::Algorithms::SumSpectra alg; // Test with range limits
@@ -441,9 +520,9 @@ public:
   }
 
   SumSpectraTestPerformance() {
-    input = WorkspaceCreationHelper::Create2DWorkspaceBinned(40000, 10000);
+    input = WorkspaceCreationHelper::create2DWorkspaceBinned(40000, 10000);
     inputEvent =
-        WorkspaceCreationHelper::CreateEventWorkspace(20000, 1000, 2000);
+        WorkspaceCreationHelper::createEventWorkspace(20000, 1000, 2000);
   }
 
   void testExec2D() {
diff --git a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
index 272ad4e9c8cfe25cb067d28290c02ad4c3d6a9db..65a5fe6bb7c7f6cf1dc03fbabefa32782925cc4b 100644
--- a/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
+++ b/Framework/Algorithms/test/TOFSANSResolutionByPixelTest.h
@@ -137,10 +137,10 @@ Mantid::API::MatrixWorkspace_sptr createTestWorkspace(
     std::vector<double> guideLogDetails = std::vector<double>()) {
   Mantid::API::MatrixWorkspace_sptr ws2d;
   if (isModerator) {
-    ws2d = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    ws2d = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         twos(), static_cast<int>(nhist), x0, x1, dx, true);
   } else {
-    ws2d = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    ws2d = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         ones(), static_cast<int>(nhist), x0, x1, dx, true);
   }
 
diff --git a/Framework/Algorithms/test/TransposeTest.h b/Framework/Algorithms/test/TransposeTest.h
index a6a35a2fd7023d11bee54a4fc9ced90c71104a50..6ff040702992b08782a45521b77f2d549aed1693 100644
--- a/Framework/Algorithms/test/TransposeTest.h
+++ b/Framework/Algorithms/test/TransposeTest.h
@@ -101,7 +101,7 @@ public:
 
   void testRebinnedOutput() {
     RebinnedOutput_sptr inputWS =
-        WorkspaceCreationHelper::CreateRebinnedOutputWorkspace();
+        WorkspaceCreationHelper::createRebinnedOutputWorkspace();
     std::string inName = inputWS->getName();
     AnalysisDataService::Instance().addOrReplace(inName, inputWS);
     std::string outName = "rebinTrans";
@@ -169,7 +169,7 @@ public:
 
     // set up testRebinnedOutputPerformance
     RebinnedOutput_sptr inputWS =
-        WorkspaceCreationHelper::CreateRebinnedOutputWorkspace();
+        WorkspaceCreationHelper::createRebinnedOutputWorkspace();
     std::string inName = rebinned_inputWS;
     AnalysisDataService::Instance().addOrReplace(inName, inputWS);
   }
diff --git a/Framework/Algorithms/test/UnGroupWorkspaceTest.h b/Framework/Algorithms/test/UnGroupWorkspaceTest.h
index 601170796c3990c3f10b43a6ffdcd761e453c634..70a5ea9404c01f1d1bb99a5e6f909149074df88e 100644
--- a/Framework/Algorithms/test/UnGroupWorkspaceTest.h
+++ b/Framework/Algorithms/test/UnGroupWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidAlgorithms/UnGroupWorkspace.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
 class UnGroupWorkspaceTest : public CxxTest::TestSuite {
@@ -111,7 +112,7 @@ private:
   Mantid::API::MatrixWorkspace_sptr
   addTestMatrixWorkspaceToADS(const std::string &name) {
     auto &ads = Mantid::API::AnalysisDataService::Instance();
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ads.add(name, ws);
     return ws;
   }
diff --git a/Framework/Algorithms/test/UnaryOperationTest.h b/Framework/Algorithms/test/UnaryOperationTest.h
index 2e0ec86d23ee01bb83b5d9e7de82858d44363bab..c76a88bc8ee9c6da7a1e547a50b4b96a5238fa49 100644
--- a/Framework/Algorithms/test/UnaryOperationTest.h
+++ b/Framework/Algorithms/test/UnaryOperationTest.h
@@ -65,7 +65,7 @@ public:
 
   void testExec() {
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("InputWS", inputWS);
 
     UnaryOpHelper helper3;
diff --git a/Framework/Algorithms/test/UnwrapSNSTest.h b/Framework/Algorithms/test/UnwrapSNSTest.h
index 78f1661f1a8c5f74eab87d7f580431ad1f50debb..3c03b24c4d0ba2ccf1b4d2469da8ffe82c22da52 100644
--- a/Framework/Algorithms/test/UnwrapSNSTest.h
+++ b/Framework/Algorithms/test/UnwrapSNSTest.h
@@ -27,7 +27,7 @@ private:
 
   void makeFakeEventWorkspace(std::string wsName) {
     // Make an event workspace with 2 events in each bin.
-    EventWorkspace_sptr test_in = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr test_in = WorkspaceCreationHelper::createEventWorkspace(
         NUMPIXELS, NUMBINS, NUMBINS, 0.0, BIN_DELTA, 2);
     // Fake a d-spacing unit in the data.
     test_in->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
diff --git a/Framework/Algorithms/test/VesuvioL1ThetaResolutionTest.h b/Framework/Algorithms/test/VesuvioL1ThetaResolutionTest.h
index 73e411e2f247f4eeb31ce35bd62ab2c69cad0a59..eb5e081c2da3e59d1c27d4774025d8fa11bdf83b 100644
--- a/Framework/Algorithms/test/VesuvioL1ThetaResolutionTest.h
+++ b/Framework/Algorithms/test/VesuvioL1ThetaResolutionTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidAlgorithms/VesuvioL1ThetaResolution.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/SpectraAxis.h"
diff --git a/Framework/Algorithms/test/WeightedMeanOfWorkspaceTest.h b/Framework/Algorithms/test/WeightedMeanOfWorkspaceTest.h
index f00686b59302d7fd0def80bb4388da07f4bbd8da..d5a20882197977c1939f10cbf3ef0c4c44e53010 100644
--- a/Framework/Algorithms/test/WeightedMeanOfWorkspaceTest.h
+++ b/Framework/Algorithms/test/WeightedMeanOfWorkspaceTest.h
@@ -116,11 +116,11 @@ private:
     if (doMasked) {
       masked.insert(0);
     }
-    return WorkspaceCreationHelper::Create2DWorkspace123(4, 3, true, masked);
+    return WorkspaceCreationHelper::create2DWorkspace123(4, 3, true, masked);
   }
 
   EventWorkspace_sptr createEventWorkspace() {
-    return WorkspaceCreationHelper::CreateEventWorkspace();
+    return WorkspaceCreationHelper::createEventWorkspace();
   }
 };
 
diff --git a/Framework/Algorithms/test/WeightedMeanTest.h b/Framework/Algorithms/test/WeightedMeanTest.h
index 76617fc580749934275e348efd49f5f7c1e16839..7c994c4b3ece5087dbc9ebfc4f96cf3a1339d384 100644
--- a/Framework/Algorithms/test/WeightedMeanTest.h
+++ b/Framework/Algorithms/test/WeightedMeanTest.h
@@ -2,6 +2,7 @@
 #define WEIGHTEDMEANTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAlgorithms/WeightedMean.h"
 #include "MantidDataHandling/LoadRaw3.h"
 
diff --git a/Framework/Algorithms/test/WienerSmoothTest.h b/Framework/Algorithms/test/WienerSmoothTest.h
index a0816cee670e2cdc161d50c6b90913ac9bd797a0..87d856f4d7793bc2b20d656cb20c5da0b2f94e1b 100644
--- a/Framework/Algorithms/test/WienerSmoothTest.h
+++ b/Framework/Algorithms/test/WienerSmoothTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAlgorithms/WienerSmooth.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/Algorithms/test/WorkflowAlgorithmRunnerTest.h b/Framework/Algorithms/test/WorkflowAlgorithmRunnerTest.h
index d72182ee6dcac587a89c9a190baf868f4a9d7b5e..d349d0cf3beebcb27ebe526946b61d7bb837579b 100644
--- a/Framework/Algorithms/test/WorkflowAlgorithmRunnerTest.h
+++ b/Framework/Algorithms/test/WorkflowAlgorithmRunnerTest.h
@@ -6,6 +6,7 @@
 #include "MantidAlgorithms/WorkflowAlgorithmRunner.h"
 
 #include "MantidAlgorithms/DeleteWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/Algorithms/test/WorkspaceGroupTest.h b/Framework/Algorithms/test/WorkspaceGroupTest.h
index 978c70964f0d1dd4a55fc696b71dd732345533d3..658b5a34ddc362b4df58e49ffb209b7fe7d451a6 100644
--- a/Framework/Algorithms/test/WorkspaceGroupTest.h
+++ b/Framework/Algorithms/test/WorkspaceGroupTest.h
@@ -91,13 +91,13 @@ public:
     int nHist = 20, nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr work_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     WorkspaceGroup_sptr wsSptr = WorkspaceGroup_sptr(new WorkspaceGroup);
     if (wsSptr) {
@@ -177,12 +177,10 @@ public:
     int nHist = 20, nBins = 10;
     // Register the workspace in the data service
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins, 1);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins, 1);
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins, 1);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins, 1);
     Instrument_sptr instr(new Instrument);
-    work_in1->setInstrument(instr);
-    work_in2->setInstrument(instr);
 
     // set some dead detectors
     Counts yDead(nBins, 0);
@@ -198,6 +196,8 @@ public:
       instr->add(det);
       instr->markAsDetector(det);
     }
+    work_in1->setInstrument(instr);
+    work_in2->setInstrument(instr);
 
     for (int i = 0; i < nBins; i++) {
       if (i % 2 == 0) {
@@ -304,9 +304,9 @@ public:
     constexpr int nHist = 20, nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     const std::string ws1Name = "test_ws1";
     const std::string ws2Name = "test_ws2";
@@ -344,11 +344,11 @@ public:
     constexpr int nHist = 20, nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     const std::string ws1Name = "test_ws1";
     const std::string ws2Name = "test_ws2";
@@ -388,11 +388,11 @@ public:
     constexpr int nHist = 20, nBins = 10;
     // Register the workspace in the data service
     MatrixWorkspace_sptr inGroupWs1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr inGroupWs2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr notInGroupWs =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     const std::string inGroupWsName1 = "test_ws1";
     const std::string inGroupWsName2 = "test_ws2";
@@ -436,22 +436,22 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr worklhs_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     MatrixWorkspace_sptr workrhs_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     WorkspaceGroup_sptr wsSptr = WorkspaceGroup_sptr(new WorkspaceGroup);
     if (wsSptr) {
@@ -562,18 +562,18 @@ public:
     int nHist = 10, nBins = 20;
 
     MatrixWorkspace_sptr worklhs_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     if (worklhs_in1)
       AnalysisDataService::Instance().add("testlhs_in1", worklhs_in1);
 
     MatrixWorkspace_sptr workrhs_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr workrhs_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     WorkspaceGroup_sptr wsSptr1 = WorkspaceGroup_sptr(new WorkspaceGroup);
     if (wsSptr1) {
@@ -658,13 +658,13 @@ public:
     int nHist = 10, nBins = 20;
     // Register the workspace in the data service
     MatrixWorkspace_sptr worklhs_in1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in2 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace123(nHist, nBins);
     MatrixWorkspace_sptr worklhs_in4 =
-        WorkspaceCreationHelper::Create2DWorkspace154(nHist, nBins);
+        WorkspaceCreationHelper::create2DWorkspace154(nHist, nBins);
 
     WorkspaceGroup_sptr wsSptr = WorkspaceGroup_sptr(new WorkspaceGroup);
     if (wsSptr) {
diff --git a/Framework/Beamline/CMakeLists.txt b/Framework/Beamline/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..7b30b183d5d4d9a6174857f762bf1a90cc41f6f3
--- /dev/null
+++ b/Framework/Beamline/CMakeLists.txt
@@ -0,0 +1,47 @@
+set ( SRC_FILES
+	src/DetectorInfo.cpp
+)
+
+set ( INC_FILES
+	inc/MantidBeamline/DetectorInfo.h
+)
+
+set ( TEST_FILES
+	DetectorInfoTest.h
+)
+
+if (COVERALLS)
+  foreach( loop_var ${SRC_FILES} ${INC_FILES})
+    set_property(GLOBAL APPEND PROPERTY COVERAGE_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}")
+  endforeach(loop_var)
+endif()
+
+if(UNITY_BUILD)
+  include(UnityBuild)
+  enable_unity_build(Beamline SRC_FILES SRC_UNITY_IGNORE_FILES 10)
+endif(UNITY_BUILD)
+
+# Add the target for this directory
+add_library ( Beamline ${SRC_FILES} ${INC_FILES} )
+# Set the name of the generated library
+set_target_properties ( Beamline PROPERTIES OUTPUT_NAME MantidBeamline
+  COMPILE_DEFINITIONS IN_MANTID_BEAMLINE )
+
+if (OSX_VERSION VERSION_GREATER 10.8)
+  set_target_properties ( Beamline PROPERTIES INSTALL_RPATH "@loader_path/../MacOS")
+endif ()
+
+# Add to the 'Framework' group in VS
+set_property ( TARGET Beamline PROPERTY FOLDER "MantidFramework" )
+
+target_link_libraries ( Beamline LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME} 
+                        ${GSL_LIBRARIES} ${MANTIDLIBS} )
+
+# Add the unit tests directory
+add_subdirectory ( test )
+
+###########################################################################
+# Installation settings
+###########################################################################
+
+install ( TARGETS Beamline ${SYSTEM_PACKAGE_TARGET} DESTINATION ${LIB_DIR} )
diff --git a/Framework/Beamline/inc/MantidBeamline/DetectorInfo.h b/Framework/Beamline/inc/MantidBeamline/DetectorInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..a51896de2ceb808eb86a985eb561e95b63140006
--- /dev/null
+++ b/Framework/Beamline/inc/MantidBeamline/DetectorInfo.h
@@ -0,0 +1,69 @@
+#ifndef MANTID_BEAMLINE_DETECTORINFO_H_
+#define MANTID_BEAMLINE_DETECTORINFO_H_
+
+#include "MantidBeamline/DllConfig.h"
+
+namespace Mantid {
+namespace Beamline {
+
+/** Beamline::DetectorInfo provides easy access to commonly used parameters of
+  individual detectors (pixels) in a beamline, such as mask and monitor flags,
+  positions, L2, and 2-theta.
+
+  Currently only a limited subset of functionality is implemented in
+  Beamline::DetectorInfo. The remainder is available in API::DetectorInfo which
+  acts as a wrapper around the old instrument implementation. API::DetectorInfo
+  will be removed once all functionality has been moved to
+  Beamline::DetectorInfo. For the time being, API::DetectorInfo will forward
+  calls to Beamline::DetectorInfo when applicable.
+
+  The reason for having both DetectorInfo classes in parallel is:
+  - We need to be able to move around the DetectorInfo object including data it
+    contains such as a vector of mask flags. This is relevant for the interface
+    of ExperimentInfo, when replacing the ParameterMap or when setting a new
+    instrument.
+  - API::DetectorInfo contains a caching mechanism and is frequently flushed
+    upon modification of the instrument and is thus hard to handle outside the
+    context of its owning workspace.
+  Splitting DetectorInfo into two classes seemed to be the safest and easiest
+  solution to this.
+
+
+  @author Simon Heybrock
+  @date 2016
+
+  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 MANTID_BEAMLINE_DLL DetectorInfo {
+public:
+  DetectorInfo(const size_t numberOfDetectors);
+
+  size_t size() const;
+
+private:
+  size_t m_size;
+};
+
+} // namespace Beamline
+} // namespace Mantid
+
+#endif /* MANTID_BEAMLINE_DETECTORINFO_H_ */
diff --git a/Framework/Beamline/inc/MantidBeamline/DllConfig.h b/Framework/Beamline/inc/MantidBeamline/DllConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..2fa2c3a5b80990c1cd1bc8f13dcae29e53a9cb77
--- /dev/null
+++ b/Framework/Beamline/inc/MantidBeamline/DllConfig.h
@@ -0,0 +1,37 @@
+#ifndef MANTID_BEAMLINE_DLLCONFIG_H_
+#define MANTID_BEAMLINE_DLLCONFIG_H_
+
+/*
+  This file contains the DLLExport/DLLImport linkage configuration for the
+  Beamline library
+
+  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>
+*/
+#include "MantidKernel/System.h"
+
+#ifdef IN_MANTID_BEAMLINE
+#define MANTID_BEAMLINE_DLL DLLExport
+#else
+#define MANTID_BEAMLINE_DLL DLLImport
+#endif // IN_MANTID_BEAMLINE
+
+#endif // MANTID_BEAMLINE_DLLCONFIG_H_
diff --git a/Framework/Beamline/src/DetectorInfo.cpp b/Framework/Beamline/src/DetectorInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a0cdde6bf829cfa6ad50cecbd1ee8269ff739af0
--- /dev/null
+++ b/Framework/Beamline/src/DetectorInfo.cpp
@@ -0,0 +1,14 @@
+#include "MantidBeamline/DetectorInfo.h"
+
+namespace Mantid {
+namespace Beamline {
+
+DetectorInfo::DetectorInfo(const size_t numberOfDetectors)
+    : m_size(numberOfDetectors) {}
+
+/// Returns the size of the DetectorInfo, i.e., the number of detectors in the
+/// instrument.
+size_t DetectorInfo::size() const { return m_size; }
+
+} // namespace Beamline
+} // namespace Mantid
diff --git a/Framework/Beamline/test/CMakeLists.txt b/Framework/Beamline/test/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..522c138e12a98d2bbe0d4045e80c8d2454d84ab1
--- /dev/null
+++ b/Framework/Beamline/test/CMakeLists.txt
@@ -0,0 +1,13 @@
+if ( CXXTEST_FOUND )
+  include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ../../TestHelpers/inc)
+
+  cxxtest_add_test ( BeamlineTest ${TEST_FILES} ${GMOCK_TEST_FILES})
+  target_link_libraries( BeamlineTest LINK_PRIVATE ${TCMALLOC_LIBRARIES_LINKTIME}
+    Beamline
+    ${Boost_LIBRARIES}
+    ${GTEST_LIBRARIES} )
+  
+  add_dependencies ( FrameworkTests BeamlineTest )
+  # Add to the 'FrameworkTests' group in VS
+  set_property ( TARGET BeamlineTest PROPERTY FOLDER "UnitTests" )
+endif ()
diff --git a/Framework/Beamline/test/DetectorInfoTest.h b/Framework/Beamline/test/DetectorInfoTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..47e2dd476bc636c03590c6e44dd2e1fe21e10e1d
--- /dev/null
+++ b/Framework/Beamline/test/DetectorInfoTest.h
@@ -0,0 +1,56 @@
+#ifndef MANTID_BEAMLINE_DETECTORINFOTEST_H_
+#define MANTID_BEAMLINE_DETECTORINFOTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidBeamline/DetectorInfo.h"
+#include "MantidKernel/make_unique.h"
+
+using namespace Mantid;
+using Beamline::DetectorInfo;
+
+class DetectorInfoTest : 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 DetectorInfoTest *createSuite() { return new DetectorInfoTest(); }
+  static void destroySuite(DetectorInfoTest *suite) { delete suite; }
+
+  void test_constructor() {
+    std::unique_ptr<DetectorInfo> detInfo;
+    TS_ASSERT_THROWS_NOTHING(detInfo = Kernel::make_unique<DetectorInfo>(0));
+    TS_ASSERT_EQUALS(detInfo->size(), 0);
+    TS_ASSERT_THROWS_NOTHING(detInfo = Kernel::make_unique<DetectorInfo>(1));
+    TS_ASSERT_EQUALS(detInfo->size(), 1);
+  }
+
+  void test_copy() {
+    const DetectorInfo source(7);
+    const auto copy(source);
+    TS_ASSERT_EQUALS(copy.size(), 7);
+  }
+
+  void test_move() {
+    DetectorInfo source(7);
+    const auto moved(std::move(source));
+    TS_ASSERT_EQUALS(moved.size(), 7);
+    // TODO once DetectorInfo has moveable fields, check that they are cleared.
+  }
+
+  void test_assign() {
+    const DetectorInfo source(7);
+    DetectorInfo assignee(1);
+    assignee = source;
+    TS_ASSERT_EQUALS(assignee.size(), 7);
+  }
+
+  void test_move_assign() {
+    DetectorInfo source(7);
+    DetectorInfo assignee(1);
+    assignee = std::move(source);
+    TS_ASSERT_EQUALS(assignee.size(), 7);
+    // TODO once DetectorInfo has moveable fields, check that they are cleared.
+  }
+};
+
+#endif /* MANTID_BEAMLINE_DETECTORINFOTEST_H_ */
diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt
index 72aa0ac8464f4b85e16195a9a35c6b9c2ec15467..e2a5e03d7a852c1b4b6b97dfe1a5b7629c8019ff 100644
--- a/Framework/CMakeLists.txt
+++ b/Framework/CMakeLists.txt
@@ -73,11 +73,15 @@ add_subdirectory (HistogramData)
 include_directories (Indexing/inc)
 add_subdirectory (Indexing)
 
+include_directories (Beamline/inc)
+add_subdirectory (Beamline)
+
 # HistogramData has header-only dependency on Kernel, so Kernel comes after.
 set ( MANTIDLIBS ${MANTIDLIBS} HistogramData )
 # Indexing has header-only dependency on Kernel, so Kernel comes after.
 set ( MANTIDLIBS ${MANTIDLIBS} Indexing )
 set ( MANTIDLIBS ${MANTIDLIBS} Kernel )
+set ( MANTIDLIBS ${MANTIDLIBS} Beamline )
 
 include_directories (Geometry/inc)
 # muParser needed by Geometry and subsequent packages
@@ -139,7 +143,7 @@ add_subdirectory (ScriptRepository)
 # Add a custom target to build all of the Framework
 ###########################################################################
 
-set ( FRAMEWORK_LIBS Kernel HistogramData Indexing Geometry API DataObjects
+set ( FRAMEWORK_LIBS Kernel HistogramData Indexing Beamline Geometry API DataObjects
                      PythonKernelModule PythonGeometryModule PythonAPIModule
                      PythonDataObjectsModule
                      DataHandling Nexus Algorithms CurveFitting ICat
diff --git a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
index 9611706f997481becb78fb207517bbe128f7468c..bb7a92f68c9de6772634f8ec7a904cd75f01817a 100644
--- a/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/IndexSXPeaks.h
@@ -1,14 +1,13 @@
 #ifndef MANTID_CRYSTAL_INDEX_SX_PEAKS_H_
 #define MANTID_CRYSTAL_INDEX_SX_PEAKS_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include <boost/tuple/tuple.hpp>
 #include "MantidAPI/IPeaksWorkspace_fwd.h"
 #include "MantidGeometry/Crystal/UnitCell.h"
 #include "MantidKernel/V3D.h"
+
+#include <iterator>
 #include <set>
 
 namespace Mantid {
diff --git a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
index a20c141abfb32bf64436a78348b8473c0871b568..6bd149be3fca963d7651737212058c7d87a113e9 100644
--- a/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
+++ b/Framework/Crystal/inc/MantidCrystal/LoadIsawPeaks.h
@@ -46,7 +46,6 @@ private:
 
   /// Reads calibration/detector section and returns first word of next line
   std::string ApplyCalibInfo(std::ifstream &in, std::string startChar,
-                             Geometry::Instrument_const_sptr instr_old,
                              Geometry::Instrument_const_sptr instr, double &T0);
 
   /// Reads first line of peaks file and returns first word of next line
diff --git a/Framework/Crystal/inc/MantidCrystal/PeakHKLErrors.h b/Framework/Crystal/inc/MantidCrystal/PeakHKLErrors.h
index c9d3a65b398adba66ce701aeee1d0b959a9bd52d..7f3ab7aeb958a6066c0ce66c776c767cee30f7b1 100644
--- a/Framework/Crystal/inc/MantidCrystal/PeakHKLErrors.h
+++ b/Framework/Crystal/inc/MantidCrystal/PeakHKLErrors.h
@@ -124,7 +124,7 @@ public:
     if (attName == "OptRuns") {
       OptRuns = value.asString();
 
-      if (OptRuns.size() < 1)
+      if (OptRuns.empty())
         return;
 
       if (OptRuns.at(0) != '/')
diff --git a/Framework/Crystal/src/AnvredCorrection.cpp b/Framework/Crystal/src/AnvredCorrection.cpp
index f9d6582aa35fec123454e69cb944198da11f3c8a..a51b6e243d22b6b8d0ad4cc59a22d1b8f9315ba1 100644
--- a/Framework/Crystal/src/AnvredCorrection.cpp
+++ b/Framework/Crystal/src/AnvredCorrection.cpp
@@ -7,6 +7,7 @@
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/Material.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/Fast_Exponential.h"
 #include "MantidKernel/VectorHelper.h"
diff --git a/Framework/Crystal/src/CalculatePeaksHKL.cpp b/Framework/Crystal/src/CalculatePeaksHKL.cpp
index f59327ce146338b764ef8d1550843fd781148c1b..7f5b556a522ec6bda12211082153f4b5c1256f0a 100644
--- a/Framework/Crystal/src/CalculatePeaksHKL.cpp
+++ b/Framework/Crystal/src/CalculatePeaksHKL.cpp
@@ -52,7 +52,7 @@ void CalculatePeaksHKL::exec() {
   const int n_peaks = ws->getNumberPeaks();
 
   OrientedLattice o_lattice = ws->mutableSample().getOrientedLattice();
-  Matrix<double> UB = o_lattice.getUB();
+  const Matrix<double> &UB = o_lattice.getUB();
 
   DblMatrix UB_inverse(UB);
 
diff --git a/Framework/Crystal/src/CentroidPeaks.cpp b/Framework/Crystal/src/CentroidPeaks.cpp
index cc719aa2e16f677f56bc5b3a92bd3a66ee2c763e..888876a15be223593d34f67be51e0b9a1960b22b 100644
--- a/Framework/Crystal/src/CentroidPeaks.cpp
+++ b/Framework/Crystal/src/CentroidPeaks.cpp
@@ -1,6 +1,7 @@
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidCrystal/CentroidPeaks.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/VectorHelper.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 
diff --git a/Framework/Crystal/src/ClearUB.cpp b/Framework/Crystal/src/ClearUB.cpp
index 1e44ed75b80c0199c7235de4a5636a11ab1938a7..be14295b71967b0b33fdbc3be11a66257b76f3c2 100644
--- a/Framework/Crystal/src/ClearUB.cpp
+++ b/Framework/Crystal/src/ClearUB.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/MultipleExperimentInfos.h"
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/Workspace.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/Crystal/src/IndexPeaks.cpp b/Framework/Crystal/src/IndexPeaks.cpp
index dfb86fb5e615bc981917138d58a7e24b3f36ee99..ddc1c214b7db7ad624bbb50188faed559522527e 100644
--- a/Framework/Crystal/src/IndexPeaks.cpp
+++ b/Framework/Crystal/src/IndexPeaks.cpp
@@ -51,7 +51,7 @@ void IndexPeaks::exec() {
   }
 
   OrientedLattice o_lattice = ws->mutableSample().getOrientedLattice();
-  Matrix<double> UB = o_lattice.getUB();
+  const Matrix<double> &UB = o_lattice.getUB();
 
   if (!IndexingUtils::CheckUB(UB)) {
     throw std::runtime_error(
diff --git a/Framework/Crystal/src/IntegratePeaksHybrid.cpp b/Framework/Crystal/src/IntegratePeaksHybrid.cpp
index 7ccdfd32d0ee4f652fafde3f7edd23b78420b503..e36312aec51e1c528248271aa0783815b529f7ea 100644
--- a/Framework/Crystal/src/IntegratePeaksHybrid.cpp
+++ b/Framework/Crystal/src/IntegratePeaksHybrid.cpp
@@ -44,6 +44,7 @@
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/IMDIterator.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/BoundedValidator.h"
diff --git a/Framework/Crystal/src/LoadIsawPeaks.cpp b/Framework/Crystal/src/LoadIsawPeaks.cpp
index 5c9ff368422c4360be891af663901c14a9384e1b..eacca1e5594803ee6383886487ffedbdd759edad 100644
--- a/Framework/Crystal/src/LoadIsawPeaks.cpp
+++ b/Framework/Crystal/src/LoadIsawPeaks.cpp
@@ -5,8 +5,10 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidKernel/OptionalBool.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/Unit.h"
 
 using Mantid::Kernel::Strings::readToEndOfLine;
@@ -106,16 +108,14 @@ void LoadIsawPeaks::exec() {
 }
 
 //----------------------------------------------------------------------------------------------
-std::string
-LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
-                              Geometry::Instrument_const_sptr instr_old,
-                              Geometry::Instrument_const_sptr instr,
-                              double &T0) {
-  ParameterMap_sptr parMap1 = instr_old->getParameterMap();
+std::string LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in,
+                                          std::string startChar,
+                                          Geometry::Instrument_const_sptr instr,
+                                          double &T0) {
 
   ParameterMap_sptr parMap = instr->getParameterMap();
 
-  while (in.good() && (startChar.size() < 1 || startChar != "7")) {
+  while (in.good() && (startChar.empty() || startChar != "7")) {
     readToEndOfLine(in, true);
     startChar = getWord(in, false);
   }
@@ -136,7 +136,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
     iss >> T0;
     V3D sampPos = instr->getSample()->getPos();
     SCDCalibratePanels::FixUpSourceParameterMap(instr, L1 / 100, sampPos,
-                                                parMap1);
+                                                parMap);
   } catch (...) {
     g_log.error() << "Invalid L1 or Time offset\n";
     throw std::invalid_argument("Invalid L1 or Time offset");
@@ -144,7 +144,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
 
   readToEndOfLine(in, true);
   startChar = getWord(in, false);
-  while (in.good() && (startChar.size() < 1 || startChar != "5")) {
+  while (in.good() && (startChar.empty() || startChar != "5")) {
     readToEndOfLine(in, true);
     startChar = getWord(in, false);
   }
@@ -159,7 +159,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
     std::string line;
     for (int i = 0; i < 16; i++) {
       std::string s = getWord(in, false);
-      if (s.size() < 1) {
+      if (s.empty()) {
         g_log.error() << "Not enough info to describe panel \n";
         throw std::length_error("Not enough info to describe panel ");
       }
@@ -196,7 +196,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
     }
     bankName += SbankNum;
     boost::shared_ptr<const Geometry::IComponent> bank =
-        getCachedBankByName(bankName, instr_old);
+        getCachedBankByName(bankName, instr);
 
     if (!bank) {
       g_log.error() << "There is no bank " << bankName
@@ -216,7 +216,7 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
     bankRot.inverse();
     Quat dRot = thisRot * bankRot;
 
-    boost::shared_ptr<const Geometry::RectangularDetector> bankR =
+    auto bankR =
         boost::dynamic_pointer_cast<const Geometry::RectangularDetector>(bank);
 
     if (!bankR)
@@ -227,11 +227,10 @@ LoadIsawPeaks::ApplyCalibInfo(std::ifstream &in, std::string startChar,
       DetWScale = width / bankR->xsize() / 100;
       DetHtScale = height / bankR->ysize() / 100;
     }
-    std::vector<std::string> bankNames;
-    bankNames.push_back(bankName);
+    const std::vector<std::string> bankNames{bankName};
 
     SCDCalibratePanels::FixUpBankParameterMap(
-        bankNames, instr, dPos, dRot, DetWScale, DetHtScale, parMap1, false);
+        bankNames, instr, dPos, dRot, DetWScale, DetHtScale, parMap, false);
   }
   return startChar;
 }
@@ -294,13 +293,9 @@ std::string LoadIsawPeaks::readHeader(PeaksWorkspace_sptr outWS,
   // Populate the instrument parameters in this workspace - this works around a
   // bug
   tempWS->populateInstrumentParameters();
-  Geometry::Instrument_const_sptr instr_old = tempWS->getInstrument();
-  auto instr = instr_old;
-  /*auto map = boost::make_shared<ParameterMap>();
-  auto instr = boost::make_shared<const Geometry::Instrument>(
-      instr_old->baseInstrument(), map);*/
+  Geometry::Instrument_const_sptr instr = tempWS->getInstrument();
 
-  std::string s = ApplyCalibInfo(in, "", instr_old, instr, T0);
+  std::string s = ApplyCalibInfo(in, "", instr, T0);
   outWS->setInstrument(instr);
 
   // Now skip all lines on L1, detector banks, etc. until we get to a block of
@@ -565,7 +560,7 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
       Peak peak = readPeak(outWS, s, in, seqNum, bankName, qSign);
 
       // Get the calculated goniometer matrix
-      Matrix<double> gonMat = uniGonio.getR();
+      const Matrix<double> &gonMat = uniGonio.getR();
 
       peak.setGoniometerMatrix(gonMat);
       peak.setRunNumber(run);
@@ -581,8 +576,9 @@ void LoadIsawPeaks::appendFile(PeaksWorkspace_sptr outWS,
       // Add the peak to workspace
       outWS->addPeak(peak);
     } catch (std::runtime_error &e) {
-      g_log.warning() << "Error reading peak SEQN " << seqNum << " : "
-                      << e.what() << '\n';
+      g_log.error() << "Error reading peak SEQN " << seqNum << " : " << e.what()
+                    << '\n';
+      throw std::runtime_error("Corrupted input file. ");
     }
 
     prog.report(in.tellg());
diff --git a/Framework/Crystal/src/LoadIsawUB.cpp b/Framework/Crystal/src/LoadIsawUB.cpp
index c89719269b45395c5eb78f0d14a30f30eae90987..49e754ec0fde92500122200220ca0b3de407ed4d 100644
--- a/Framework/Crystal/src/LoadIsawUB.cpp
+++ b/Framework/Crystal/src/LoadIsawUB.cpp
@@ -4,6 +4,7 @@
 #include <MantidGeometry/Crystal/OrientedLattice.h>
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/Sample.h"
+#include "MantidKernel/Strings.h"
 
 using namespace Mantid::Kernel::Strings;
 using Mantid::Kernel::DblMatrix;
diff --git a/Framework/Crystal/src/MaskPeaksWorkspace.cpp b/Framework/Crystal/src/MaskPeaksWorkspace.cpp
index 378be6b7113f2edc1b53afc1d796baaf688afb2d..18a5e7f8171133c6fe2c57defa3acec0bc0c1ab2 100644
--- a/Framework/Crystal/src/MaskPeaksWorkspace.cpp
+++ b/Framework/Crystal/src/MaskPeaksWorkspace.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidCrystal/MaskPeaksWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidAPI/InstrumentValidator.h"
@@ -9,6 +6,7 @@
 #include "MantidAPI/IPeakFunction.h"
 #include "MantidKernel/VectorHelper.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Strings.h"
 
 #include <boost/math/special_functions/round.hpp>
 
diff --git a/Framework/Crystal/src/NormaliseVanadium.cpp b/Framework/Crystal/src/NormaliseVanadium.cpp
index 26423a185c5ccc6cfb9af46a6da47282cb50f6a3..ffb43be47a99f0c6c2c7a7f966fedd5d5ebcd689 100644
--- a/Framework/Crystal/src/NormaliseVanadium.cpp
+++ b/Framework/Crystal/src/NormaliseVanadium.cpp
@@ -1,12 +1,10 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidCrystal/NormaliseVanadium.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/Fast_Exponential.h"
 #include "MantidKernel/VectorHelper.h"
diff --git a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
index e7f720798cf62d2f2b8ff271075d4a4b3523a0d9..3654f822ad27f0302641f46325f950b519344413 100644
--- a/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
+++ b/Framework/Crystal/src/OptimizeCrystalPlacement.cpp
@@ -14,6 +14,7 @@
 #include "MantidKernel/EnabledWhenProperty.h"
 #include "MantidGeometry/Crystal/IPeak.h"
 #include "MantidGeometry/Crystal/IndexingUtils.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidCrystal/PeakHKLErrors.h"
 #include "MantidCrystal/SCDCalibratePanels.h"
 
@@ -255,7 +256,7 @@ void OptimizeCrystalPlacement::exec() {
     message += "will be 'changed'";
     g_log.notice(message);
   }
-  if (OptRunNums.size() > 0 && !omitRuns)
+  if (!OptRunNums.empty() && !omitRuns)
     FuncArg += ",OptRuns=" + OptRunNums;
 
   //------------- Add initial parameter values to FuncArg -----------
diff --git a/Framework/Crystal/src/OptimizeExtinctionParameters.cpp b/Framework/Crystal/src/OptimizeExtinctionParameters.cpp
index b0c7647daf13914af0ec420c6d926562a204ca85..1ade805dbbdf5920561b6030e3dcc3b4797ab8f3 100644
--- a/Framework/Crystal/src/OptimizeExtinctionParameters.cpp
+++ b/Framework/Crystal/src/OptimizeExtinctionParameters.cpp
@@ -1,5 +1,6 @@
 #include "MantidCrystal/OptimizeExtinctionParameters.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/IPeakFunction.h"
diff --git a/Framework/Crystal/src/OptimizeLatticeForCellType.cpp b/Framework/Crystal/src/OptimizeLatticeForCellType.cpp
index a649c24ff547bcb23d98bb4804cbd017c726b2ee..0462e3b8952a1c81a6785b79ecf640e839d3043b 100644
--- a/Framework/Crystal/src/OptimizeLatticeForCellType.cpp
+++ b/Framework/Crystal/src/OptimizeLatticeForCellType.cpp
@@ -1,5 +1,6 @@
 #include "MantidCrystal/OptimizeLatticeForCellType.h"
 #include "MantidCrystal/GSLFunctions.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/IPeakFunction.h"
diff --git a/Framework/Crystal/src/PeakHKLErrors.cpp b/Framework/Crystal/src/PeakHKLErrors.cpp
index eb8f22274e23c2fe64209795ab9a30501e922ea3..73524bfd5b6f026f1bb4dee5b51a47fcdc5888a3 100644
--- a/Framework/Crystal/src/PeakHKLErrors.cpp
+++ b/Framework/Crystal/src/PeakHKLErrors.cpp
@@ -65,10 +65,10 @@ void PeakHKLErrors::setUpOptRuns() {
 
   std::vector<std::string> OptRunNums;
   std::string OptRunstemp(OptRuns);
-  if (OptRuns.size() > 0 && OptRuns.at(0) == '/')
+  if (!OptRuns.empty() && OptRuns.at(0) == '/')
     OptRunstemp = OptRunstemp.substr(1, OptRunstemp.size() - 1);
 
-  if (OptRunstemp.size() > 0 && OptRunstemp.at(OptRunstemp.size() - 1) == '/')
+  if (!OptRunstemp.empty() && OptRunstemp.at(OptRunstemp.size() - 1) == '/')
     OptRunstemp = OptRunstemp.substr(0, OptRunstemp.size() - 1);
 
   boost::split(OptRunNums, OptRunstemp, boost::is_any_of("/"));
diff --git a/Framework/Crystal/src/PeakIntensityVsRadius.cpp b/Framework/Crystal/src/PeakIntensityVsRadius.cpp
index 8e2960f5a60102c2499a04a8e0c2129c32c4320a..25841bb6b620a634e9a6d7a3f2ef849435deb2d0 100644
--- a/Framework/Crystal/src/PeakIntensityVsRadius.cpp
+++ b/Framework/Crystal/src/PeakIntensityVsRadius.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/Strings.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/Crystal/src/PeaksIntersection.cpp b/Framework/Crystal/src/PeaksIntersection.cpp
index 6051f4e2f2eb80051e983c5c6b8efed4fcb66414..d941a1e64eda259373571a837b7f489871fc51f8 100644
--- a/Framework/Crystal/src/PeaksIntersection.cpp
+++ b/Framework/Crystal/src/PeaksIntersection.cpp
@@ -5,6 +5,8 @@
 #include "MantidCrystal/PeaksIntersection.h"
 #include "MantidDataObjects/TableWorkspace.h"
 
+#include <boost/function.hpp>
+
 using namespace Mantid::API;
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
diff --git a/Framework/Crystal/src/PredictFractionalPeaks.cpp b/Framework/Crystal/src/PredictFractionalPeaks.cpp
index 86a4906756c942366c2d9c93837b1db763e7f3e1..d422382a590adff69201c6992606f3809c0b8146 100644
--- a/Framework/Crystal/src/PredictFractionalPeaks.cpp
+++ b/Framework/Crystal/src/PredictFractionalPeaks.cpp
@@ -161,7 +161,7 @@ void PredictFractionalPeaks::exec() {
     hkl[2] = peak0.getL();
   }
 
-  Kernel::DblMatrix UB = ol.getUB();
+  const Kernel::DblMatrix &UB = ol.getUB();
   vector<vector<int>> AlreadyDonePeaks;
   bool done = false;
   int ErrPos = 1; // Used to determine position in code of a throw
diff --git a/Framework/Crystal/src/PredictPeaks.cpp b/Framework/Crystal/src/PredictPeaks.cpp
index adf25dfe274df47781d4c7a767d90be9925383f2..7cc823f794cb3ecae93c4673cfa470a99bfcdc32 100644
--- a/Framework/Crystal/src/PredictPeaks.cpp
+++ b/Framework/Crystal/src/PredictPeaks.cpp
@@ -216,7 +216,7 @@ void PredictPeaks::exec() {
   const Sample &sample = inputExperimentInfo->sample();
 
   // Retrieve the OrientedLattice (UnitCell) from the workspace
-  OrientedLattice orientedLattice = sample.getOrientedLattice();
+  const OrientedLattice &orientedLattice = sample.getOrientedLattice();
 
   // Get the UB matrix from it
   Matrix<double> ub(3, 3, true);
diff --git a/Framework/Crystal/src/SCDCalibratePanels.cpp b/Framework/Crystal/src/SCDCalibratePanels.cpp
index fdab7d7c0c83754edb0596d21fb2df1e09346f79..274ba9649f71c6aa0f118bc852f4a54e252452e9 100644
--- a/Framework/Crystal/src/SCDCalibratePanels.cpp
+++ b/Framework/Crystal/src/SCDCalibratePanels.cpp
@@ -1,4 +1,5 @@
 #include "MantidCrystal/SCDCalibratePanels.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ConstraintFactory.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
@@ -368,7 +369,7 @@ void SCDCalibratePanels::exec() {
           "Workspace2D", MyBankNames.size(), nPeaks, nPeaks);
   TofWksp->setInstrument(inst);
   OrientedLattice lattice = peaksWs->mutableSample().getOrientedLattice();
-  DblMatrix UB = lattice.getUB();
+  const DblMatrix &UB = lattice.getUB();
   // sort again since edge peaks can trace to other banks
   peaksWs->sort(criteria);
   PARALLEL_FOR_IF(Kernel::threadSafe(*ColWksp, *RowWksp, *TofWksp))
diff --git a/Framework/Crystal/src/SaveHKL.cpp b/Framework/Crystal/src/SaveHKL.cpp
index 7273700621bed86560fd9e4767b60e33daaad096..04974daab13d6e092c78a7fa08388fbe24fc4bbd 100644
--- a/Framework/Crystal/src/SaveHKL.cpp
+++ b/Framework/Crystal/src/SaveHKL.cpp
@@ -6,8 +6,10 @@
 #include "MantidKernel/Utils.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/Material.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/Strings.h"
 #include "MantidCrystal/AnvredCorrection.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include <fstream>
diff --git a/Framework/Crystal/src/SaveIsawPeaks.cpp b/Framework/Crystal/src/SaveIsawPeaks.cpp
index 8c5a7d110175704cb38ebb414d377d117bd9c902..7ba77820ef5a8c35cb7603b4787d946fe5754597 100644
--- a/Framework/Crystal/src/SaveIsawPeaks.cpp
+++ b/Framework/Crystal/src/SaveIsawPeaks.cpp
@@ -4,7 +4,9 @@
 #include "MantidCrystal/SaveIsawPeaks.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/Utils.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include <fstream>
diff --git a/Framework/Crystal/src/SaveIsawUB.cpp b/Framework/Crystal/src/SaveIsawUB.cpp
index 92608c5fd002c1623f70e501f9a6f9a37cff46eb..9e13bc57b568b1a7460e5e24b43e94dbd5671d86 100644
--- a/Framework/Crystal/src/SaveIsawUB.cpp
+++ b/Framework/Crystal/src/SaveIsawUB.cpp
@@ -1,9 +1,11 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidCrystal/SaveIsawUB.h"
-#include <fstream>
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/Sample.h"
 
+#include <fstream>
+#include <iomanip>
+
 using Mantid::Kernel::DblMatrix;
 using Mantid::Geometry::UnitCell;
 using Mantid::Geometry::OrientedLattice;
diff --git a/Framework/Crystal/src/SaveLauenorm.cpp b/Framework/Crystal/src/SaveLauenorm.cpp
index 780faf5b3efc7397654ee0ef84949b65921e97e1..bb54a1cd9f371857569a662318e6676e042fca3a 100644
--- a/Framework/Crystal/src/SaveLauenorm.cpp
+++ b/Framework/Crystal/src/SaveLauenorm.cpp
@@ -7,6 +7,7 @@
 #include "MantidKernel/ListValidator.h"
 #include "MantidCrystal/AnvredCorrection.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Strings.h"
 #include <fstream>
 #include <Poco/File.h>
 #include <Poco/Path.h>
diff --git a/Framework/Crystal/src/SetGoniometer.cpp b/Framework/Crystal/src/SetGoniometer.cpp
index d08034aeb20185dc6e56a71990a0165588ec30f9..104b3192fd1d13d3d68171111cea0c760824f10f 100644
--- a/Framework/Crystal/src/SetGoniometer.cpp
+++ b/Framework/Crystal/src/SetGoniometer.cpp
@@ -1,9 +1,14 @@
 #include "MantidCrystal/SetGoniometer.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 using Mantid::Geometry::Goniometer;
 using namespace Mantid::Geometry;
 
diff --git a/Framework/Crystal/src/ShowPossibleCells.cpp b/Framework/Crystal/src/ShowPossibleCells.cpp
index 237c467f75c75b457ec0e961a42a302b6fdd185a..cd77926624a207893e675d677678bcfe6aff6327 100644
--- a/Framework/Crystal/src/ShowPossibleCells.cpp
+++ b/Framework/Crystal/src/ShowPossibleCells.cpp
@@ -51,7 +51,7 @@ void ShowPossibleCells::exec() {
   }
 
   OrientedLattice o_lattice = ws->sample().getOrientedLattice();
-  Matrix<double> UB = o_lattice.getUB();
+  const Matrix<double> &UB = o_lattice.getUB();
 
   if (!IndexingUtils::CheckUB(UB)) {
     throw std::runtime_error(
diff --git a/Framework/Crystal/src/SortHKL.cpp b/Framework/Crystal/src/SortHKL.cpp
index d02c068e22e2da46c5e212023a353c8e88c504a9..450084846821adc915a934e963639b84098ba9f5 100644
--- a/Framework/Crystal/src/SortHKL.cpp
+++ b/Framework/Crystal/src/SortHKL.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/Sample.h"
 
diff --git a/Framework/Crystal/test/AddPeakHKLTest.h b/Framework/Crystal/test/AddPeakHKLTest.h
index 2f9da672e41af04256ad13baa00e9a18fca5a6b3..fdc21c4c07d2a095e9dc0a74a74e2d5d05d16f96 100644
--- a/Framework/Crystal/test/AddPeakHKLTest.h
+++ b/Framework/Crystal/test/AddPeakHKLTest.h
@@ -9,6 +9,7 @@
 #include "MantidAPI/Sample.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
 using Mantid::Crystal::AddPeakHKL;
diff --git a/Framework/Crystal/test/CalculateUMatrixTest.h b/Framework/Crystal/test/CalculateUMatrixTest.h
index 6e6a5494ba365201065fc0181aac5ad9ba951716..60bd1aff51de6e93e31e2c0a2cab55fe76446967 100644
--- a/Framework/Crystal/test/CalculateUMatrixTest.h
+++ b/Framework/Crystal/test/CalculateUMatrixTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 
diff --git a/Framework/Crystal/test/ClearUBTest.h b/Framework/Crystal/test/ClearUBTest.h
index 1d684f54c7d316cb217502a48b559f8473b535ea..29eb8ba2e9cce7db5695348564b5880da8b38f72 100644
--- a/Framework/Crystal/test/ClearUBTest.h
+++ b/Framework/Crystal/test/ClearUBTest.h
@@ -32,7 +32,7 @@ private:
 
   // Helper method to create a matrix workspace.
   std::string createMatrixWorkspace(const bool withOrientedLattice = true) {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 2);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 2);
     if (withOrientedLattice) {
       OrientedLattice latt(1.0, 2.0, 3.0, 90, 90, 90);
       ws->mutableSample().setOrientedLattice(&latt);
diff --git a/Framework/Crystal/test/FindUBUsingFFTTest.h b/Framework/Crystal/test/FindUBUsingFFTTest.h
index 8666128f835f20a10d9dbb5832c0bc2ae9c64fe4..efa17e6c367388815c6192e6d2918ba50bd368d2 100644
--- a/Framework/Crystal/test/FindUBUsingFFTTest.h
+++ b/Framework/Crystal/test/FindUBUsingFFTTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include "MantidCrystal/FindUBUsingFFT.h"
diff --git a/Framework/Crystal/test/FindUBUsingIndexedPeaksTest.h b/Framework/Crystal/test/FindUBUsingIndexedPeaksTest.h
index f33a81dd1a80da6ddbfa55654e7a74c87ad957f8..fc60c2c910fd55e8190620d88497193a36719204 100644
--- a/Framework/Crystal/test/FindUBUsingIndexedPeaksTest.h
+++ b/Framework/Crystal/test/FindUBUsingIndexedPeaksTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include "MantidCrystal/FindUBUsingIndexedPeaks.h"
diff --git a/Framework/Crystal/test/FindUBUsingLatticeParametersTest.h b/Framework/Crystal/test/FindUBUsingLatticeParametersTest.h
index 41f4009fa0f9ebda6fba47f33cb67d2c9f464d92..55e6d2253b8cd84e4bf74afc891f6197efa4a687 100644
--- a/Framework/Crystal/test/FindUBUsingLatticeParametersTest.h
+++ b/Framework/Crystal/test/FindUBUsingLatticeParametersTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_CRYSTAL_FIND_UB_USING_LATTICE_PARAMETERS_TEST_H_
 #define MANTID_CRYSTAL_FIND_UB_USING_LATTICE_PARAMETERS_TEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 #include "MantidDataHandling/DeleteTableRows.h"
 #include "MantidKernel/System.h"
diff --git a/Framework/Crystal/test/FindUBUsingMinMaxDTest.h b/Framework/Crystal/test/FindUBUsingMinMaxDTest.h
index d39bd22926bc48d1fa9f55d00bd0250323e94aaa..c192e78b2e4666a4153991e12d91f79c731a767f 100644
--- a/Framework/Crystal/test/FindUBUsingMinMaxDTest.h
+++ b/Framework/Crystal/test/FindUBUsingMinMaxDTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include "MantidCrystal/FindUBUsingMinMaxD.h"
diff --git a/Framework/Crystal/test/HasUBTest.h b/Framework/Crystal/test/HasUBTest.h
index 1fa14900271831068d1c01a0da41df08672d63cc..20a47032e5f84c5e7e9b87a944d82c774aed2f8b 100644
--- a/Framework/Crystal/test/HasUBTest.h
+++ b/Framework/Crystal/test/HasUBTest.h
@@ -21,7 +21,7 @@ class HasUBTest : public CxxTest::TestSuite {
 private:
   // Helper method to create a matrix workspace.
   std::string createMatrixWorkspace(const bool withOrientedLattice = true) {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 2);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 2);
     if (withOrientedLattice) {
       OrientedLattice *latt = new OrientedLattice(1.0, 2.0, 3.0, 90, 90, 90);
       ws->mutableSample().setOrientedLattice(latt);
diff --git a/Framework/Crystal/test/IndexPeaksTest.h b/Framework/Crystal/test/IndexPeaksTest.h
index 2a4d066ca2d654438bdfc262222255dbff587229..8042fb3e5fa389fcfef58c9eda4ca75016ee70ab 100644
--- a/Framework/Crystal/test/IndexPeaksTest.h
+++ b/Framework/Crystal/test/IndexPeaksTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include "MantidCrystal/IndexPeaks.h"
diff --git a/Framework/Crystal/test/IndexSXPeaksTest.h b/Framework/Crystal/test/IndexSXPeaksTest.h
index 67c6ab3140efbf7eb64e89e64dc514de3a62cfa9..abf8de06f31810d58034bba9f4a6599285d309f1 100644
--- a/Framework/Crystal/test/IndexSXPeaksTest.h
+++ b/Framework/Crystal/test/IndexSXPeaksTest.h
@@ -2,6 +2,7 @@
 #define INDEX_SX_PEAKS_TEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/TableRow.h"
diff --git a/Framework/Crystal/test/LoadHKLTest.h b/Framework/Crystal/test/LoadHKLTest.h
index c3a29814ed2be30ef3b5d6edad9143e9d6ab176d..84395d8e9f99ec125bc7522def6d4f7363746590 100644
--- a/Framework/Crystal/test/LoadHKLTest.h
+++ b/Framework/Crystal/test/LoadHKLTest.h
@@ -9,6 +9,7 @@
 #include "MantidKernel/Material.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
diff --git a/Framework/Crystal/test/LoadIsawPeaksTest.h b/Framework/Crystal/test/LoadIsawPeaksTest.h
index c39a8b2bfb4fe18c1e0affa3f2e8263212336b1d..c2b48afdea497c8ddda1e8a28a1476d7c71c2447 100644
--- a/Framework/Crystal/test/LoadIsawPeaksTest.h
+++ b/Framework/Crystal/test/LoadIsawPeaksTest.h
@@ -5,6 +5,7 @@
 #include "MantidCrystal/LoadIsawPeaks.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/Matrix.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
diff --git a/Framework/Crystal/test/LoadIsawUBTest.h b/Framework/Crystal/test/LoadIsawUBTest.h
index dd991891e411921bc260cc070b14b32853e6e13f..aad1f9d4f15a96cbea4473d8a3e3a15e351a048b 100644
--- a/Framework/Crystal/test/LoadIsawUBTest.h
+++ b/Framework/Crystal/test/LoadIsawUBTest.h
@@ -30,7 +30,7 @@ public:
   void test_exec() {
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("LoadIsawUBTest_ws", ws);
 
     LoadIsawUB alg;
@@ -84,7 +84,7 @@ MaskPeaksWorkspace("TOPAZ_3007", "peaks")
    */
   void test_integration() {
     Workspace2D_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 20);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 20);
     PeaksWorkspace_sptr pw;
     AnalysisDataService::Instance().addOrReplace("TOPAZ_3007", ws);
 
@@ -94,7 +94,7 @@ MaskPeaksWorkspace("TOPAZ_3007", "peaks")
         "True");
 
     // Match the goniometer angles
-    WorkspaceCreationHelper::SetGoniometer(ws, 86.92, 135.00, -105.66);
+    WorkspaceCreationHelper::setGoniometer(ws, 86.92, 135.00, -105.66);
     // WorkspaceCreationHelper::SetGoniometer(ws, 0, 0, 0);
 
     // Load the .mat file into it
diff --git a/Framework/Crystal/test/OptimizeLatticeForCellTypeTest.h b/Framework/Crystal/test/OptimizeLatticeForCellTypeTest.h
index 252fadaa9880427a921948dee2aa73011318b674..cf4b10c0195e36e631073d20fe73ac5d435bfc1d 100644
--- a/Framework/Crystal/test/OptimizeLatticeForCellTypeTest.h
+++ b/Framework/Crystal/test/OptimizeLatticeForCellTypeTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include "MantidCrystal/OptimizeLatticeForCellType.h"
diff --git a/Framework/Crystal/test/PeakIntensityVsRadiusTest.h b/Framework/Crystal/test/PeakIntensityVsRadiusTest.h
index 8827c402542949544d3bad22c35facc724f0f0d2..9cae1b19c9f03c37dbaff81575b79e3bb4189617 100644
--- a/Framework/Crystal/test/PeakIntensityVsRadiusTest.h
+++ b/Framework/Crystal/test/PeakIntensityVsRadiusTest.h
@@ -2,6 +2,7 @@
 #define MANTID_CRYSTAL_PEAKINTENSITYVSRADIUSTEST_H_
 
 #include "MantidCrystal/PeakIntensityVsRadius.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
diff --git a/Framework/Crystal/test/PredictPeaksTest.h b/Framework/Crystal/test/PredictPeaksTest.h
index 674e924b6e402cd6ff213f8e3bc798f93ff6e1ca..4e746bbd7ebc91cd819439a75df3d5cc99f31654 100644
--- a/Framework/Crystal/test/PredictPeaksTest.h
+++ b/Framework/Crystal/test/PredictPeaksTest.h
@@ -11,6 +11,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/V3D.h"
 #include "MantidGeometry/IDTypes.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidAPI/Sample.h"
 
@@ -52,14 +53,14 @@ public:
 
     // Make the fake input workspace
     MatrixWorkspace_sptr inWS =
-        WorkspaceCreationHelper::Create2DWorkspace(10000, 1);
+        WorkspaceCreationHelper::create2DWorkspace(10000, 1);
     Instrument_sptr inst =
         ComponentCreationHelper::createTestInstrumentRectangular(1, 100);
     inWS->setInstrument(inst);
 
     // Set ub and Goniometer rotation
-    WorkspaceCreationHelper::SetOrientedLattice(inWS, 12.0, 12.0, 12.0);
-    WorkspaceCreationHelper::SetGoniometer(inWS, 0., 0., 0.);
+    WorkspaceCreationHelper::setOrientedLattice(inWS, 12.0, 12.0, 12.0);
+    WorkspaceCreationHelper::setGoniometer(inWS, 0., 0., 0.);
 
     PeaksWorkspace_sptr hklPW = getHKLpw(inst, hkls, 10000);
 
@@ -121,13 +122,13 @@ public:
 
     // Make the fake input workspace
     MatrixWorkspace_sptr inWS =
-        WorkspaceCreationHelper::Create2DWorkspace(10000, 1);
+        WorkspaceCreationHelper::create2DWorkspace(10000, 1);
     Instrument_sptr inst =
         ComponentCreationHelper::createTestInstrumentRectangular2(1, 100);
     inWS->setInstrument(inst);
 
     // Set ub and Goniometer rotation
-    WorkspaceCreationHelper::SetOrientedLattice(inWS, 10.0, 10.0, 10.0);
+    WorkspaceCreationHelper::setOrientedLattice(inWS, 10.0, 10.0, 10.0);
 
     // Make a U matrix of 22.5 degree rotation around +Y
     DblMatrix u(3, 3);
@@ -139,7 +140,7 @@ public:
 
     // Final rotation should add up to 45 degrees around +Y so that hkl 1,0,0
     // goes to +X
-    WorkspaceCreationHelper::SetGoniometer(inWS, GonioRotation, 0., 0.);
+    WorkspaceCreationHelper::setGoniometer(inWS, GonioRotation, 0., 0.);
 
     DblMatrix ub = inWS->sample().getOrientedLattice().getUB();
     PeaksWorkspace_sptr hklPW = getHKLpw(inst, {{-1, 0, 0}}, 0);
diff --git a/Framework/Crystal/test/SCDCalibratePanelsTest.h b/Framework/Crystal/test/SCDCalibratePanelsTest.h
index 627403b8803f7ea447952b238e0af56561dc47d1..ac348e0a5b840e245f8a85aa7354f45aaf5c7f21 100644
--- a/Framework/Crystal/test/SCDCalibratePanelsTest.h
+++ b/Framework/Crystal/test/SCDCalibratePanelsTest.h
@@ -9,6 +9,7 @@
 #define SCDCALIBRATEPANELSTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidCrystal/SCDCalibratePanels.h"
 
 using namespace Mantid::API;
diff --git a/Framework/Crystal/test/SaveIsawUBTest.h b/Framework/Crystal/test/SaveIsawUBTest.h
index 77b9ce5e690cf6b1e5d5e6a432459dacf592f8b3..b4917fc7d821f170da2edd0db4b49cef07f79492 100644
--- a/Framework/Crystal/test/SaveIsawUBTest.h
+++ b/Framework/Crystal/test/SaveIsawUBTest.h
@@ -43,7 +43,7 @@ public:
   void test_exec() {
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("LoadIsawUBTest_ws", ws);
 
     std::string File1, File2;
diff --git a/Framework/Crystal/test/SelectCellOfTypeTest.h b/Framework/Crystal/test/SelectCellOfTypeTest.h
index 101eb3830c21b504887690ef3333e04618bb9b4c..a89c12976b28ddc4c7bfabe043e5edd840e3058b 100644
--- a/Framework/Crystal/test/SelectCellOfTypeTest.h
+++ b/Framework/Crystal/test/SelectCellOfTypeTest.h
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Crystal/IndexingUtils.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidCrystal/LoadIsawUB.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 using namespace Mantid;
diff --git a/Framework/Crystal/test/SelectCellWithFormTest.h b/Framework/Crystal/test/SelectCellWithFormTest.h
index eb5538814cebd1b3fec7714504ea49dbe5117b48..4f684f1214744df4e520d0e23831fc3b7eed5855 100644
--- a/Framework/Crystal/test/SelectCellWithFormTest.h
+++ b/Framework/Crystal/test/SelectCellWithFormTest.h
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Crystal/IndexingUtils.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidCrystal/LoadIsawUB.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 using namespace Mantid;
diff --git a/Framework/Crystal/test/SetGoniometerTest.h b/Framework/Crystal/test/SetGoniometerTest.h
index 7380082ff01a431c1cb76887ca0fecbdb95b610f..3b0013159e81e47f2a03a25f57e8c773fa8b0ceb 100644
--- a/Framework/Crystal/test/SetGoniometerTest.h
+++ b/Framework/Crystal/test/SetGoniometerTest.h
@@ -30,7 +30,7 @@ public:
   }
 
   void test_exec_fail() {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("SetGoniometerTest_ws", ws);
 
     SetGoniometer alg;
@@ -48,7 +48,7 @@ public:
 
   /** Create an "empty" goniometer by NOT giving any axes. */
   void test_exec_emptyGoniometer() {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("SetGoniometerTest_ws", ws);
 
     SetGoniometer alg;
@@ -69,7 +69,7 @@ public:
   }
 
   void test_exec() {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("SetGoniometerTest_ws", ws);
     FrameworkManager::Instance().exec(
         "AddSampleLog", 8, "Workspace", "SetGoniometerTest_ws", "LogName",
@@ -112,7 +112,7 @@ public:
     AnalysisDataService::Instance().remove("SetGoniometerTest_ws");
   }
   void test_universal() {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("SetUnivGoniometerTest_ws",
                                                  ws);
     FrameworkManager::Instance().exec(
@@ -152,7 +152,7 @@ public:
    * @param numExpected :: how many axes should be created (0 or 1)
    */
   void do_test_param(std::string axis0, size_t numExpected = 0) {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace("SetGoniometerTest_ws", ws);
     FrameworkManager::Instance().exec(
         "AddSampleLog", 8, "Workspace", "SetGoniometerTest_ws", "LogName",
diff --git a/Framework/Crystal/test/SetUBTest.h b/Framework/Crystal/test/SetUBTest.h
index caa445891fdee1b32c1ec647d0e81920421b0b5c..7ce080fe464dd032985e8df94996f2eed3515700 100644
--- a/Framework/Crystal/test/SetUBTest.h
+++ b/Framework/Crystal/test/SetUBTest.h
@@ -39,7 +39,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
@@ -79,7 +79,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
@@ -126,7 +126,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
@@ -151,7 +151,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
@@ -173,7 +173,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
@@ -196,7 +196,7 @@ public:
     std::string wsName("SetUBTest_WS");
     // Fake output WS
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(wsName, ws);
 
     SetUB alg;
diff --git a/Framework/Crystal/test/ShowPossibleCellsTest.h b/Framework/Crystal/test/ShowPossibleCellsTest.h
index b036c34003296a5e5f086d55582a964a30375f0b..e7b519d3e023f073d9f50c7c1835efa6e655cda0 100644
--- a/Framework/Crystal/test/ShowPossibleCellsTest.h
+++ b/Framework/Crystal/test/ShowPossibleCellsTest.h
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Crystal/IndexingUtils.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidCrystal/LoadIsawUB.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 using namespace Mantid;
diff --git a/Framework/Crystal/test/SortHKLTest.h b/Framework/Crystal/test/SortHKLTest.h
index 1cd0517b08fd284a63c8a2bb4c5300885bc1980b..db8210cfd56239f17121b21a750e2e0e1903e849 100644
--- a/Framework/Crystal/test/SortHKLTest.h
+++ b/Framework/Crystal/test/SortHKLTest.h
@@ -8,6 +8,7 @@
 #include "MantidKernel/Material.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
diff --git a/Framework/Crystal/test/StatisticsOfPeaksWorkspaceTest.h b/Framework/Crystal/test/StatisticsOfPeaksWorkspaceTest.h
index e1b6b7a36fc55dbba80567e5fa6b83a39cd51a51..62516ad9472c07b69c23b3e2bf4bef5ed332113b 100644
--- a/Framework/Crystal/test/StatisticsOfPeaksWorkspaceTest.h
+++ b/Framework/Crystal/test/StatisticsOfPeaksWorkspaceTest.h
@@ -7,6 +7,7 @@
 #include "MantidGeometry/IDTypes.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
diff --git a/Framework/Crystal/test/TransformHKLTest.h b/Framework/Crystal/test/TransformHKLTest.h
index b548276707c2ad210b265fe16d863362f2ed1d41..ae5227531615359ff893ffa1e926fe2214897a35 100644
--- a/Framework/Crystal/test/TransformHKLTest.h
+++ b/Framework/Crystal/test/TransformHKLTest.h
@@ -10,6 +10,7 @@
 #include "MantidGeometry/Crystal/IndexingUtils.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidCrystal/LoadIsawUB.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 using namespace Mantid;
diff --git a/Framework/CurveFitting/CMakeLists.txt b/Framework/CurveFitting/CMakeLists.txt
index 4383241eed57bf646fa1a7265c9032d636b9eddc..f339292731db9e5bc404d026b40416f8c4812b9f 100644
--- a/Framework/CurveFitting/CMakeLists.txt
+++ b/Framework/CurveFitting/CMakeLists.txt
@@ -32,7 +32,7 @@ set ( SRC_FILES
 	src/CostFunctions/CostFuncUnweightedLeastSquares.cpp
 	src/FitMW.cpp
 	src/FuncMinimizers/BFGS_Minimizer.cpp
-	src/FuncMinimizers/DampingMinimizer.cpp
+	src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp
 	src/FuncMinimizers/DerivMinimizer.cpp
 	src/FuncMinimizers/FABADAMinimizer.cpp
 	src/FuncMinimizers/FRConjugateGradientMinimizer.cpp
@@ -78,6 +78,7 @@ set ( SRC_FILES
 	src/Functions/FlatBackground.cpp
 	src/Functions/FullprofPolynomial.cpp
 	src/Functions/FunctionGenerator.cpp
+	src/Functions/FunctionQDepends.cpp
 	src/Functions/GausDecay.cpp
 	src/Functions/GausOsc.cpp
 	src/Functions/Gaussian.cpp
@@ -185,7 +186,7 @@ set ( INC_FILES
 	inc/MantidCurveFitting/FortranMatrix.h
 	inc/MantidCurveFitting/FortranVector.h
 	inc/MantidCurveFitting/FuncMinimizers/BFGS_Minimizer.h
-	inc/MantidCurveFitting/FuncMinimizers/DampingMinimizer.h
+	inc/MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/DerivMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/FABADAMinimizer.h
 	inc/MantidCurveFitting/FuncMinimizers/FRConjugateGradientMinimizer.h
@@ -231,6 +232,7 @@ set ( INC_FILES
 	inc/MantidCurveFitting/Functions/FlatBackground.h
 	inc/MantidCurveFitting/Functions/FullprofPolynomial.h
 	inc/MantidCurveFitting/Functions/FunctionGenerator.h
+	inc/MantidCurveFitting/Functions/FunctionQDepends.h
 	inc/MantidCurveFitting/Functions/GausDecay.h
 	inc/MantidCurveFitting/Functions/GausOsc.h
 	inc/MantidCurveFitting/Functions/Gaussian.h
@@ -338,7 +340,7 @@ set ( TEST_FILES
 	FortranMatrixTest.h
 	FortranVectorTest.h
 	FuncMinimizers/BFGSTest.h
-	FuncMinimizers/DampingMinimizerTest.h
+	FuncMinimizers/DampedGaussNewtonMinimizerTest.h
 	FuncMinimizers/FABADAMinimizerTest.h
 	FuncMinimizers/FRConjugateGradientTest.h
 	FuncMinimizers/LevenbergMarquardtMDTest.h
@@ -376,6 +378,7 @@ set ( TEST_FILES
 	Functions/ExpDecayTest.h
 	Functions/FlatBackgroundTest.h
 	Functions/FullprofPolynomialTest.h
+	Functions/FunctionQDependsTest.h
 	Functions/GausDecayTest.h
 	Functions/GausOscTest.h
 	Functions/GaussianComptonProfileTest.h
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h
index f6b1113bb2ef4548523aedf26a8b3f85b228327e..0cc87ff3ac99672bab7b751d72701fe1972d3e54 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAPI/CompositeFunction.h"
 #include "MantidAPI/ITableWorkspace_fwd.h"
@@ -53,7 +54,9 @@ namespace Algorithms {
   File change history is stored at: <https://github.com/mantidproject/mantid>
   Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-class DLLExport RefinePowderInstrumentParameters : public API::Algorithm {
+class DLLExport RefinePowderInstrumentParameters
+    : public API::Algorithm,
+      public API::DeprecatedAlgorithm {
 public:
   RefinePowderInstrumentParameters();
 
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
index a26ca2df67b1d6a93d9586dc2844855296e463e0..51ed2dce5c909e38a8ad6b8c417f4e456a3a9125 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Algorithms/SplineSmoothing.h
@@ -4,6 +4,7 @@
 #include "MantidKernel/System.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidCurveFitting/Functions/BSpline.h"
 
 namespace Mantid {
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampingMinimizer.h b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h
similarity index 81%
rename from Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampingMinimizer.h
rename to Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h
index 69e54e104788355b031d262ec5ac454c86629f82..8fe6c9b9b80c9bcb16c24140d9903b6e8653300b 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampingMinimizer.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h
@@ -1,5 +1,5 @@
-#ifndef MANTID_CURVEFITTING_DAMPINGMINIMIZER_H_
-#define MANTID_CURVEFITTING_DAMPINGMINIMIZER_H_
+#ifndef MANTID_CURVEFITTING_DAMPEDGAUSSNEWTONMINIMIZER_H_
+#define MANTID_CURVEFITTING_DAMPEDGAUSSNEWTONMINIMIZER_H_
 
 //----------------------------------------------------------------------
 // Includes
@@ -16,7 +16,8 @@ class CostFuncLeastSquares;
 namespace FuncMinimisers {
 
 /**
-    Implements a least squares minimization algorithm with damping.
+    Implements a Gauss-Newton minimization algorithm with damping
+    for use with least squares cost function.
 
     @author Roman Tolchenov, Tessella plc
 
@@ -41,12 +42,12 @@ namespace FuncMinimisers {
     File change history is stored at: <https://github.com/mantidproject/mantid>.
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-class DLLExport DampingMinimizer : public API::IFuncMinimizer {
+class DLLExport DampedGaussNewtonMinimizer : public API::IFuncMinimizer {
 public:
   /// Constructor
-  DampingMinimizer(double relTol = 0.0001);
+  DampedGaussNewtonMinimizer(double relTol = 0.0001);
   /// Name of the minimizer.
-  std::string name() const override { return "DampingMinimizer"; }
+  std::string name() const override { return "DampedGaussNewtonMinimizer"; }
 
   /// Initialize minimizer, i.e. pass a function to minimize.
   void initialize(API::ICostFunction_sptr function,
@@ -68,4 +69,4 @@ private:
 } // namespace CurveFitting
 } // namespace Mantid
 
-#endif /*MANTID_CURVEFITTING_DAMPINGMINIMIZER_H_*/
+#endif /* MANTID_CURVEFITTING_DAMPEDGAUSSNEWTONMINIMIZER_H_*/
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FunctionQDepends.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FunctionQDepends.h
new file mode 100644
index 0000000000000000000000000000000000000000..d28c2701ae1005e39b5bdfd1a3731af35e124d24
--- /dev/null
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/FunctionQDepends.h
@@ -0,0 +1,81 @@
+#ifndef MANTID_CURVEFITTING_FUNCTIONQDEPENDS_H_
+#define MANTID_CURVEFITTING_FUNCTIONQDEPENDS_H_
+
+// Mantid Coding standars <http://www.mantidproject.org/Coding_Standards>
+
+// Mantid Headers from the same project
+#include "MantidAPI/IFunction.h"
+#include "MantidAPI/IFunction1D.h"
+#include "MantidAPI/ParamFunction.h"
+// Mantid headers from other projects
+// N/A
+// 3rd party library headers
+// N/A
+// Standard library
+// N/A
+
+namespace Mantid {
+namespace CurveFitting {
+namespace Functions {
+
+/** This is a specialization of IFunction1D for functions having the magnitude
+    of the momentum transfer (Q) as attribute.
+
+    Main features of this interface:
+     - Declares attributes "Q" and "WorkspaceIndex"
+     - Implements setMatrixWorkspace
+     - Extracts or compute Q values for each spectra, if possible
+
+    @author Jose Borreguero, NScD-ORNL
+    @date 12/10/2016
+
+    Copyright &copy; 2009 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 FunctionQDepends : public Mantid::API::IFunction1D,
+                                   Mantid::API::ParamFunction {
+
+public:
+  /* -------------------
+     Overridden methods
+    -------------------*/
+  virtual void declareAttributes() override;
+  virtual void
+  setAttribute(const std::string &attName,
+               const Mantid::API::IFunction::Attribute &attValue) override;
+  void setMatrixWorkspace(
+      boost::shared_ptr<const Mantid::API::MatrixWorkspace> workspace,
+      size_t wi, double startX, double endX) override;
+
+private:
+  std::vector<double>
+  extractQValues(const Mantid::API::MatrixWorkspace &workspace);
+  // list of Q values associated to the spectra
+  std::vector<double> m_vQ;
+
+}; // end of class FunctionQDepends
+
+} // namespace Functions
+} // namespace CurveFitting
+} // namespace Mantid
+
+#endif /*MANTID_CURVEFITTING_FUNCTIONQDEPENDS_H_*/
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/IkedaCarpenterPV.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/IkedaCarpenterPV.h
index ea596f6573049ae25213db7a5dfbc5218cfd5d59..ae97e2c00daac7a74cad5dfc5af2f662856e0f6b 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/IkedaCarpenterPV.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/IkedaCarpenterPV.h
@@ -54,13 +54,8 @@ public:
   std::string name() const override { return "IkedaCarpenterPV"; }
   const std::string category() const override { return "Peak"; }
 
-  // define these instead of functionLocal if you want to custom specify the
-  // calculation
-  // domain for this function
-  // virtual void function(double* out, const double* xValues, const int&
-  // nData)const;
-  // virtual void functionDeriv(API::Jacobian* out, const double* xValues, const
-  // int& nData);
+  /// Returns the integral intensity of the peak
+  double intensity() const override;
 
 protected:
   void functionLocal(double *out, const double *xValues,
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Voigt.h b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Voigt.h
index 36b14ecff7d2c7b9164599b21079dc94e83c9890..c959d433208105829fbb328988ee1ed8901e7ca4 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Voigt.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/Functions/Voigt.h
@@ -65,6 +65,10 @@ private:
   void setHeight(const double value) override;
   /// Set the FWHM of the peak
   void setFwhm(const double value) override;
+  /// Returns the integral intensity of the peak
+  double intensity() const override;
+  /// Sets the integral intensity of the peak
+  void setIntensity(const double value) override;
 };
 
 } // namespace Functions
diff --git a/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h b/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h
index 063888dce51367cd611677c822aebffb648d7887..0abe12832cbc8a9f1429ea903ceb9c6d272dd4cb 100644
--- a/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h
+++ b/Framework/CurveFitting/inc/MantidCurveFitting/IFittingAlgorithm.h
@@ -75,7 +75,7 @@ protected:
   std::vector<std::string> getCostFunctionNames() const;
   void declareCostFunctionProperty();
   boost::shared_ptr<CostFunctions::CostFuncFitting>
-  getCostFunctionProperty() const;
+  getCostFunctionInitialized() const;
 
   /// Keep the domain type
   API::IDomainCreator::DomainType m_domainType{API::IDomainCreator::Simple};
diff --git a/Framework/CurveFitting/src/Algorithms/CalculateCostFunction.cpp b/Framework/CurveFitting/src/Algorithms/CalculateCostFunction.cpp
index 30c9e6d89e7cffbe1acc776c27081a68186baa72..80f18582b398b17f9b9a98a3707f8ec75240976f 100644
--- a/Framework/CurveFitting/src/Algorithms/CalculateCostFunction.cpp
+++ b/Framework/CurveFitting/src/Algorithms/CalculateCostFunction.cpp
@@ -43,7 +43,7 @@ void CalculateCostFunction::initConcrete() {
 void CalculateCostFunction::execConcrete() {
 
   if (!m_costFunction) {
-    m_costFunction = getCostFunctionProperty();
+    m_costFunction = getCostFunctionInitialized();
   }
 
   // Get the result.
diff --git a/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp b/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp
index fe99f86d374f3b2d78dec702556751f331c83415..879188a934350402fbabd087ea7986f0dce016fa 100644
--- a/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp
+++ b/Framework/CurveFitting/src/Algorithms/ConvertToYSpace.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/Instrument.h"
@@ -196,6 +197,11 @@ void ConvertToYSpace::exec() {
   const int64_t nreports = nhist;
   auto progress = boost::make_shared<Progress>(this, 0.0, 1.0, nreports);
 
+  auto &spectrumInfo = m_outputWS->mutableSpectrumInfo();
+  SpectrumInfo *qSpectrumInfo{nullptr};
+  if (m_qOutputWS)
+    qSpectrumInfo = &m_qOutputWS->mutableSpectrumInfo();
+
   PARALLEL_FOR_IF(Kernel::threadSafe(*m_inputWS, *m_outputWS))
   for (int64_t i = 0; i < nhist; ++i) {
     PARALLEL_START_INTERUPT_REGION
@@ -203,9 +209,14 @@ void ConvertToYSpace::exec() {
     if (!convert(i)) {
       g_log.warning("No detector defined for index=" + std::to_string(i) +
                     ". Zeroing spectrum.");
-      m_outputWS->maskWorkspaceIndex(i);
-      if (m_qOutputWS)
-        m_qOutputWS->maskWorkspaceIndex(i);
+      m_outputWS->getSpectrum(i).clearData();
+      PARALLEL_CRITICAL(setMasked) {
+        spectrumInfo.setMasked(i, true);
+        if (m_qOutputWS) {
+          m_qOutputWS->getSpectrum(i).clearData();
+          qSpectrumInfo->setMasked(i, true);
+        }
+      }
     }
 
     PARALLEL_END_INTERUPT_REGION
diff --git a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
index 417f84b03b8010940ba3cbcc0682a08c401f0ef9..680aa066e296164a201a07e47cdfa715bd91bb87 100644
--- a/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
+++ b/Framework/CurveFitting/src/Algorithms/EstimateFitParameters.cpp
@@ -3,6 +3,9 @@
 #include "MantidAPI/ConstraintFactory.h"
 #include "MantidAPI/CostFunctionFactory.h"
 #include "MantidAPI/Expression.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceFactory.h"
 #include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncFitting.h"
 #include "MantidCurveFitting/Functions/ChebfunBase.h"
@@ -10,6 +13,7 @@
 #include "MantidKernel/MersenneTwister.h"
 #include "MantidKernel/NormalDistribution.h"
 
+#include <map>
 #include <numeric>
 
 namespace Mantid {
@@ -102,6 +106,39 @@ void fixBadParameters(CostFunctions::CostFuncFitting &costFunction,
   }
 }
 
+/// A class for sorting and storing sets of best function parameters.
+class BestParameters {
+  /// Maximum size of the store
+  size_t m_size;
+  /// Actual storage.
+  std::map<double, GSLVector> m_params;
+
+public:
+  /// Constructor
+  explicit BestParameters(size_t size) : m_size(size) {}
+  /// Test a cost function value if corresponding parameters must be stored.
+  bool isOneOfBest(double value) const {
+    return m_params.size() < m_size || value < m_params.rbegin()->first;
+  }
+  /// Insert a set of parameters to the store.
+  void insertParams(double value, const GSLVector &params) {
+    if (m_params.size() == m_size) {
+      auto it = m_params.find(m_params.rbegin()->first);
+      m_params.erase(it);
+    }
+    m_params[value] = params;
+  }
+  /// Return all stored parameters, drop function values.
+  std::vector<GSLVector> getParams() const {
+    std::vector<GSLVector> res;
+    res.reserve(m_params.size());
+    for (auto &it : m_params) {
+      res.push_back(it.second);
+    }
+    return res;
+  }
+};
+
 /// Run the Monte Carlo version of the algorithm.
 /// Generate random values of function parameters and return those that
 /// give the smallest cost function.
@@ -111,19 +148,22 @@ void fixBadParameters(CostFunctions::CostFuncFitting &costFunction,
 /// @param constraints :: Additional constraints.
 /// @param nSamples :: A number of samples to generate.
 /// @param seed :: A seed for the random number generator.
-void runMonteCarlo(CostFunctions::CostFuncFitting &costFunction,
-                   const std::vector<std::pair<double, double>> &ranges,
-                   const std::vector<std::unique_ptr<IConstraint>> &constraints,
-                   size_t nSamples, size_t seed) {
+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;
   if (seed != 0) {
     randGenerator.setSeed(seed);
   }
-  double bestValue = costFunction.val() + getConstraints(constraints);
+  double value = costFunction.val() + getConstraints(constraints);
   auto nParams = costFunction.nParams();
-  GSLVector bestParams;
-  costFunction.getParameters(bestParams);
+  GSLVector params;
+  costFunction.getParameters(params);
+  BestParameters bestParams(nOutput);
+  bestParams.insertParams(value, params);
 
   // Implicit cast from int to size_t
   for (size_t it = 0; it < nSamples; ++it) {
@@ -136,18 +176,20 @@ void runMonteCarlo(CostFunctions::CostFuncFitting &costFunction,
     if (getConstraints(constraints) > 0.0) {
       continue;
     }
-    auto value = costFunction.val();
+    value = costFunction.val();
     if (costFunction.nParams() != nParams) {
       throw std::runtime_error("Cost function changed number of parameters " +
                                std::to_string(nParams) + " -> " +
                                std::to_string(costFunction.nParams()));
     }
-    if (value < bestValue) {
-      bestValue = value;
-      costFunction.getParameters(bestParams);
+    if (bestParams.isOneOfBest(value)) {
+      costFunction.getParameters(params);
+      bestParams.insertParams(value, params);
     }
   }
-  costFunction.setParameters(bestParams);
+  auto outputParams = bestParams.getParams();
+  costFunction.setParameters(outputParams.front());
+  return outputParams;
 }
 /// Run the Cross Entropy version of the algorithm.
 /// https://en.wikipedia.org/wiki/Cross-entropy_method
@@ -283,6 +325,14 @@ void EstimateFitParameters::initConcrete() {
   declareProperty(
       "Type", "Monte Carlo",
       "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)");
+  declareProperty(Kernel::make_unique<WorkspaceProperty<ITableWorkspace>>(
+                      "OutputWorkspace", "", Direction::Output,
+                      Mantid::API::PropertyMode::Optional),
+                  "Optional: A table workspace with parameter sets producing "
+                  "the smallest values of cost function. (Monte Carlo only)");
   declareProperty("NIterations", 10,
                   "Number of iterations of the Cross Entropy algorithm.");
   declareProperty("Selection", 10, "Size of the selection in the Cross Entropy "
@@ -300,7 +350,7 @@ void EstimateFitParameters::initConcrete() {
 //----------------------------------------------------------------------------------------------
 /// Execute the algorithm.
 void EstimateFitParameters::execConcrete() {
-  auto costFunction = getCostFunctionProperty();
+  auto costFunction = getCostFunctionInitialized();
   auto func = costFunction->getFittingFunction();
 
   // Use additional constraints on parameters tied in some way
@@ -359,7 +409,35 @@ void EstimateFitParameters::execConcrete() {
   size_t seed = static_cast<int>(getProperty("Seed"));
 
   if (getPropertyValue("Type") == "Monte Carlo") {
-    runMonteCarlo(*costFunction, ranges, constraints, nSamples, seed);
+    int nOutput = getProperty("NOutputs");
+    auto outputWorkspaceProp = getPointerToProperty("OutputWorkspace");
+    if (outputWorkspaceProp->isDefault() || nOutput <= 0) {
+      nOutput = 1;
+    }
+    auto output = runMonteCarlo(*costFunction, ranges, constraints, nSamples,
+                                static_cast<size_t>(nOutput), seed);
+
+    if (!outputWorkspaceProp->isDefault()) {
+      auto table = API::WorkspaceFactory::Instance().createTable();
+      auto column = table->addColumn("str", "Name");
+      column->setPlotType(6);
+      for (size_t i = 0; i < output.size(); ++i) {
+        column = table->addColumn("double", std::to_string(i + 1));
+        column->setPlotType(2);
+      }
+
+      for (size_t i = 0, ia = 0; i < m_function->nParams(); ++i) {
+        if (!m_function->isFixed(i)) {
+          TableRow row = table->appendRow();
+          row << m_function->parameterName(i);
+          for (size_t j = 0; j < output.size(); ++j) {
+            row << output[j][ia];
+          }
+          ++ia;
+        }
+      }
+      setProperty("OutputWorkspace", table);
+    }
   } else {
     size_t nSelection = static_cast<int>(getProperty("Selection"));
     size_t nIterations = static_cast<int>(getProperty("NIterations"));
diff --git a/Framework/CurveFitting/src/Algorithms/EvaluateFunction.cpp b/Framework/CurveFitting/src/Algorithms/EvaluateFunction.cpp
index 92dda1a5f9b5500b68fe025749d36d0b0b5b9b7d..5905625620ca01cdd65365534e6cec46fee2fd37 100644
--- a/Framework/CurveFitting/src/Algorithms/EvaluateFunction.cpp
+++ b/Framework/CurveFitting/src/Algorithms/EvaluateFunction.cpp
@@ -1,4 +1,5 @@
 #include "MantidCurveFitting/Algorithms/EvaluateFunction.h"
+#include "MantidAPI/Workspace.h"
 
 namespace Mantid {
 namespace CurveFitting {
@@ -45,6 +46,9 @@ void EvaluateFunction::execConcrete() {
   // Do something with the function which may depend on workspace.
   m_domainCreator->initFunction(m_function);
 
+  // Apply any ties.
+  m_function->applyTies();
+
   // Calculate function values.
   m_function->function(*domain, *values);
 
diff --git a/Framework/CurveFitting/src/Algorithms/Fit.cpp b/Framework/CurveFitting/src/Algorithms/Fit.cpp
index 7805de53b27461817170dbdb1da235c2a9df8fcb..9fedae9cd1637ca5abe1c96ed6dceb6109a02feb 100644
--- a/Framework/CurveFitting/src/Algorithms/Fit.cpp
+++ b/Framework/CurveFitting/src/Algorithms/Fit.cpp
@@ -4,9 +4,7 @@
 #include "MantidCurveFitting/Algorithms/Fit.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncFitting.h"
 
-#include "MantidAPI/CostFunctionFactory.h"
 #include "MantidAPI/FuncMinimizerFactory.h"
-#include "MantidAPI/FunctionValues.h"
 #include "MantidAPI/IFuncMinimizer.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -53,11 +51,7 @@ void Fit::initConcrete() {
       boost::make_shared<Kernel::StartsWithValidator>(minimizerOptions);
 
   declareProperty("Minimizer", "Levenberg-Marquardt", minimizerValidator,
-                  "Minimizer to use for fitting. Minimizers available are "
-                  "\"Levenberg-Marquardt\", \"Simplex\", \"FABADA\", "
-                  "\"Conjugate gradient (Fletcher-Reeves imp.)\", \"Conjugate "
-                  "gradient (Polak-Ribiere imp.)\", \"BFGS\", and "
-                  "\"Levenberg-MarquardtMD\"");
+                  "Minimizer to use for fitting.");
 
   std::vector<std::string> costFuncOptions =
       API::CostFunctionFactory::Instance().getKeys();
@@ -134,32 +128,16 @@ void Fit::execConcrete() {
     m_function->addConstraints(contstraints);
   }
 
-  // prepare the function for a fit
-  m_function->setUpForFit();
+  auto costFunc = getCostFunctionInitialized();
 
-  API::FunctionDomain_sptr domain;
-  API::FunctionValues_sptr values;
-  m_domainCreator->createDomain(domain, values);
-
-  // do something with the function which may depend on workspace
-  m_domainCreator->initFunction(m_function);
+  // Try to retrieve optional properties
+  int intMaxIterations = getProperty("MaxIterations");
+  const size_t maxIterations = static_cast<size_t>(intMaxIterations);
 
   // get the minimizer
   std::string minimizerName = getPropertyValue("Minimizer");
   API::IFuncMinimizer_sptr minimizer =
       API::FuncMinimizerFactory::Instance().createMinimizer(minimizerName);
-
-  // Try to retrieve optional properties
-  int intMaxIterations = getProperty("MaxIterations");
-  const size_t maxIterations = static_cast<size_t>(intMaxIterations);
-
-  // get the cost function which must be a CostFuncFitting
-  boost::shared_ptr<CostFunctions::CostFuncFitting> costFunc =
-      boost::dynamic_pointer_cast<CostFunctions::CostFuncFitting>(
-          API::CostFunctionFactory::Instance().create(
-              getPropertyValue("CostFunction")));
-
-  costFunc->setFittingFunction(m_function, domain, values);
   minimizer->initialize(costFunc, maxIterations);
 
   const int64_t nsteps = maxIterations * m_function->estimateNoProgressCalls();
@@ -205,7 +183,7 @@ void Fit::execConcrete() {
   setPropertyValue("OutputStatus", errorString);
 
   // degrees of freedom
-  size_t dof = domain->size() - costFunc->nParams();
+  size_t dof = costFunc->getDomain()->size() - costFunc->nParams();
   if (dof == 0)
     dof = 1;
   double rawcostfuncval = minimizer->costFunctionVal();
@@ -356,8 +334,8 @@ void Fit::execConcrete() {
       }
       m_domainCreator->separateCompositeMembersInOutput(unrollComposites,
                                                         convolveMembers);
-      m_domainCreator->createOutputWorkspace(baseName, m_function, domain,
-                                             values);
+      m_domainCreator->createOutputWorkspace(
+          baseName, m_function, costFunc->getDomain(), costFunc->getValues());
     }
   }
 
diff --git a/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp b/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp
index 0d5db13d4b630f2dbc56e6fd92645c67b249479a..8caf73ba4861a83639ea45ebc0ccde45d778a4d8 100644
--- a/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp
+++ b/Framework/CurveFitting/src/Algorithms/FitPowderDiffPeaks.cpp
@@ -24,10 +24,11 @@
 #include "MantidCurveFitting/Functions/Gaussian.h"
 #include "MantidCurveFitting/Functions/BackToBackExponential.h"
 #include "MantidCurveFitting/Functions/ThermalNeutronBk2BkExpConvPVoigt.h"
-#include "MantidCurveFitting/FuncMinimizers/DampingMinimizer.h"
+#include "MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncFitting.h"
 
 #include <fstream>
+#include <iostream>
 
 #include <gsl/gsl_sf_erf.h>
 #include <cmath>
diff --git a/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp b/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp
index cfc8bfa10d65cad1aa1988a7ab81a8941e14e504..bf9914cf6e1940bcc70df53dff1ce766d4cc3afe 100644
--- a/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp
+++ b/Framework/CurveFitting/src/Algorithms/LeBailFit.cpp
@@ -15,7 +15,9 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/split.hpp>
 
+#include <cctype>
 #include <fstream>
+#include <iomanip>
 
 const int OBSDATAINDEX(0);
 const int CALDATAINDEX(1);
@@ -206,7 +208,8 @@ void LeBailFit::init() {
   setPropertySettings("Minimizer", Kernel::make_unique<VisibleWhenProperty>(
                                        "Function", IS_EQUAL_TO, "LeBailFit"));
 
-  declareProperty("Damping", 1.0, "Damping factor if minizer is 'Damping'");
+  declareProperty("Damping", 1.0,
+                  "Damping factor if minimizer is 'Damped Gauss-Newton'");
   setPropertySettings("Damping", Kernel::make_unique<VisibleWhenProperty>(
                                      "Function", IS_EQUAL_TO, "LeBailFit"));
   setPropertySettings("Damping", Kernel::make_unique<VisibleWhenProperty>(
@@ -1179,7 +1182,7 @@ void LeBailFit::parseBackgroundTableWorkspace(TableWorkspace_sptr bkgdparamws,
     // Remove extra white spaces
     boost::algorithm::trim(parname);
 
-    if (parname.size() > 0 && (parname[0] == 'A' || parname == "Bkpos")) {
+    if (!parname.empty() && (parname[0] == 'A' || parname == "Bkpos")) {
       // Insert parameter name starting with A or Bkpos (special case for
       // FullprofPolynomial)
       parmap.emplace(parname, parvalue);
diff --git a/Framework/CurveFitting/src/Algorithms/LeBailFunction.cpp b/Framework/CurveFitting/src/Algorithms/LeBailFunction.cpp
index a85af08502f8ccd97498e50cea3c1275831d541a..6c617604a56a9bdee5ed1fdc7c7a2bfe1b2a2b8e 100644
--- a/Framework/CurveFitting/src/Algorithms/LeBailFunction.cpp
+++ b/Framework/CurveFitting/src/Algorithms/LeBailFunction.cpp
@@ -106,7 +106,7 @@ LeBailFunction::function(const Mantid::HistogramData::HistogramX &xvalues,
 
   // Reset output elements to zero
   std::vector<double> out(xvalues.size(), 0);
-  auto xvals = xvalues.rawData();
+  const auto &xvals = xvalues.rawData();
 
   // Peaks
   if (calpeaks) {
@@ -799,12 +799,9 @@ void LeBailFunction::groupPeaks(
 
         if (thispeak_rightbound < rightpeak_leftbound) {
           // this peak and its right peak are well separated.
-          // finish this group by a copy
-          vector<pair<double, IPowderDiffPeakFunction_sptr>> peakgroupcopy =
-              peakgroup;
-          peakgroupvec.push_back(peakgroupcopy);
-          //  clear for the next group
-          peakgroup.clear();
+          // finish this group by swapping values
+          peakgroupvec.push_back(std::move(peakgroup));
+          peakgroup = {};
         } else {
           // this peak and its right peak are close enough to be in same group.
           // do nothing
@@ -812,9 +809,7 @@ void LeBailFunction::groupPeaks(
         }
       } else {
         // Rightmost peak.  Finish the current peak
-        vector<pair<double, IPowderDiffPeakFunction_sptr>> peakgroupcopy =
-            peakgroup;
-        peakgroupvec.push_back(peakgroupcopy);
+        peakgroupvec.push_back(peakgroup);
       }
 
       ++ipk;
@@ -827,17 +822,14 @@ void LeBailFunction::groupPeaks(
                           << "peak over at maximum TOF = " << xmax << ".\n";
 
       if (!peakgroup.empty()) {
-        vector<pair<double, IPowderDiffPeakFunction_sptr>> peakgroupcopy =
-            peakgroup;
-        peakgroupvec.push_back(peakgroupcopy);
+        peakgroupvec.push_back(peakgroup);
       }
     } // FIRST out of boundary
   }   // ENDWHILE
 
   while (ipk < m_numPeaks) {
     // Group peaks out of uppper boundary to a separate vector of peaks
-    IPowderDiffPeakFunction_sptr thispeak = m_dspPeakVec[ipk].second;
-    outboundpeakvec.push_back(thispeak);
+    outboundpeakvec.push_back(m_dspPeakVec[ipk].second);
     ipk += 1;
   }
 
diff --git a/Framework/CurveFitting/src/Algorithms/PawleyFit.cpp b/Framework/CurveFitting/src/Algorithms/PawleyFit.cpp
index 54fb86e6d95048356d177a60064fd1917535834a..1463a19cbf1a3dfd1f0798ce56261e1d116a771a 100644
--- a/Framework/CurveFitting/src/Algorithms/PawleyFit.cpp
+++ b/Framework/CurveFitting/src/Algorithms/PawleyFit.cpp
@@ -14,6 +14,10 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/UnitConversion.h"
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
+
 #include <algorithm>
 
 namespace Mantid {
diff --git a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
index 415298121a8ce27786df0925435175a46418e6e2..498e0ccbceecd5286b85d8cf611ab8f3e0165e82 100644
--- a/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
+++ b/Framework/CurveFitting/src/Algorithms/PlotPeakByLogValue.cpp
@@ -114,6 +114,14 @@ void PlotPeakByLogValue::init() {
   declareProperty("MaxIterations", 500,
                   "Stop after this number of iterations if a good fit is not "
                   "found");
+  declareProperty("PeakRadius", 0,
+                  "A value of the peak radius the peak functions should use. A "
+                  "peak radius defines an interval on the x axis around the "
+                  "centre of the peak where its values are calculated. Values "
+                  "outside the interval are not calculated and assumed zeros."
+                  "Numerically the radius is a whole number of peak widths "
+                  "(FWHM) that fit into the interval on each side from the "
+                  "centre. The default value of 0 means the whole x axis.");
 
   declareProperty("CreateOutput", false, "Set to true to create output "
                                          "workspaces with the results of the "
@@ -292,6 +300,7 @@ void PlotPeakByLogValue::exec() {
         fit->setPropertyValue("CostFunction", getPropertyValue("CostFunction"));
         fit->setPropertyValue("MaxIterations",
                               getPropertyValue("MaxIterations"));
+        fit->setPropertyValue("PeakRadius", getPropertyValue("PeakRadius"));
         fit->setProperty("CalcErrors", true);
         fit->setProperty("CreateOutput", createFitOutput);
         if (!histogramFit) {
@@ -545,7 +554,7 @@ PlotPeakByLogValue::makeNames() const {
       } else if (index.size() > 1 && index[0] == 'i') { // workspace index
         wi = boost::lexical_cast<int>(index.substr(1));
         spec = -1; // undefined yet
-      } else if (index.size() > 0 && index[0] == 'v') {
+      } else if (!index.empty() && index[0] == 'v') {
         if (index.size() > 1) { // there is some text after 'v'
           tokenizer range(index.substr(1), ":",
                           tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
@@ -636,7 +645,7 @@ std::string PlotPeakByLogValue::getMinimizerString(const std::string &wsName,
     Mantid::API::WorkspaceProperty<> *wsProp =
         dynamic_cast<Mantid::API::WorkspaceProperty<> *>(minimizerProp);
     if (wsProp) {
-      std::string wsPropValue = minimizerProp->value();
+      const std::string &wsPropValue = minimizerProp->value();
       if (wsPropValue != "") {
         std::string wsPropName = minimizerProp->name();
         m_minimizerWorkspaces[wsPropName].push_back(wsPropValue);
diff --git a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp
index 2868a4a164ea7f207b542ebef22649b8466687f2..f415e21f1114b2e7654d70ac6c80db606816ea05 100644
--- a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp
+++ b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters.cpp
@@ -27,6 +27,8 @@
 #include <boost/algorithm/string/split.hpp>
 
 #include <fstream>
+#include <iomanip>
+#include <iostream>
 
 #include <gsl/gsl_sf_erf.h>
 
@@ -52,7 +54,9 @@ DECLARE_ALGORITHM(RefinePowderInstrumentParameters)
  */
 RefinePowderInstrumentParameters::RefinePowderInstrumentParameters()
     : m_BestGSLChi2(0.0), m_MinSigma(0.0), m_MinNumFittedPeaks(0),
-      m_MaxNumberStoredParameters(0) {}
+      m_MaxNumberStoredParameters(0) {
+  this->useAlgorithm("RefinePowderInstrumentParameters", 3);
+}
 
 //----------------------------------------------------------------------------------------------
 /** Parameter declaration
diff --git a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp
index 9f1f11599a2a09003098dd110a7831f0eddc3012..69288d58376741000e9fdb7ffa317385244dc6bb 100644
--- a/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp
+++ b/Framework/CurveFitting/src/Algorithms/RefinePowderInstrumentParameters3.cpp
@@ -6,6 +6,8 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidKernel/ListValidator.h"
 
+#include <iomanip>
+
 using namespace Mantid::API;
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Functions;
@@ -86,13 +88,12 @@ void RefinePowderInstrumentParameters3::init() {
       "Algorithm to calculate the standard error of peak positions.");
 
   // Damping factor
-  declareProperty(
-      "Damping", 1.0,
-      "Damping factor for (1) minimizer 'damping'. (2) Monte Calro. ");
+  declareProperty("Damping", 1.0, "Damping factor for (1) minimizer 'Damped "
+                                  "Gauss-Newton'. (2) Monte Carlo. ");
 
   // Anealing temperature
   declareProperty("AnnealingTemperature", 1.0,
-                  "Starting aneealing temperature.");
+                  "Starting annealing temperature.");
 
   // Monte Carlo iterations
   declareProperty("MonteCarloIterations", 100,
@@ -275,7 +276,7 @@ void RefinePowderInstrumentParameters3::parseTableWorkspace(
 
     // If empty string, fit is default to be false
     bool fit = false;
-    if (fitq.size() > 0) {
+    if (!fitq.empty()) {
       if (fitq[0] == 'F' || fitq[0] == 'f')
         fit = true;
     }
diff --git a/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp b/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
index e2acc755258a63557b785a8eebf4654cb1501adf..2640d3716519783637645978f5f26786049670ba 100644
--- a/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
+++ b/Framework/CurveFitting/src/Algorithms/SplineInterpolation.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/Progress.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidCurveFitting/Algorithms/SplineInterpolation.h"
 
diff --git a/Framework/CurveFitting/src/Algorithms/SplineSmoothing.cpp b/Framework/CurveFitting/src/Algorithms/SplineSmoothing.cpp
index 92ccf5bcc43ac0779448261a6758d4fc27b6ea3f..f93d19d3f8609b79854c88d795c3cb2fcab4bd29 100644
--- a/Framework/CurveFitting/src/Algorithms/SplineSmoothing.cpp
+++ b/Framework/CurveFitting/src/Algorithms/SplineSmoothing.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/Progress.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/BoundedValidator.h"
 
 #include <algorithm>
diff --git a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
index 3749bf274f9c92e7958dcb9b987328197305a5dc..22c9e5deba499e47b056e2663cbde2cd6fbe8aa9 100644
--- a/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
+++ b/Framework/CurveFitting/src/Algorithms/VesuvioCalculateGammaBackground.cpp
@@ -17,6 +17,8 @@
 
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
+#include "MantidGeometry/Objects/Object.h"
 
 namespace Mantid {
 namespace CurveFitting {
diff --git a/Framework/CurveFitting/src/FitMW.cpp b/Framework/CurveFitting/src/FitMW.cpp
index e6476795227c74aad3531f76fbdc3f86fe5fd476..807884f4fbc7ae1e0037f897838b13237fbb7d21 100644
--- a/Framework/CurveFitting/src/FitMW.cpp
+++ b/Framework/CurveFitting/src/FitMW.cpp
@@ -187,9 +187,9 @@ void FitMW::createDomain(boost::shared_ptr<API::FunctionDomain> &domain,
     {
       if (!m_ignoreInvalidData)
         throw std::runtime_error("Infinte number or NaN found in input data.");
-      y = 0.0;                        // leaving inf or nan would break the fit
-    } else if (!std::isfinite(error)) // nan or inf error
-    {
+      y = 0.0; // leaving inf or nan would break the fit
+    } else if (!std::isfinite(error)) {
+      // nan or inf error
       if (!m_ignoreInvalidData)
         throw std::runtime_error("Infinte number or NaN found in input data.");
     } else if (error <= 0) {
@@ -197,6 +197,12 @@ void FitMW::createDomain(boost::shared_ptr<API::FunctionDomain> &domain,
         weight = 1.0;
     } else {
       weight = 1.0 / error;
+      if (!std::isfinite(weight)) {
+        if (!m_ignoreInvalidData)
+          throw std::runtime_error(
+              "Error of a data point is probably too small.");
+        weight = 0.0;
+      }
     }
 
     values->setFitData(j, y);
diff --git a/Framework/CurveFitting/src/FuncMinimizers/DampingMinimizer.cpp b/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp
similarity index 81%
rename from Framework/CurveFitting/src/FuncMinimizers/DampingMinimizer.cpp
rename to Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp
index 6120555a14a19f050fd5a2dd0cfecfacf85c5d1b..36435eeac77b0d2ffe90aeeaefa37e9dac3e1550 100644
--- a/Framework/CurveFitting/src/FuncMinimizers/DampingMinimizer.cpp
+++ b/Framework/CurveFitting/src/FuncMinimizers/DampedGaussNewtonMinimizer.cpp
@@ -1,7 +1,7 @@
 //----------------------------------------------------------------------
 // Includes
 //----------------------------------------------------------------------
-#include "MantidCurveFitting/FuncMinimizers/DampingMinimizer.h"
+#include "MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h"
 #include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
 
 #include "MantidAPI/CostFunctionFactory.h"
@@ -21,30 +21,32 @@ namespace FuncMinimisers {
 
 namespace {
 /// static logger
-Kernel::Logger g_log("DampingMinimizer");
+Kernel::Logger g_log("DampedGaussNewtonMinimizer");
 }
 
-DECLARE_FUNCMINIMIZER(DampingMinimizer, Damping)
+DECLARE_FUNCMINIMIZER(DampedGaussNewtonMinimizer, Damped GaussNewton)
 
 /// Constructor
-DampingMinimizer::DampingMinimizer(double relTol)
+DampedGaussNewtonMinimizer::DampedGaussNewtonMinimizer(double relTol)
     : IFuncMinimizer(), m_relTol(relTol) {
   declareProperty("Damping", 0.0, "The damping parameter.");
 }
 
 /// Initialize minimizer, i.e. pass a function to minimize.
-void DampingMinimizer::initialize(API::ICostFunction_sptr function, size_t) {
+void DampedGaussNewtonMinimizer::initialize(API::ICostFunction_sptr function,
+                                            size_t) {
   m_leastSquares =
       boost::dynamic_pointer_cast<CostFunctions::CostFuncLeastSquares>(
           function);
   if (!m_leastSquares) {
-    throw std::invalid_argument("Damping minimizer works only with least "
-                                "squares. Different function was given.");
+    throw std::invalid_argument(
+        "Damped Gauss-Newton minimizer works only with least "
+        "squares. Different function was given.");
   }
 }
 
 /// Do one iteration.
-bool DampingMinimizer::iterate(size_t) {
+bool DampedGaussNewtonMinimizer::iterate(size_t) {
   const bool debug = false;
 
   const double damping = getProperty("Damping");
@@ -113,7 +115,7 @@ bool DampingMinimizer::iterate(size_t) {
 }
 
 /// Return current value of the cost function
-double DampingMinimizer::costFunctionVal() {
+double DampedGaussNewtonMinimizer::costFunctionVal() {
   if (!m_leastSquares) {
     throw std::runtime_error("Cost function isn't set up.");
   }
diff --git a/Framework/CurveFitting/src/Functions/CrystalFieldSpectrum.cpp b/Framework/CurveFitting/src/Functions/CrystalFieldSpectrum.cpp
index 47a690e4bf7fd806464c70aa434d67a46b181c3c..c4ef20fd81fb0ceffc0f39770e819453b9743d2d 100644
--- a/Framework/CurveFitting/src/Functions/CrystalFieldSpectrum.cpp
+++ b/Framework/CurveFitting/src/Functions/CrystalFieldSpectrum.cpp
@@ -104,7 +104,7 @@ std::string CrystalFieldSpectrum::asString() const {
   std::vector<std::string> attr = this->getAttributeNames();
   for (const auto &attName : attr) {
     std::string attValue = this->getAttribute(attName).value();
-    if (!attValue.empty() && attValue != "\"\"") {
+    if (!attValue.empty() && attValue != "\"\"" && attValue != "()") {
       ostr << ',' << attName << '=' << attValue;
     }
   }
diff --git a/Framework/CurveFitting/src/Functions/DeltaFunction.cpp b/Framework/CurveFitting/src/Functions/DeltaFunction.cpp
index baab6b8cd5aa9b8978e41bdf41bf156fdda3a685..3640a821ff0c52f38d33fea71c0dd55fe4b80198 100644
--- a/Framework/CurveFitting/src/Functions/DeltaFunction.cpp
+++ b/Framework/CurveFitting/src/Functions/DeltaFunction.cpp
@@ -17,7 +17,7 @@ using namespace API;
 
 DECLARE_FUNCTION(DeltaFunction)
 
-DeltaFunction::DeltaFunction() {
+DeltaFunction::DeltaFunction() : IPeakFunction() {
   declareParameter("Height", 1.0,
                    "Scaling factor to be applied to the resolution.");
   declareParameter("Centre", 0.0,
diff --git a/Framework/CurveFitting/src/Functions/DynamicKuboToyabe.cpp b/Framework/CurveFitting/src/Functions/DynamicKuboToyabe.cpp
index 514424fc0f21c449a68658dc3afd1d0c201f3918..14e55390b02533f6bc422f1eb8aea58da8ef61cb 100644
--- a/Framework/CurveFitting/src/Functions/DynamicKuboToyabe.cpp
+++ b/Framework/CurveFitting/src/Functions/DynamicKuboToyabe.cpp
@@ -1,11 +1,11 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidCurveFitting/Functions/DynamicKuboToyabe.h"
 #include "MantidAPI/Jacobian.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/PhysicalConstants.h"
+
+#include <iomanip>
+#include <sstream>
 #include <vector>
 
 namespace Mantid {
diff --git a/Framework/CurveFitting/src/Functions/FunctionGenerator.cpp b/Framework/CurveFitting/src/Functions/FunctionGenerator.cpp
index 1bcb3271a7c07609e6cc3e33292258c64c3c4f75..492efacc6fbdbe91662a192ce1803f71564521c5 100644
--- a/Framework/CurveFitting/src/Functions/FunctionGenerator.cpp
+++ b/Framework/CurveFitting/src/Functions/FunctionGenerator.cpp
@@ -158,9 +158,13 @@ void FunctionGenerator::unfix(size_t i) {
 /// Return parameter index from a parameter reference.
 size_t
 FunctionGenerator::getParameterIndex(const ParameterReference &ref) const {
-  auto index = m_source->getParameterIndex(ref);
-  if (index < m_nOwnParams) {
-    return index;
+  if (ref.getFunction() == this) {
+    auto index = ref.getIndex();
+    auto np = nParams();
+    if (index < np) {
+      return index;
+    }
+    return np;
   }
   checkTargetFunction();
   return m_target->getParameterIndex(ref) + m_nOwnParams;
@@ -265,6 +269,8 @@ void FunctionGenerator::addTie(API::ParameterTie *tie) {
     m_source->addTie(tie);
   } else {
     checkTargetFunction();
+    tie->reset(m_target.get(), tie->getIndex() - m_nOwnParams,
+               tie->isDefault());
     m_target->addTie(tie);
   }
 }
diff --git a/Framework/CurveFitting/src/Functions/FunctionQDepends.cpp b/Framework/CurveFitting/src/Functions/FunctionQDepends.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..22490bfb7ed19ccba574e5fa44114baba1a51a16
--- /dev/null
+++ b/Framework/CurveFitting/src/Functions/FunctionQDepends.cpp
@@ -0,0 +1,157 @@
+// Mantid Coding standars <http://www.mantidproject.org/Coding_Standards>
+
+// Main Module Header
+#include "MantidCurveFitting/Functions/FunctionQDepends.h"
+// Mantid Headers from the same project
+// N/A
+// Mantid headers from other projects
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/NumericAxis.h"
+#include "MantidKernel/UnitConversion.h"
+#include "MantidAPI/SpectrumInfo.h"
+// third party libraries
+// N/A
+// standard library
+// N/A
+
+using Attr = Mantid::API::IFunction::Attribute;
+
+namespace {
+Mantid::Kernel::Logger g_log("FunctionQDepends");
+}
+
+namespace Mantid {
+namespace CurveFitting {
+namespace Functions {
+
+/* ===========
+   Public
+   ===========*/
+
+/**
+ * @brief declare commonattributes Q and WorkspaceIndex.
+ * Subclasses containing additional attributes should override this method by
+ * declaring the additional
+ * attributes and then calling the parent (this) method to declare Q and
+ * WorkspaceIndex.
+ */
+void FunctionQDepends::declareAttributes() {
+  this->declareAttribute("Q", Attr(EMPTY_DBL()));
+  this->declareAttribute("WorkspaceIndex", Attr(EMPTY_INT()));
+}
+
+/**
+ * @brief Update attributes WorkspaceIndex and Q according to certain precedence
+ *rules.
+ * Subclasses featuring additional attributes should override and insert a call
+ *to
+ * this method within the overriding setAttribute function.
+ * There are two ways to update Q: (i) loading the value from the spectrum, and
+ *(ii) manual
+ * input from the user. Therefore, rules of precedence must be set to prevent
+ *conflict. The
+ * priority is to accept Q from the spectrum, if a Q value can be derived from
+ *such. In
+ * this case the existing Q value will be overwritten, irrespective of the
+ *mannier in which
+ * the old Q value was set.
+ *
+ * @param attName name of the attribute
+ * @param attValue  value of the attribute
+ */
+void FunctionQDepends::setAttribute(const std::string &attName,
+                                    const Attr &attValue) {
+  // Q value is tied to WorkspaceIndex if we have a list of Q values
+  if (attName == "WorkspaceIndex") {
+    size_t wi{static_cast<size_t>(
+        attValue.asInt())}; // ah!, the "joys" of C++ strong typing.
+    if (!m_vQ.empty() && wi < m_vQ.size()) {
+      Mantid::API::IFunction::setAttribute(attName, attValue);
+      Mantid::API::IFunction::setAttribute("Q", Attribute(m_vQ.at(wi)));
+    }
+  }
+  // Q can be manually changed by user only if list of Q values is empty
+  else if (attName == "Q") {
+    if (m_vQ.empty()) {
+      Mantid::API::IFunction::setAttribute(attName, attValue);
+    }
+  } else {
+    Mantid::API::IFunction::setAttribute(attName, attValue);
+  }
+}
+
+/**
+ * @brief Learn the Q values from the workspace, if possible, and update
+ * attribute Q accordingly.
+ * @param workspace Matrix workspace
+ * @param wi selected spectrum to initialize attributes
+ * @param startX unused
+ * @param endX unused
+ */
+void FunctionQDepends::setMatrixWorkspace(
+    boost::shared_ptr<const Mantid::API::MatrixWorkspace> workspace, size_t wi,
+    double startX, double endX) {
+  UNUSED_ARG(startX);
+  UNUSED_ARG(endX);
+  // reset attributes if new workspace is passed
+  if (!m_vQ.empty()) {
+    Mantid::API::IFunction::setAttribute("WorkspaceIndex", Attr(EMPTY_INT()));
+    Mantid::API::IFunction::setAttribute("Q", Attr(EMPTY_DBL()));
+  }
+  // Obtain Q values from the passed workspace, if possible. m_vQ will be
+  // cleared if unsuccessful.
+  if (workspace) {
+    m_vQ = this->extractQValues(*workspace);
+  }
+  if (!m_vQ.empty()) {
+    this->setAttribute("WorkspaceIndex", Attr(static_cast<int>(wi)));
+  }
+}
+
+/* ===========
+   Private
+   ===========*/
+
+/**
+ * @brief Extract Q values from vertical dimension of the workspace, or compute
+ * them.
+ * @param workspace workspace possibly containing Q values.
+ */
+std::vector<double> FunctionQDepends::extractQValues(
+    const Mantid::API::MatrixWorkspace &workspace) {
+  std::vector<double> qs;
+  // Check if the vertical axis has units of momentum transfer, then extract Q
+  // values...
+  auto axis_ptr =
+      dynamic_cast<Mantid::API::NumericAxis *>(workspace.getAxis(1));
+  if (axis_ptr) {
+    const boost::shared_ptr<Kernel::Unit> &unit_ptr = axis_ptr->unit();
+    if (unit_ptr->unitID() == "MomentumTransfer") {
+      qs = axis_ptr->getValues();
+    }
+  }
+  // ...otherwise, compute the momentum transfer for each spectrum, if possible
+  else {
+    const auto &spectrumInfo = workspace.spectrumInfo();
+    size_t numHist = workspace.getNumberHistograms();
+    for (size_t wi = 0; wi < numHist; wi++) {
+      try {
+        Mantid::Geometry::IDetector_const_sptr detector;
+        detector = workspace.getDetector(wi);
+        double efixed = workspace.getEFixed(detector);
+        double usignTheta = 0.5 * spectrumInfo.twoTheta(wi);
+        double q = Mantid::Kernel::UnitConversion::run(usignTheta, efixed);
+        qs.push_back(q);
+      } catch (Kernel::Exception::NotFoundError &) {
+        g_log.debug("Cannot populate Q values from workspace");
+        qs.clear();
+        break;
+      }
+    }
+  }
+  return qs;
+}
+
+} // namespace Functions
+} // namespace CurveFitting
+} // namespace Mantid
\ No newline at end of file
diff --git a/Framework/CurveFitting/src/Functions/IkedaCarpenterPV.cpp b/Framework/CurveFitting/src/Functions/IkedaCarpenterPV.cpp
index ab44b09e234523102e4c725b4139ac73d2fd6fd0..1fce22558c9cb3fe1358d98efa37e464629891b9 100644
--- a/Framework/CurveFitting/src/Functions/IkedaCarpenterPV.cpp
+++ b/Framework/CurveFitting/src/Functions/IkedaCarpenterPV.cpp
@@ -6,6 +6,7 @@
 #include "MantidCurveFitting/SpecialFunctionSupport.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/PeakFunctionIntegrator.h"
 #include "MantidKernel/UnitFactory.h"
 #include <cmath>
 #include <gsl/gsl_math.h>
@@ -373,6 +374,21 @@ void IkedaCarpenterPV::functionDeriv(const API::FunctionDomain &domain,
   calNumericalDeriv(domain, jacobian);
 }
 
+/// Returns the integral intensity of the peak
+double IkedaCarpenterPV::intensity() const {
+  auto interval = getDomainInterval(1e-2);
+
+  API::PeakFunctionIntegrator integrator;
+  API::IntegrationResult result =
+      integrator.integrate(*this, interval.first, interval.second);
+
+  if (!result.success) {
+    return 0.0;
+  }
+
+  return result.result;
+}
+
 } // namespace Functions
 } // namespace CurveFitting
 } // namespace Mantid
diff --git a/Framework/CurveFitting/src/Functions/InelasticDiffRotDiscreteCircle.cpp b/Framework/CurveFitting/src/Functions/InelasticDiffRotDiscreteCircle.cpp
index c7e6c5c8500935852094e83056e00a126c80b9cc..3a034d38e7b7e47decc74530e3d5ebb12e51a54a 100644
--- a/Framework/CurveFitting/src/Functions/InelasticDiffRotDiscreteCircle.cpp
+++ b/Framework/CurveFitting/src/Functions/InelasticDiffRotDiscreteCircle.cpp
@@ -14,6 +14,7 @@
 // standard library headers
 #include <cmath>
 #include <limits>
+#include <sstream>
 
 using BConstraint = Mantid::CurveFitting::Constraints::BoundaryConstraint;
 
diff --git a/Framework/CurveFitting/src/Functions/PawleyFunction.cpp b/Framework/CurveFitting/src/Functions/PawleyFunction.cpp
index d6aadb2c80f820283eeee25b6d7ccc487cfc90f4..dc9c3afbaa8841f6d51e8a9393c592f11a4125df 100644
--- a/Framework/CurveFitting/src/Functions/PawleyFunction.cpp
+++ b/Framework/CurveFitting/src/Functions/PawleyFunction.cpp
@@ -6,6 +6,7 @@
 
 #include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
 
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/UnitConversion.h"
 #include "MantidKernel/UnitFactory.h"
 
diff --git a/Framework/CurveFitting/src/Functions/ProcessBackground.cpp b/Framework/CurveFitting/src/Functions/ProcessBackground.cpp
index 26f472a8e3a05dd35019170c62ef278d2b4bcb13..08545d6b91e0bf885ba1dd4cba5f4cd33ab7a69e 100644
--- a/Framework/CurveFitting/src/Functions/ProcessBackground.cpp
+++ b/Framework/CurveFitting/src/Functions/ProcessBackground.cpp
@@ -456,8 +456,7 @@ void ProcessBackground::selectBkgdPoints() {
   // explicitly
   string outbkgdparwsname =
       getPropertyValue("OutputBackgroundParameterWorkspace");
-  if (outbkgdparwsname.size() > 0 &&
-      outbkgdparwsname.compare("_dummy02") != 0) {
+  if (!outbkgdparwsname.empty() && outbkgdparwsname.compare("_dummy02") != 0) {
     // Will fit the selected background
     string bkgdfunctype = getPropertyValue("OutputBackgroundType");
     fitBackgroundFunction(bkgdfunctype);
@@ -692,7 +691,7 @@ ProcessBackground::filterForBackground(BackgroundFunction_sptr bkgdfunction) {
 
   // Optional output
   string userbkgdwsname = getPropertyValue("UserBackgroundWorkspace");
-  if (userbkgdwsname.size() == 0)
+  if (userbkgdwsname.empty())
     throw runtime_error("In mode SelectBackgroundPoints, "
                         "UserBackgroundWorkspace must be given!");
 
diff --git a/Framework/CurveFitting/src/Functions/Voigt.cpp b/Framework/CurveFitting/src/Functions/Voigt.cpp
index 3228667bdc3e9c67644d05855aec7d74830b4185..5f2cfb84f84d0aa1ef6e65baaa6ee38d75f992ed 100644
--- a/Framework/CurveFitting/src/Functions/Voigt.cpp
+++ b/Framework/CurveFitting/src/Functions/Voigt.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/FunctionFactory.h"
 
 #include <cmath>
+#include <limits>
 
 namespace Mantid {
 namespace CurveFitting {
@@ -132,7 +133,16 @@ double Voigt::centre() const { return getParameter(LORENTZ_POS); }
  * Return the value of the "LorentzAmp" parameter
  * @return value of height of peak
  */
-double Voigt::height() const { return 2.0 * getParameter(LORENTZ_AMP) / 3.0; }
+double Voigt::height() const {
+  if (getParameter(LORENTZ_AMP) == 0.0 || getParameter(LORENTZ_FWHM) == 0.0 ||
+      getParameter(GAUSSIAN_FWHM) == 0.0) {
+    return 0.0;
+  }
+  double pos = getParameter(LORENTZ_POS);
+  double h;
+  functionLocal(&h, &pos, 1);
+  return h;
+}
 
 /**
  * Gives the FWHM of the peak. This is estimated as
@@ -156,7 +166,22 @@ void Voigt::setCentre(const double value) {
  * @param value :: The new value for the centre of the peak
  */
 void Voigt::setHeight(const double value) {
-  this->setParameter(LORENTZ_AMP, 1.5 * value);
+  auto lorentzFwhm = getParameter(LORENTZ_FWHM);
+  if (lorentzFwhm == 0.0) {
+    lorentzFwhm = std::numeric_limits<double>::epsilon();
+    setParameter(LORENTZ_FWHM, lorentzFwhm);
+  }
+  auto lorentzAmp = getParameter(LORENTZ_AMP);
+  if (lorentzAmp == 0.0) {
+    lorentzAmp = std::numeric_limits<double>::epsilon();
+    setParameter(LORENTZ_AMP, lorentzAmp);
+  }
+  auto gaussFwhm = getParameter(GAUSSIAN_FWHM);
+  if (gaussFwhm == 0.0) {
+    setParameter(GAUSSIAN_FWHM, std::numeric_limits<double>::epsilon());
+  }
+  auto h = height();
+  this->setParameter(LORENTZ_AMP, lorentzAmp * value / h);
 }
 
 /**
@@ -164,8 +189,44 @@ void Voigt::setHeight(const double value) {
  * @param value :: The new value for the FWHM of the peak
  */
 void Voigt::setFwhm(const double value) {
-  this->setParameter(LORENTZ_FWHM, 0.5 * value);
-  this->setParameter(GAUSSIAN_FWHM, 0.5 * value);
+  auto lorentzFwhm = getParameter(LORENTZ_FWHM);
+  if (lorentzFwhm == 0.0) {
+    lorentzFwhm = std::numeric_limits<double>::epsilon();
+  }
+  auto gaussFwhm = getParameter(GAUSSIAN_FWHM);
+  if (gaussFwhm == 0.0) {
+    gaussFwhm = std::numeric_limits<double>::epsilon();
+  }
+  auto ratio = lorentzFwhm / (lorentzFwhm + gaussFwhm);
+  this->setParameter(LORENTZ_FWHM, ratio * value);
+  this->setParameter(GAUSSIAN_FWHM, (1.0 - ratio) * value);
+}
+
+/**
+ * Returns the integral intensity of the peak
+ */
+double Voigt::intensity() const {
+  if (getParameter(GAUSSIAN_FWHM) == 0.0) {
+    return 0.0;
+  }
+  return M_PI * getParameter(LORENTZ_AMP) * getParameter(LORENTZ_FWHM) / 2.0;
+}
+
+/**
+ * Sets the integral intensity of the peak
+ * @param value :: The new value for the intensity.
+ */
+void Voigt::setIntensity(const double value) {
+  auto lorentzFWHM = getParameter(LORENTZ_FWHM);
+  if (lorentzFWHM == 0.0) {
+    lorentzFWHM = std::numeric_limits<double>::epsilon();
+    setParameter(LORENTZ_FWHM, lorentzFWHM);
+  }
+  auto gaussFwhm = getParameter(GAUSSIAN_FWHM);
+  if (gaussFwhm == 0.0) {
+    setParameter(GAUSSIAN_FWHM, std::numeric_limits<double>::epsilon());
+  }
+  setParameter(LORENTZ_AMP, 2.0 * value / (M_PI * lorentzFWHM));
 }
 
 } // namespace Functions
diff --git a/Framework/CurveFitting/src/IFittingAlgorithm.cpp b/Framework/CurveFitting/src/IFittingAlgorithm.cpp
index 60190da0a709a8bd1ba4e02cc30b9f6813c024c8..c228967f6ff1402b4bb75d0fa7d7aedae21eb9ca 100644
--- a/Framework/CurveFitting/src/IFittingAlgorithm.cpp
+++ b/Framework/CurveFitting/src/IFittingAlgorithm.cpp
@@ -93,6 +93,14 @@ void IFittingAlgorithm::init() {
                   "centre of each bin. If it is \"Histogram\" then function is "
                   "integrated within the bin and the integrals returned.",
                   Kernel::Direction::Input);
+  declareProperty("PeakRadius", 0,
+                  "A value of the peak radius the peak functions should use. A "
+                  "peak radius defines an interval on the x axis around the "
+                  "centre of the peak where its values are calculated. Values "
+                  "outside the interval are not calculated and assumed zeros."
+                  "Numerically the radius is a whole number of peak widths "
+                  "(FWHM) that fit into the interval on each side from the "
+                  "centre. The default value of 0 means the whole x axis.");
 
   initConcrete();
 }
@@ -290,9 +298,10 @@ void IFittingAlgorithm::declareCostFunctionProperty() {
       Kernel::Direction::InOut);
 }
 
-/// Create a cost function from the "CostFunction" property.
+/// Create a cost function from the "CostFunction" property
+/// and make it ready for evaluation.
 boost::shared_ptr<CostFunctions::CostFuncFitting>
-IFittingAlgorithm::getCostFunctionProperty() const {
+IFittingAlgorithm::getCostFunctionInitialized() const {
   // Function may need some preparation.
   m_function->setUpForFit();
 
@@ -300,6 +309,15 @@ IFittingAlgorithm::getCostFunctionProperty() const {
   API::FunctionValues_sptr values;
   m_domainCreator->createDomain(domain, values);
 
+  // Set peak radius to the values which will be passed to
+  // all IPeakFunctions
+  int peakRadius = getProperty("PeakRadius");
+  if (auto d1d = dynamic_cast<API::FunctionDomain1D *>(domain.get())) {
+    if (peakRadius != 0) {
+      d1d->setPeakRadius(peakRadius);
+    }
+  }
+
   // Do something with the function which may depend on workspace.
   m_domainCreator->initFunction(m_function);
 
diff --git a/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp b/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
index af4421e5631b2a27577971f8d1cb2281f4f8f9c5..8b42f51d7bf34b3668b6b8845fcadd2c33d93a62 100644
--- a/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
+++ b/Framework/CurveFitting/src/SeqDomainSpectrumCreator.cpp
@@ -3,6 +3,7 @@
 #include "MantidCurveFitting/Jacobian.h"
 #include "MantidCurveFitting/SeqDomain.h"
 #include "MantidAPI/IEventWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/Workspace.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidAPI/WorkspaceProperty.h"
@@ -218,17 +219,12 @@ bool SeqDomainSpectrumCreator::histogramIsUsable(size_t i) const {
     throw std::invalid_argument("No matrix workspace assigned.");
   }
 
-  try {
-    Geometry::IDetector_const_sptr detector = m_matrixWorkspace->getDetector(i);
+  const auto &spectrumInfo = m_matrixWorkspace->spectrumInfo();
 
-    if (!detector) {
-      return true;
-    }
-
-    return !detector->isMasked();
-  } catch (const Kernel::Exception::NotFoundError &) {
+  if (!spectrumInfo.hasDetectors(i)) {
     return true;
   }
+  return !spectrumInfo.isMasked(i);
 }
 
 } // namespace CurveFitting
diff --git a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
index 718c447c1ee2dfcc556b95d53dcd4edf813dc558..768635bc158d94029799ec024a8471fd2797b9db 100644
--- a/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
+++ b/Framework/CurveFitting/test/Algorithms/CalculateChiSquaredTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Algorithms/CalculateChiSquared.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Column.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionFactory.h"
diff --git a/Framework/CurveFitting/test/Algorithms/CalculateCostFunctionTest.h b/Framework/CurveFitting/test/Algorithms/CalculateCostFunctionTest.h
index da8e084e2f6bb3ac64672eac4b74168308d3891e..c7140f747032d46a8faba68d49db6b6fdf4f672b 100644
--- a/Framework/CurveFitting/test/Algorithms/CalculateCostFunctionTest.h
+++ b/Framework/CurveFitting/test/Algorithms/CalculateCostFunctionTest.h
@@ -32,7 +32,7 @@ public:
   void test_calculate() {
     CalculateCostFunction alg;
     alg.initialize();
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double, int) { return 0.0; }, 1, 0.0, 1.0, 0.1);
     alg.setPropertyValue("Function", "name=UserFunction,Formula=a*x,a=1");
     alg.setProperty("InputWorkspace", ws);
@@ -47,7 +47,7 @@ public:
   void test_calculate_weighted() {
     CalculateCostFunction alg;
     alg.initialize();
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double, int) { return 0.0; }, 1, 0.0, 1.0, 0.1);
     double w = 0.0;
     std::generate(ws->dataE(0).begin(), ws->dataE(0).end(), [&w] {
@@ -71,7 +71,7 @@ public:
   void test_calculate_weighted_unweighted() {
     CalculateCostFunction alg;
     alg.initialize();
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double, int) { return 1.0; }, 1, 0.0, 1.0, 0.1);
     double w = 0.0;
     std::generate(ws->dataE(0).begin(), ws->dataE(0).end(), [&w] {
diff --git a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
index 3dbfccc88a5773ca386155d141e64cfb905dca0a..98b982cf3774a54de6aa4feb0305356a7d84874b 100644
--- a/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
+++ b/Framework/CurveFitting/test/Algorithms/ConvertToYSpaceTest.h
@@ -104,7 +104,7 @@ public:
 
   void test_Input_Workspace_Not_In_TOF_Throws_Error() {
     auto alg = createAlgorithm();
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace123(1, 10);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace123(1, 10);
     testWS->getAxis(0)->setUnit("Wavelength");
 
     TS_ASSERT_THROWS(alg->setProperty("InputWorkspace", testWS),
@@ -113,7 +113,7 @@ public:
 
   void test_Input_Workspace_In_TOF_Without_Instrument_Throws_Error() {
     auto alg = createAlgorithm();
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace123(1, 10);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace123(1, 10);
     testWS->getAxis(0)->setUnit("TOF");
 
     TS_ASSERT_THROWS(alg->setProperty("InputWorkspace", testWS),
diff --git a/Framework/CurveFitting/test/Algorithms/ConvolveWorkspacesTest.h b/Framework/CurveFitting/test/Algorithms/ConvolveWorkspacesTest.h
index 9343daa70f29d0ea1604572c77a4cc0ff407f154..d273fe70a65d08a319c5dc5e14db2b6b034c1bc1 100644
--- a/Framework/CurveFitting/test/Algorithms/ConvolveWorkspacesTest.h
+++ b/Framework/CurveFitting/test/Algorithms/ConvolveWorkspacesTest.h
@@ -48,10 +48,10 @@ public:
     // Convolution of normalized Gaussians should have sigma =
     // sqrt(sig1^2+sig2^2)
     Workspace2D_sptr ws1 =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             NormGaussianFunc1(), 1, -2.0, 2.0, 0.01, false);
     Workspace2D_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             NormGaussianFunc2(), 1, -2.0, 2.0, 0.01, false);
     TS_ASSERT_THROWS_NOTHING(
         AnalysisDataService::Instance().addOrReplace("wksp1", ws1));
@@ -101,9 +101,9 @@ public:
   ConvolveWorkspacesTestPerformance() { FrameworkManager::Instance(); }
 
   void setUp() override {
-    ws1 = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    ws1 = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         NormGaussianFunc1(), 1000, -5.0, 5.0, 0.005, false);
-    ws2 = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    ws2 = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         NormGaussianFunc2(), 1000, -5.0, 5.0, 0.005, false);
     AnalysisDataService::Instance().addOrReplace("wksp1", ws1);
     AnalysisDataService::Instance().addOrReplace("wksp2", ws2);
diff --git a/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h b/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
index f7beda3d9b750d4d12e4d367684650ef08d11899..0e25179a7808241e5b7a39bfd6c1fd55190e61ca 100644
--- a/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
+++ b/Framework/CurveFitting/test/Algorithms/EstimateFitParametersTest.h
@@ -33,7 +33,7 @@ public:
   }
 
   void test_no_constraints() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double, int) { return 0.0; }, 1, 0, 1, 0.1);
 
     EstimateFitParameters alg;
@@ -46,7 +46,7 @@ public:
   }
 
   void test_no_lower_bound() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
 
     EstimateFitParameters alg;
@@ -59,7 +59,7 @@ public:
   }
 
   void test_no_upper_bound() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
 
     EstimateFitParameters alg;
@@ -72,7 +72,7 @@ public:
   }
 
   void test_all_free() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
 
     std::string funStr(
@@ -103,7 +103,7 @@ public:
   }
 
   void test_fixed() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
 
     std::string funStr(
@@ -133,7 +133,7 @@ public:
   }
 
   void test_tied() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
 
     std::string funStr(
@@ -167,7 +167,7 @@ public:
   }
 
   void test_fix_bad_parameters() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return exp(-x * x / 4.0); }, 1, -8.5, 8.5, 1.0);
 
     std::string funStr("name=BackToBackExponential,S=1.1,constraints=(0.01<I<"
@@ -203,7 +203,7 @@ public:
   }
 
   void test_fix_bad_parameters_doesnt_change_values() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         [](double x, int) { return exp(-x * x / 4.0); }, 1, -8.5, 8.5, 1.0);
 
     std::string funStr("name=BackToBackExponential,S=1.1,constraints=(0.01<I<"
@@ -237,6 +237,47 @@ public:
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("I")));
     TS_ASSERT(!fun->isFixed(fun->parameterIndex("S")));
   }
+
+  void test_output() {
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
+        [](double x, int) { return 2.0 + 3.0 * x; }, 1, 0, 1, 0.1);
+
+    std::string funStr(
+        "name=UserFunction,Formula=a*x+b,a=0,b=0,constraints=(1<a<4, 0<b<4)");
+    EstimateFitParameters alg;
+    alg.initialize();
+    alg.setRethrows(true);
+    alg.setPropertyValue("Function", funStr);
+    alg.setProperty("InputWorkspace", ws);
+    alg.setProperty("OutputWorkspace", "out");
+    alg.execute();
+    IFunction_sptr fun = alg.getProperty("Function");
+    auto params =
+        AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("out");
+    TS_ASSERT(params);
+    TS_ASSERT_EQUALS(params->rowCount(), 2);
+    TS_ASSERT_EQUALS(params->columnCount(), 11);
+
+    double costValue = 0.0;
+    auto names = params->getColumn(0);
+    for (size_t col = 1; col < params->columnCount(); ++col) {
+      auto column = params->getColumn(col);
+      for (size_t row = 0; row < column->size(); ++row) {
+        fun->setParameter(names->cell<std::string>(row),
+                          column->cell<double>(row));
+      }
+      CalculateCostFunction calc;
+      calc.initialize();
+      calc.setProperty("Function", fun);
+      calc.setProperty("InputWorkspace", ws);
+      calc.execute();
+      double value = calc.getProperty("Value");
+      TSM_ASSERT_LESS_THAN(
+          "Parameter sets aren't sorted by cost function value.", costValue,
+          value);
+    }
+    AnalysisDataService::Instance().clear();
+  }
 };
 
 #endif /* MANTID_CURVEFITTING_ESTIMATEFITPARAMETERSTEST_H_ */
diff --git a/Framework/CurveFitting/test/Algorithms/EstimatePeakErrorsTest.h b/Framework/CurveFitting/test/Algorithms/EstimatePeakErrorsTest.h
index b38019f242745343b5e6af70aec35363dce7f015..17ebd69ae348f7b4bf9ca060eff278228895bdf7 100644
--- a/Framework/CurveFitting/test/Algorithms/EstimatePeakErrorsTest.h
+++ b/Framework/CurveFitting/test/Algorithms/EstimatePeakErrorsTest.h
@@ -148,14 +148,14 @@ public:
     TS_ASSERT_EQUALS(res->cell<std::string>(3, 0), "f0.Intensity");
 
     TS_ASSERT_DELTA(res->cell<double>(0, 1), -3.9865, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(1, 1), 3.1881, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(2, 1), 2.0011, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(3, 1), 10.0218, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(1, 1), 3.1883, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(2, 1), 2.0007, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(3, 1), 10.0200, 1e-4);
 
     TS_ASSERT_DELTA(res->cell<double>(0, 2), 0.1764, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(1, 2), 0.5690, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(2, 2), 0.5968, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(3, 2), 2.6126, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(1, 2), 0.5684, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(2, 2), 0.6063, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(3, 2), 2.6687, 1e-4);
 
     TS_ASSERT_EQUALS(res->cell<std::string>(4, 0), "f1.Centre");
     TS_ASSERT_EQUALS(res->cell<std::string>(5, 0), "f1.Height");
@@ -165,12 +165,12 @@ public:
     TS_ASSERT_DELTA(res->cell<double>(4, 1), 3.0064, 1e-4);
     TS_ASSERT_DELTA(res->cell<double>(5, 1), 2.1327, 1e-4);
     TS_ASSERT_DELTA(res->cell<double>(6, 1), 2.9908, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(7, 1), 10.0196, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(7, 1), 10.0188, 1e-4);
 
-    TS_ASSERT_DELTA(res->cell<double>(4, 2), 0.3234, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(5, 2), 0.4756, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(6, 2), 1.2002, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(7, 2), 3.7937, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(4, 2), 0.3232, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(5, 2), 0.4771, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(6, 2), 1.2008, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(7, 2), 3.8074, 1e-4);
 
     AnalysisDataService::Instance().clear();
   }
@@ -206,13 +206,13 @@ public:
 
     TS_ASSERT_DELTA(res->cell<double>(0, 1), -4.0000, 1e-4);
     TS_ASSERT_DELTA(res->cell<double>(1, 1), 3.1878, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(2, 1), 2.0012, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(3, 1), 10.0207, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(2, 1), 2.0006, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(3, 1), 10.0181, 1e-4);
 
     TS_ASSERT_DELTA(res->cell<double>(0, 2), 0.0000, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(1, 2), 0.5609, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(2, 2), 0.5797, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(3, 2), 2.4090, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(1, 2), 0.5605, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(2, 2), 0.5872, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(3, 2), 2.4510, 1e-4);
 
     TS_ASSERT_EQUALS(res->cell<std::string>(4, 0), "f1.Centre");
     TS_ASSERT_EQUALS(res->cell<std::string>(5, 0), "f1.Height");
@@ -221,12 +221,12 @@ public:
 
     TS_ASSERT_DELTA(res->cell<double>(4, 1), 3.0056, 1e-4);
     TS_ASSERT_DELTA(res->cell<double>(5, 1), 2.1320, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(6, 1), 2.9921, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(7, 1), 10.0207, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(6, 1), 2.9915, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(7, 1), 10.0181, 1e-4);
 
-    TS_ASSERT_DELTA(res->cell<double>(4, 2), 0.3231, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(5, 2), 0.4668, 1e-4);
-    TS_ASSERT_DELTA(res->cell<double>(6, 2), 0.6551, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(4, 2), 0.3229, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(5, 2), 0.4677, 1e-4);
+    TS_ASSERT_DELTA(res->cell<double>(6, 2), 0.6563, 1e-4);
     TS_ASSERT_DELTA(res->cell<double>(7, 2), 0.0000, 1e-4);
 
     AnalysisDataService::Instance().clear();
diff --git a/Framework/CurveFitting/test/Algorithms/FitPowderDiffPeaksTest.h b/Framework/CurveFitting/test/Algorithms/FitPowderDiffPeaksTest.h
index 8457ed5ae95ef5a3979dd35affcc7768ecb6de92..21e2c9763d76114ebadd9fb8967afbb934f03e06 100644
--- a/Framework/CurveFitting/test/Algorithms/FitPowderDiffPeaksTest.h
+++ b/Framework/CurveFitting/test/Algorithms/FitPowderDiffPeaksTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidCurveFitting/Algorithms/FitPowderDiffPeaks.h"
 #include "MantidDataHandling/LoadAscii.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
diff --git a/Framework/CurveFitting/test/Algorithms/FitTest.h b/Framework/CurveFitting/test/Algorithms/FitTest.h
index 30950a9230a87544ea2030fd0737ec6642dd7180..822660ba5bdf26cf9f240a060b3bd20c0f966387 100644
--- a/Framework/CurveFitting/test/Algorithms/FitTest.h
+++ b/Framework/CurveFitting/test/Algorithms/FitTest.h
@@ -23,6 +23,7 @@
 #include <Poco/File.h>
 
 using namespace Mantid;
+using namespace Mantid::Kernel;
 using namespace Mantid::API;
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Algorithms;
@@ -830,24 +831,40 @@ public:
     auto &y = data->dataY(0);
     auto &e = data->dataE(0);
 
-    y = {0, -1.77636e-16, -1.77636e-16, 0, -1.77636e-16, -8.88178e-17,
-         -1.33227e-16, 0, 0, 8.88178e-17, 3.33067e-17, 1.11022e-17, 1.27676e-16,
-         6.66134e-17, 8.32667e-17, 3.88578e-17, 9.4369e-17, 1.44329e-16,
-         2.66454e-16, 5.10703e-15, 9.80105e-14, 1.63027e-12, 2.31485e-11,
-         2.80779e-10, 2.91067e-09, 2.58027e-08, 1.9575e-07, 1.27204e-06,
-         7.08849e-06, 3.39231e-05, 0.000139678, 0.000496012, 0.00152387,
-         0.0040672, 0.00948273, 0.0194574, 0.0354878, 0.0583005, 0.0877657,
-         0.123662, 0.167048, 0.221547, 0.293962, 0.393859, 0.531629, 0.714256,
-         0.938713, 1.18531, 1.41603, 1.58257, 1.64355, 1.58257, 1.41603,
-         1.18531, 0.938713, 0.714256, 0.531629, 0.393859, 0.293962, 0.221547,
-         0.167048, 0.123662, 0.0877657, 0.0583005, 0.0354878, 0.0194574,
-         0.00948273, 0.0040672, 0.00152387, 0.000496012, 0.000139678,
-         3.39231e-05, 7.08849e-06, 1.27204e-06, 1.9575e-07, 2.58027e-08,
-         2.91067e-09, 2.80779e-10, 2.31486e-11, 1.63033e-12, 9.80771e-14,
-         5.09592e-15, 2.77556e-16, 3.88578e-17, 2.22045e-17, -1.66533e-17,
-         -1.11022e-17, 0, -7.21645e-17, -8.88178e-17, -1.11022e-16,
-         -1.33227e-16, -4.44089e-17, -1.77636e-16, -1.33227e-16, -8.88178e-17,
-         -3.55271e-16, -8.88178e-17, -1.77636e-16, -1.77636e-16};
+    y = {0.00679397551246448, 0.00684266083126313, 0.00698285916556982,
+         0.00719965548825388, 0.00747519954546736, 0.00779445649068509,
+         0.00814796531751759, 0.0085316132498512,  0.00894499942724,
+         0.00938983058044737, 0.0098689280357672,  0.0103857911674609,
+         0.0109444805899566,  0.0115496436468315,  0.0122065986210473,
+         0.0129214505517302,  0.0137012349575442,  0.0145540939647495,
+         0.0154894928726603,  0.0165184880798197,  0.0176540608380039,
+         0.01891153608981,    0.0203091122610038,  0.021868537134057,
+         0.0236159780401305,  0.0255831534292171,  0.0278088202944704,
+         0.0303407524938984,  0.0332384060776671,  0.0365765613911014,
+         0.0404503783689891,  0.0449825362752094,  0.0503335145708212,
+         0.0567167210280417,  0.0644212970503862,  0.0738474209204705,
+         0.085562497139828,   0.10039290319273,    0.119576178650528,
+         0.145011665152563,   0.17965292804199,    0.228047317644744,
+         0.296874083423821,   0.394987350612542,   0.532006328704948,
+         0.714364415633021,   0.938739703160756,   1.18531948194073,
+         1.41603503739802,    1.58257225395956,    1.64354644127685,
+         1.58257225395956,    1.41603503739802,    1.18531948194073,
+         0.938739703160756,   0.714364415633021,   0.532006328704948,
+         0.394987350612542,   0.296874083423821,   0.228047317644743,
+         0.17965292804199,    0.145011665152563,   0.119576178650528,
+         0.10039290319273,    0.085562497139828,   0.0738474209204706,
+         0.0644212970503863,  0.0567167210280418,  0.0503335145708214,
+         0.0449825362752095,  0.0404503783689893,  0.0365765613911016,
+         0.0332384060776675,  0.0303407524938988,  0.0278088202944705,
+         0.0255831534292172,  0.0236159780401305,  0.0218685371340571,
+         0.0203091122610038,  0.0189115360898101,  0.0176540608380039,
+         0.0165184880798196,  0.0154894928726603,  0.0145540939647495,
+         0.0137012349575443,  0.0129214505517302,  0.0122065986210471,
+         0.0115496436468314,  0.0109444805899566,  0.0103857911674609,
+         0.00986892803576708, 0.00938983058044717, 0.00894499942723977,
+         0.00853161324985108, 0.0081479653175175,  0.00779445649068496,
+         0.00747519954546727, 0.00719965548825406, 0.00698285916556974,
+         0.00684266083126313};
 
     x = {-10,  -9.8, -9.6, -9.4, -9.2, -9,   -8.8, -8.6, -8.4, -8.2, -8,   -7.8,
          -7.6, -7.4, -7.2, -7,   -6.8, -6.6, -6.4, -6.2, -6,   -5.8, -5.6, -5.4,
@@ -1969,6 +1986,49 @@ public:
     TS_ASSERT_DELTA(out->getParameter("A2"), 1.0, 0.0001);
   }
 
+  void test_PeakRadius() {
+    size_t nbins = 100;
+    auto ws =
+        WorkspaceFactory::Instance().create("Workspace2D", 1, nbins, nbins);
+    FunctionDomain1DVector x(-10, 10, nbins);
+    ws->dataX(0) = x.toVector();
+    {
+      Fit fit;
+      fit.initialize();
+      fit.setProperty("Function", "name=Lorentzian,Amplitude=5,FWHM=1");
+      fit.setProperty("InputWorkspace", ws);
+      fit.setProperty("MaxIterations", 0);
+      fit.setProperty("Output", "out");
+      fit.execute();
+      auto res = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
+          "out_Workspace");
+      auto y = res->y(1);
+      TS_ASSERT_DIFFERS(y.front(), 0.0);
+      TS_ASSERT_DIFFERS(y.back(), 0.0);
+    }
+    {
+      Fit fit;
+      fit.initialize();
+      fit.setProperty("Function", "name=Lorentzian,Amplitude=5,FWHM=1");
+      fit.setProperty("InputWorkspace", ws);
+      fit.setProperty("PeakRadius", 5);
+      fit.setProperty("MaxIterations", 0);
+      fit.setProperty("Output", "out");
+      fit.execute();
+      auto res = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
+          "out_Workspace");
+      auto y = res->y(1);
+      for (size_t i = 0; i < 25; ++i) {
+        TS_ASSERT_EQUALS(y[i], 0.0);
+        TS_ASSERT_EQUALS(y[nbins - i - 1], 0.0);
+      }
+      TS_ASSERT_DIFFERS(y[26], 0.0);
+      TS_ASSERT_DIFFERS(y[26], 0.0);
+    }
+
+    AnalysisDataService::Instance().clear();
+  }
+
 private:
   /// build test input workspaces for the Pawley function Fit tests
   MatrixWorkspace_sptr getWorkspacePawley(const std::string &functionString,
@@ -2042,7 +2102,8 @@ public:
   }
 
   void test_fit_peaks_Damping() {
-    runFitAlgorithm(m_onePeakWS, FitTestHelpers::SingleB2BPeak, "Damping");
+    runFitAlgorithm(m_onePeakWS, FitTestHelpers::SingleB2BPeak,
+                    "Damped GaussNewton");
   }
 
   void test_fit_peaks_SteepestDescent() {
@@ -2085,7 +2146,8 @@ public:
   }
 
   void test_fit_smooth_Damping() {
-    runFitAlgorithm(m_smoothWS, FitTestHelpers::SmoothishGaussians, "Damping");
+    runFitAlgorithm(m_smoothWS, FitTestHelpers::SmoothishGaussians,
+                    "Damped GaussNewton");
   }
 
   // disabled: too slow: ~17s
diff --git a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
index 06b7b715f2782a49c9e251e89821c2225aa99997..de2bc59b44bcd82d1aee0559ec75719bcf30d10e 100644
--- a/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
+++ b/Framework/CurveFitting/test/Algorithms/PlotPeakByLogValueTest.h
@@ -16,6 +16,8 @@
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/BinEdgeAxis.h"
+#include "MantidAPI/WorkspaceHistory.h"
+#include "MantidKernel/PropertyHistory.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/UnitFactory.h"
 
@@ -281,7 +283,7 @@ public:
   }
 
   void test_passWorkspaceIndexToFunction() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("PLOTPEAKBYLOGVALUETEST_WS", ws);
     PlotPeakByLogValue alg;
@@ -308,7 +310,7 @@ public:
   }
 
   void test_dont_passWorkspaceIndexToFunction() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("PLOTPEAKBYLOGVALUETEST_WS", ws);
     PlotPeakByLogValue alg;
@@ -337,7 +339,7 @@ public:
   }
 
   void test_passWorkspaceIndexToFunction_composit_function_case() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("PLOTPEAKBYLOGVALUETEST_WS", ws);
     PlotPeakByLogValue alg;
@@ -366,7 +368,7 @@ public:
   }
 
   void test_createOutputOption() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("PLOTPEAKBYLOGVALUETEST_WS", ws);
     PlotPeakByLogValue alg;
@@ -623,7 +625,7 @@ private:
     AnalysisDataService::Instance().add("PlotPeakGroup", m_wsg);
     const int N = 3;
     for (int iWS = 0; iWS < N; ++iWS) {
-      auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+      auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
           PlotPeak_Expression(iWS), 3, 0, 10, 0.005, hist);
       for (int i = 0; i < 3; ++i) {
         ws->getSpectrum(i).setSpectrumNo(0);
diff --git a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParameters3Test.h b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParameters3Test.h
index 71b6f5ebea22bf68727b88fa0e598288bce90881..e22e29d045a82c6e2064471890d6fb0ab73acac3 100644
--- a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParameters3Test.h
+++ b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParameters3Test.h
@@ -5,6 +5,7 @@
 
 #include "MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters3.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/TableWorkspace.h"
diff --git a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
index bdb436ab2f70eda5b738b8d4381d68f417146595..233c1a20055e57a6afc44f54949e3f49375657cd 100644
--- a/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
+++ b/Framework/CurveFitting/test/Algorithms/RefinePowderInstrumentParametersTest.h
@@ -4,11 +4,13 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Algorithms/RefinePowderInstrumentParameters.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include <fstream>
+#include <iomanip>
 
 using Mantid::CurveFitting::Algorithms::RefinePowderInstrumentParameters;
 using namespace Mantid;
diff --git a/Framework/CurveFitting/test/Algorithms/SeqDomainSpectrumCreatorTest.h b/Framework/CurveFitting/test/Algorithms/SeqDomainSpectrumCreatorTest.h
index c233a1b147bd51d1ba4eddfb71c2ec884713c994..0c95cad7690a1ec730e7c0542258bd40064aab51 100644
--- a/Framework/CurveFitting/test/Algorithms/SeqDomainSpectrumCreatorTest.h
+++ b/Framework/CurveFitting/test/Algorithms/SeqDomainSpectrumCreatorTest.h
@@ -17,6 +17,7 @@
 
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 #include "MantidTestHelpers/HistogramDataTestHelper.h"
 
@@ -51,7 +52,7 @@ public:
   void testSetMatrixWorkspace() {
     TestableSeqDomainSpectrumCreator creator(NULL, "");
     TS_ASSERT_THROWS_NOTHING(creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace(5, 5)));
+        WorkspaceCreationHelper::create2DWorkspace(5, 5)));
 
     TS_ASSERT_EQUALS(creator.m_matrixWorkspace->getNumberHistograms(), 5);
 
@@ -62,7 +63,7 @@ public:
   void testGetDomainSize() {
     TestableSeqDomainSpectrumCreator creator(NULL, "");
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12));
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12));
 
     FunctionDomain_sptr domain;
     FunctionValues_sptr values;
@@ -86,14 +87,14 @@ public:
     std::set<int64_t> masked;
     masked.insert(0);
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 12, false, masked));
+        WorkspaceCreationHelper::create2DWorkspace123(2, 12, false, masked));
 
     TS_ASSERT(!creator.histogramIsUsable(0));
     TS_ASSERT(creator.histogramIsUsable(1));
 
     // No instrument
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 12));
+        WorkspaceCreationHelper::create2DWorkspace123(2, 12));
     TS_ASSERT(creator.histogramIsUsable(0));
     TS_ASSERT(creator.histogramIsUsable(1));
   }
@@ -101,7 +102,7 @@ public:
   void testCreateDomain() {
     TestableSeqDomainSpectrumCreator creator(NULL, "");
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12, true));
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12, true));
 
     FunctionDomain_sptr domain;
     FunctionValues_sptr values;
@@ -133,7 +134,7 @@ public:
     std::set<int64_t> masked;
     masked.insert(2);
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12, true, masked));
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12, true, masked));
 
     FunctionDomain_sptr domain;
     FunctionValues_sptr values;
@@ -168,7 +169,7 @@ public:
 
     // TODO is the workspace created with the wrong values here
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12);
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12);
 
     TestableSeqDomainSpectrumCreator creator(NULL, "");
     creator.setMatrixWorkspace(matrixWs);
@@ -213,7 +214,7 @@ public:
     std::set<int64_t> masked;
     masked.insert(2);
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12, false, masked);
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12, false, masked);
 
     TestableSeqDomainSpectrumCreator creator(NULL, "");
     creator.setMatrixWorkspace(matrixWs);
@@ -245,9 +246,10 @@ public:
       const auto &y = outputWsMatrix->y(i);
 
       TS_ASSERT_EQUALS(x, matrixWs->x(i));
+      const auto &spectrumInfo = outputWsMatrix->spectrumInfo();
       for (size_t j = 0; j < x.size(); ++j) {
         // If detector is not masked, there should be values, otherwise 0.
-        if (!outputWsMatrix->getDetector(i)->isMasked()) {
+        if (!spectrumInfo.isMasked(i)) {
           TS_ASSERT_EQUALS(y[j], static_cast<double>(i) + slope * x[j]);
         } else {
           TS_ASSERT_EQUALS(y[j], 0.0);
@@ -259,7 +261,7 @@ public:
   void testCreateOutputWorkspaceWithDistributionAsInput() {
     // Arrange
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 12, true);
+        WorkspaceCreationHelper::create2DWorkspace123(4, 12, true);
     Mantid::API::WorkspaceHelpers::makeDistribution(matrixWs);
 
     TestableSeqDomainSpectrumCreator creator(NULL, "");
@@ -288,7 +290,7 @@ public:
     double slope = 2.0;
 
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(400, 500);
+        WorkspaceCreationHelper::create2DWorkspace123(400, 500);
     for (size_t i = 0; i < matrixWs->getNumberHistograms(); ++i) {
       auto &x = matrixWs->mutableX(i);
       auto &y = matrixWs->mutableY(i);
@@ -331,7 +333,7 @@ public:
     }
 
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(400, 50);
+        WorkspaceCreationHelper::create2DWorkspace123(400, 50);
     for (size_t i = 0; i < matrixWs->getNumberHistograms(); ++i) {
       auto &x = matrixWs->mutableX(i);
       auto &y = matrixWs->mutableY(i);
diff --git a/Framework/CurveFitting/test/Algorithms/SplineBackgroundTest.h b/Framework/CurveFitting/test/Algorithms/SplineBackgroundTest.h
index f198a379cbdc7283cc23163b24abcd61376fe317..2ab8d823a3a4970b07bfccf528ef354398361ca3 100644
--- a/Framework/CurveFitting/test/Algorithms/SplineBackgroundTest.h
+++ b/Framework/CurveFitting/test/Algorithms/SplineBackgroundTest.h
@@ -23,7 +23,7 @@ private:
 
 public:
   void testIt() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         SinFunction(), 1, 0.1, 10.1, 0.1, true);
     WorkspaceCreationHelper::addNoise(ws, 0.1);
     // Mask some bins out to test that functionality
@@ -66,7 +66,7 @@ public:
     constexpr double xRangeEnd = 2500.1;
     constexpr double xRangeStep = 0.1;
 
-    ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         SinFunction(), nspec, xRangeStart, xRangeEnd, xRangeStep, true);
     WorkspaceCreationHelper::addNoise(ws, 0.1);
     // Mask some bins out to test that functionality
diff --git a/Framework/CurveFitting/test/Algorithms/SplineInterpolationTest.h b/Framework/CurveFitting/test/Algorithms/SplineInterpolationTest.h
index 1718ced8660f37cfdc31e0b2d7a2de0ad041ceca..abffe7f19eb8ddc150e0912e0f376946e9271583 100644
--- a/Framework/CurveFitting/test/Algorithms/SplineInterpolationTest.h
+++ b/Framework/CurveFitting/test/Algorithms/SplineInterpolationTest.h
@@ -7,6 +7,7 @@
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/TextAxis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using Mantid::CurveFitting::Algorithms::SplineInterpolation;
 using namespace Mantid::API;
@@ -36,10 +37,10 @@ public:
 
     // create binned workspaces
     MatrixWorkspace_sptr mws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(SplineFunc(), 1,
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(SplineFunc(), 1,
                                                                0, 20, 1, false);
     MatrixWorkspace_sptr iws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 20, 0.1, false);
 
     SplineInterpolation alg;
@@ -52,10 +53,10 @@ public:
 
     // create binned workspaces
     MatrixWorkspace_sptr mws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(SplineFunc(), 1,
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(SplineFunc(), 1,
                                                                0, 20, 1, true);
     MatrixWorkspace_sptr iws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 20, 1, true);
 
     SplineInterpolation alg;
@@ -68,10 +69,10 @@ public:
 
     // create binned workspaces
     MatrixWorkspace_sptr mws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(SplineFunc(), 1,
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(SplineFunc(), 1,
                                                                0, 20, 1, true);
     MatrixWorkspace_sptr iws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 20, 1, true);
 
     SplineInterpolation alg;
@@ -84,10 +85,10 @@ public:
 
     // create binned workspaces
     MatrixWorkspace_sptr mws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(SplineFunc(), 1,
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(SplineFunc(), 1,
                                                                0, 20, 1, true);
     MatrixWorkspace_sptr iws =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 20, 1, true);
 
     // Add an axis
@@ -171,11 +172,11 @@ public:
     constexpr int xStepVal(1);
 
     MatrixWorkspace_sptr matWs =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, xStartVal, xEndVal, xStepVal, false);
 
     MatrixWorkspace_sptr inWs =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, xStartVal, xEndVal, (xStepVal * 0.1), false);
 
     inputWs = inWs;
diff --git a/Framework/CurveFitting/test/Algorithms/SplineSmoothingTest.h b/Framework/CurveFitting/test/Algorithms/SplineSmoothingTest.h
index fa82e66115db858040112abb75d3528cef173c78..7ef1ad3b8a3a111ad64a59c8b94c42636df3e6cb 100644
--- a/Framework/CurveFitting/test/Algorithms/SplineSmoothingTest.h
+++ b/Framework/CurveFitting/test/Algorithms/SplineSmoothingTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidCurveFitting/Algorithms/SplineSmoothing.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using Mantid::CurveFitting::Algorithms::SplineSmoothing;
 
@@ -36,7 +37,7 @@ public:
 
     // create a binned workspace
     MatrixWorkspace_sptr inputWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 5, 0.02, false);
 
     // setup algorithm
@@ -53,7 +54,7 @@ public:
 
     // create a binned workspace
     MatrixWorkspace_sptr inputWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 5, 0.02, true);
 
     SplineSmoothing alg;
@@ -69,7 +70,7 @@ public:
 
     // create a binned workspace
     MatrixWorkspace_sptr inputWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+        WorkspaceCreationHelper::create2DWorkspaceFromFunction(
             SplineFunc(), spectra, 0, 5, 0.02, true);
 
     SplineSmoothing alg;
diff --git a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
index b2ef11f7fb01113aae60a78313b308858b4eb47a..b4768449294f950efca2a91d6862c5f32dceddc8 100644
--- a/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
+++ b/Framework/CurveFitting/test/Algorithms/VesuvioCalculateMSTest.h
@@ -199,7 +199,7 @@ public:
     VesuvioCalculateMS alg;
     alg.initialize();
 
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     TS_ASSERT_THROWS(alg.setProperty("InputWorkspace", testWS),
                      std::invalid_argument);
   }
@@ -208,7 +208,7 @@ public:
     VesuvioCalculateMS alg;
     alg.initialize();
 
-    auto testWS = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto testWS = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     testWS->getAxis(0)->setUnit("TOF");
     TS_ASSERT_THROWS(alg.setProperty("InputWorkspace", testWS),
                      std::invalid_argument);
diff --git a/Framework/CurveFitting/test/CompositeFunctionTest.h b/Framework/CurveFitting/test/CompositeFunctionTest.h
index e6893283c435b902b1d376fe5a198215ce8a8000..15433437e8e287e06da2459340885d0293c70ff7 100644
--- a/Framework/CurveFitting/test/CompositeFunctionTest.h
+++ b/Framework/CurveFitting/test/CompositeFunctionTest.h
@@ -183,7 +183,7 @@ public:
     TS_ASSERT_EQUALS(mfun->getParameter(6), 1.1);
     TS_ASSERT_EQUALS(mfun->getParameter(7), 1.0);
 
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         TestFunction(), 1, 0.0, 10.0, 0.1);
     WorkspaceCreationHelper::addNoise(ws, 0.1);
     WorkspaceCreationHelper::storeWS("mfun", ws);
diff --git a/Framework/CurveFitting/test/FuncMinimizers/DampingMinimizerTest.h b/Framework/CurveFitting/test/FuncMinimizers/DampedGaussNewtonMinimizerTest.h
similarity index 95%
rename from Framework/CurveFitting/test/FuncMinimizers/DampingMinimizerTest.h
rename to Framework/CurveFitting/test/FuncMinimizers/DampedGaussNewtonMinimizerTest.h
index 260c0f58f68658826f4cdbe22325ec2b5d87621c..23f0f708ab0a57041336d75b61ef921a5edba551 100644
--- a/Framework/CurveFitting/test/FuncMinimizers/DampingMinimizerTest.h
+++ b/Framework/CurveFitting/test/FuncMinimizers/DampedGaussNewtonMinimizerTest.h
@@ -1,10 +1,10 @@
-#ifndef CURVEFITTING_DAMPINGTEST_H_
-#define CURVEFITTING_DAMPINGTEST_H_
+#ifndef CURVEFITTING_DAMPEDGAUSSNEWTONTEST_H_
+#define CURVEFITTING_DAMPEDGAUSSNEWTONTEST_H_
 
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
-#include "MantidCurveFitting/FuncMinimizers/DampingMinimizer.h"
+#include "MantidCurveFitting/FuncMinimizers/DampedGaussNewtonMinimizer.h"
 #include "MantidCurveFitting/Functions/UserFunction.h"
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionValues.h"
@@ -20,7 +20,7 @@ using namespace Mantid::CurveFitting::Constraints;
 using namespace Mantid::CurveFitting::Functions;
 using namespace Mantid::API;
 
-class DampingMinimizerTest : public CxxTest::TestSuite {
+class DampedGaussNewtonMinimizerTest : public CxxTest::TestSuite {
 public:
   void test_Gaussian() {
     API::FunctionDomain1D_sptr domain(
@@ -49,7 +49,7 @@ public:
         boost::make_shared<CostFuncLeastSquares>();
     costFun->setFittingFunction(fun, domain, values);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.existsProperty("Damping"));
     double damping = s.getProperty("Damping");
@@ -91,7 +91,7 @@ public:
         boost::make_shared<CostFuncLeastSquares>();
     costFun->setFittingFunction(fun, domain, values);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     s.setProperty("Damping", 100.0);
     double damping = s.getProperty("Damping");
@@ -135,7 +135,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 3);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
     TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
@@ -175,7 +175,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 3);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
     TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
@@ -215,7 +215,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 3);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
     TS_ASSERT_DELTA(costFun->val(), 0.002, 0.01);
@@ -256,7 +256,7 @@ public:
     costFun->setFittingFunction(fun, domain, values);
     TS_ASSERT_EQUALS(costFun->nParams(), 2);
 
-    DampingMinimizer s;
+    DampedGaussNewtonMinimizer s;
     s.initialize(costFun);
     TS_ASSERT(s.minimize());
 
@@ -266,4 +266,4 @@ public:
   }
 };
 
-#endif /*CURVEFITTING_DAMPINGTEST_H_*/
+#endif /*CURVEFITTING_DAMPEDGAUSSNEWTONTEST_H_*/
diff --git a/Framework/CurveFitting/test/FuncMinimizers/FABADAMinimizerTest.h b/Framework/CurveFitting/test/FuncMinimizers/FABADAMinimizerTest.h
index 2c61271703237c63d3e0a939bbd523ca9ea3cdf9..a0b922512b962a8609ad6a688df8ec10634ca5f8 100644
--- a/Framework/CurveFitting/test/FuncMinimizers/FABADAMinimizerTest.h
+++ b/Framework/CurveFitting/test/FuncMinimizers/FABADAMinimizerTest.h
@@ -7,6 +7,7 @@
 
 #include "MantidCurveFitting/Algorithms/Fit.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 #include "MantidCurveFitting/Functions/ExpDecay.h"
 #include "MantidKernel/PropertyManager.h"
diff --git a/Framework/CurveFitting/test/FunctionDomain1DSpectrumCreatorTest.h b/Framework/CurveFitting/test/FunctionDomain1DSpectrumCreatorTest.h
index 4a7ca5b4c232878898be04eadc7f901275966757..82a877ce301905e96e5f170108944109a590bb03 100644
--- a/Framework/CurveFitting/test/FunctionDomain1DSpectrumCreatorTest.h
+++ b/Framework/CurveFitting/test/FunctionDomain1DSpectrumCreatorTest.h
@@ -54,7 +54,7 @@ public:
     TestableFunctionDomain1DSpectrumCreator creator;
 
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(10, 15);
+        WorkspaceCreationHelper::create2DWorkspace123(10, 15);
     creator.setMatrixWorkspace(matrixWs);
 
     TS_ASSERT_EQUALS(creator.m_matrixWorkspace->getNumberHistograms(), 10);
@@ -70,7 +70,7 @@ public:
     TS_ASSERT_THROWS(creator.throwIfWorkspaceInvalid(), std::invalid_argument);
 
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(10, 15));
+        WorkspaceCreationHelper::create2DWorkspace123(10, 15));
     // still throws, since workspace index has not been set explicitly.
     TS_ASSERT_THROWS(creator.throwIfWorkspaceInvalid(), std::invalid_argument);
 
@@ -85,13 +85,13 @@ public:
   void testGetDomainSize() {
     FunctionDomain1DSpectrumCreator creator;
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 5, 0.0, 1.0));
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 5, 0.0, 1.0));
     creator.setWorkspaceIndex(0);
 
     TS_ASSERT_EQUALS(creator.getDomainSize(), 5);
 
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 15));
+        WorkspaceCreationHelper::create2DWorkspace123(1, 15));
 
     TS_ASSERT_EQUALS(creator.getDomainSize(), 15);
   }
@@ -99,7 +99,7 @@ public:
   void testCreateDomain() {
     TestableFunctionDomain1DSpectrumCreator creator;
     creator.setMatrixWorkspace(
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 5));
+        WorkspaceCreationHelper::create2DWorkspace123(1, 5));
     creator.setWorkspaceIndex(0);
 
     FunctionDomain_sptr domain;
@@ -130,4 +130,4 @@ private:
   };
 };
 
-#endif /* MANTID_CURVEFITTING_FUNCTIONDOMAIN1DSPECTRUMCREATORTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_CURVEFITTING_FUNCTIONDOMAIN1DSPECTRUMCREATORTEST_H_ */
diff --git a/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h b/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h
index 6588d3fd3592b8dee328318757db78144c1092b4..375f273bd9dc14bd7e0ee11cc0afccb29d840e2d 100644
--- a/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h
+++ b/Framework/CurveFitting/test/FunctionParameterDecoratorFitTest.h
@@ -75,7 +75,7 @@ public:
 
   void testFit() {
     Workspace2D_sptr ws =
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(20, 1.5, 0.5);
+        WorkspaceCreationHelper::create1DWorkspaceConstant(20, 1.5, 0.5);
 
     FunctionParameterDecorator_sptr fn =
         boost::make_shared<SimpleFunctionParameterDecorator>();
diff --git a/Framework/CurveFitting/test/Functions/ChebyshevTest.h b/Framework/CurveFitting/test/Functions/ChebyshevTest.h
index 68db7ff0238679b5e0df9572ad44d1da5517907a..8e388b4896b9d12d7e209d5a847b7fce5addec96 100644
--- a/Framework/CurveFitting/test/Functions/ChebyshevTest.h
+++ b/Framework/CurveFitting/test/Functions/ChebyshevTest.h
@@ -7,6 +7,8 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
+#include <array>
+
 using namespace Mantid::API;
 using Mantid::CurveFitting::Functions::Chebyshev;
 
diff --git a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
index 1e6c65d280eb9dc7b988d1d2e69c17d6abadd0cc..2504e8eadf6bb2b4112bc22cd14c804f98e2694e 100644
--- a/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
+++ b/Framework/CurveFitting/test/Functions/ComptonProfileTestHelpers.h
@@ -42,7 +42,7 @@ createTestWorkspace(const size_t nhist, const double x0, const double x1,
                     const double dx, const bool singleMassSpectrum,
                     const bool addFoilChanger) {
   bool isHist(false);
-  auto ws2d = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+  auto ws2d = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
       ones(), static_cast<int>(nhist), x0, x1, dx, isHist);
   ws2d->getAxis(0)->setUnit("TOF");
   if (singleMassSpectrum) {
diff --git a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
index d36f4d4425fc4ff2cefc9ce25e15e01b3496ee9b..6d9054a2b776fb586a3ff3f725dd87862f1c3317 100644
--- a/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
+++ b/Framework/CurveFitting/test/Functions/CrystalFieldMultiSpectrumTest.h
@@ -148,14 +148,14 @@ public:
     TS_ASSERT_EQUALS(out->getNumberHistograms(), 3);
     TS_ASSERT_DELTA(out->readY(1)[0], 1.094 * 2.0 * c_mbsr, 0.001 * c_mbsr);
     TS_ASSERT_DELTA(out->readY(1)[1], 0.738 * 2.0 * c_mbsr, 0.001 * c_mbsr);
-    TS_ASSERT_DELTA(out->readY(1)[2], 0.373 * 2.0 * c_mbsr, 0.001 * c_mbsr);
+    TS_ASSERT_DELTA(out->readY(1)[2], 59.5010, 0.001);
     out = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
         "Workspace_1");
     TS_ASSERT(out);
     TS_ASSERT_EQUALS(out->getNumberHistograms(), 3);
     TS_ASSERT_DELTA(out->readY(1)[0], 1.094 * 3.3 * c_mbsr, 0.001 * c_mbsr);
     TS_ASSERT_DELTA(out->readY(1)[1], 0.738 * 3.3 * c_mbsr, 0.001 * c_mbsr);
-    TS_ASSERT_DELTA(out->readY(1)[2], 0.3734 * 3.3 * c_mbsr, 0.001 * c_mbsr);
+    TS_ASSERT_DELTA(out->readY(1)[2], 98.1627, 0.001);
     AnalysisDataService::Instance().clear();
   }
 
@@ -371,6 +371,48 @@ public:
     TS_ASSERT_LESS_THAN(chi2, 100.0);
   }
 
+  void test_ties_in_composite_function() {
+    std::string funDef =
+        "name=CrystalFieldMultiSpectrum,Ion=Ce,Symmetry=C2v,Temperatures=(44.0,"
+        "50),FWHMs=(1.1,0.9),B44=-0.115325956893,B40=0.0844136192563,B42=-0."
+        "459507287606,B22=4.36779676967;name=CrystalFieldMultiSpectrum,Ion=Pr,"
+        "Symmetry=C2v,Temperatures=(44.0,50),FWHMs=(1.1,0.9),B44=-0."
+        "115325956893,B40=0.0844136192563,B42=-0.459507287606,B22=4."
+        "36779676967;ties=(f1.IntensityScaling0=2.0*f0.IntensityScaling0,f1."
+        "IntensityScaling1=2.0*f0.IntensityScaling1,f0.f0.f1.FWHM=f1.f0.f1."
+        "FWHM/2)";
+    auto fun = FunctionFactory::Instance().createInitialized(funDef);
+    {
+      auto index = fun->parameterIndex("f1.IntensityScaling0");
+      auto tie = fun->getTie(index);
+      TS_ASSERT(tie);
+      if (!tie) {
+        return;
+      }
+      TS_ASSERT_EQUALS(tie->asString(),
+                       "f1.IntensityScaling0=2.0*f0.IntensityScaling0");
+    }
+    {
+      auto index = fun->parameterIndex("f1.IntensityScaling1");
+      auto tie = fun->getTie(index);
+      TS_ASSERT(tie);
+      if (!tie) {
+        return;
+      }
+      TS_ASSERT_EQUALS(tie->asString(),
+                       "f1.IntensityScaling1=2.0*f0.IntensityScaling1");
+    }
+    {
+      auto index = fun->parameterIndex("f0.f0.f1.FWHM");
+      auto tie = fun->getTie(index);
+      TS_ASSERT(tie);
+      if (!tie) {
+        return;
+      }
+      TS_ASSERT_EQUALS(tie->asString(), "f0.f0.f1.FWHM=f1.f0.f1.FWHM/2");
+    }
+  }
+
 private:
   Workspace_sptr createWorkspace() {
     auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, 100, 100);
diff --git a/Framework/CurveFitting/test/Functions/CrystalFieldSpectrumTest.h b/Framework/CurveFitting/test/Functions/CrystalFieldSpectrumTest.h
index 01cd42bb5f7b6d5bb14980ddaa8dcd92879347a6..39b37300f5c6f114ea319097aa22ddfbf5a45ea7 100644
--- a/Framework/CurveFitting/test/Functions/CrystalFieldSpectrumTest.h
+++ b/Framework/CurveFitting/test/Functions/CrystalFieldSpectrumTest.h
@@ -652,6 +652,39 @@ public:
     TS_ASSERT_THROWS_NOTHING(fit->execute());
   }
 
+  void test_ties_in_composite_function() {
+    std::string funDef =
+        "name=CrystalFieldSpectrum,Ion=Ce,Symmetry=C2v,Temperature=44.0,"
+        "ToleranceEnergy=1e-10,ToleranceIntensity=0.1,FixAllPeaks=False,"
+        "PeakShape=Lorentzian,FWHM=1.1,B44=-0.12544,B20=0.37737,B22=3.977,B40=-"
+        "0.031787,B42=-0.11611;name=CrystalFieldSpectrum,Ion=Pr,Symmetry=C2v,"
+        "Temperature="
+        "44.0,ToleranceEnergy=1e-10,ToleranceIntensity=0.1,FixAllPeaks=False,"
+        "PeakShape=Lorentzian,FWHM=1.1,B44=-0.12544,B20=0.37737,B22=3.977,B40=-"
+        "0.031787,B42=-0.11611;ties=(f1.IntensityScaling=2.0*f0."
+        "IntensityScaling,f0.f1.FWHM=f1.f2.FWHM/2)";
+    auto fun = FunctionFactory::Instance().createInitialized(funDef);
+    {
+      auto index = fun->parameterIndex("f1.IntensityScaling");
+      auto tie = fun->getTie(index);
+      TS_ASSERT(tie);
+      if (!tie) {
+        return;
+      }
+      TS_ASSERT_EQUALS(tie->asString(),
+                       "f1.IntensityScaling=2.0*f0.IntensityScaling");
+    }
+    {
+      auto index = fun->parameterIndex("f0.f1.FWHM");
+      auto tie = fun->getTie(index);
+      TS_ASSERT(tie);
+      if (!tie) {
+        return;
+      }
+      TS_ASSERT_EQUALS(tie->asString(), "f0.f1.FWHM=f1.f2.FWHM/2");
+    }
+  }
+
 private:
   std::pair<double, double> getBounds(API::IFunction &fun,
                                       const std::string &parName) {
diff --git a/Framework/CurveFitting/test/Functions/DeltaFunctionTest.h b/Framework/CurveFitting/test/Functions/DeltaFunctionTest.h
index a6873994c0fb319cb6d6ca47ebaa538cccb3f681..164f9feb4f1b3be27c0f8da146a4f522b0afd5ac 100644
--- a/Framework/CurveFitting/test/Functions/DeltaFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/DeltaFunctionTest.h
@@ -127,7 +127,6 @@ public:
   }
 
   void test_delta_with_shift() {
-    IPeakFunction::setPeakRadius(1000);
     auto res = IPeakFunction_sptr(new DeltaFunctionTest_Gauss());
     double a = 0.13;
     double ha = 1.0 / sqrt(M_PI * a);
@@ -169,7 +168,6 @@ public:
   }
 
   void test_two_deltas_with_shifts() {
-    IPeakFunction::setPeakRadius(1000);
     auto res = IPeakFunction_sptr(new DeltaFunctionTest_Gauss());
     double a = 0.13;
     double ha = 1.0 / sqrt(M_PI * a);
diff --git a/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h b/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
index c667c12d27acf784194a5e24758e921897973ae5..1c6ce5f34b47d67c7cbd278e10e9b7c5631e771f 100644
--- a/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
+++ b/Framework/CurveFitting/test/Functions/DiffRotDiscreteCircleTest.h
@@ -431,7 +431,7 @@ private:
     const size_t M = xView.size();
     // create temporaray workspace.
     auto temp_ws =
-        WorkspaceCreationHelper::Create2DWorkspace(1, static_cast<int>(M));
+        WorkspaceCreationHelper::create2DWorkspace(1, static_cast<int>(M));
     for (size_t i = 0; i < M; i++) {
       temp_ws->dataX(0)[i] = xView[i];
       temp_ws->dataY(0)[i] = dataYvalues.getCalculated(i);
@@ -484,7 +484,7 @@ private:
       dataX[i] = (static_cast<double>(i) - M / 2) * dw;
 
     // create the workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, M);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, M);
     double fractional_error = 0.01; // error taken as a percent of the signal
     for (size_t i = 0; i < M; i++) {
       double bin_boundary =
@@ -541,7 +541,7 @@ private:
     fitalg_function->function(dataXview, dataYvalues);
 
     // Create the workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, M);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, M);
 
     // Create the instrument
     boost::shared_ptr<Instrument> inst =
diff --git a/Framework/CurveFitting/test/Functions/DiffSphereTest.h b/Framework/CurveFitting/test/Functions/DiffSphereTest.h
index 1023e8c8a0701625648d60ba5b9c16f257d6715e..91b4019a44516ff37cace8bfbab256f87b08468b 100644
--- a/Framework/CurveFitting/test/Functions/DiffSphereTest.h
+++ b/Framework/CurveFitting/test/Functions/DiffSphereTest.h
@@ -73,6 +73,7 @@ public:
     fitalg.setProperty("Function", funtion_string);
     fitalg.setProperty("InputWorkspace", data_workspace);
     fitalg.setPropertyValue("WorkspaceIndex", "0");
+    fitalg.setProperty("IgnoreInvalidData", true);
     TS_ASSERT_THROWS_NOTHING(TS_ASSERT(fitalg.execute()));
     TS_ASSERT(fitalg.isExecuted());
 
@@ -475,7 +476,7 @@ private:
     fitalg_function->function(dataXview, dataYvalues);
 
     // Create the workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, M);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, M);
 
     // Create the instrument
     boost::shared_ptr<Instrument> inst =
diff --git a/Framework/CurveFitting/test/Functions/FunctionQDependsTest.h b/Framework/CurveFitting/test/Functions/FunctionQDependsTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1860a032320980e32c2fbd7df29003145ed6ae2d
--- /dev/null
+++ b/Framework/CurveFitting/test/Functions/FunctionQDependsTest.h
@@ -0,0 +1,173 @@
+#ifndef MANTID_CURVEFITTING_FUNCTIONQDEPENDSTEST_H
+#define MANTID_CURVEFITTING_FUNCTIONQDEPENDSTEST_H
+
+// Mantid Coding standars <http://www.mantidproject.org/Coding_Standards>
+
+// Mantid Headers from the same project
+#include "MantidCurveFitting/Functions/FunctionQDepends.h"
+// Mantid headers from other projects
+#include "MantidAPI/IFunction.h"
+#include "MantidAPI/ParamFunction.h"
+#include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidKernel/EmptyValues.h"
+#include "MantidDataHandling/LoadNexus.h"
+// 3rd party library headers
+#include <cxxtest/TestSuite.h>
+// Standard library
+// N/A
+
+using Attr = Mantid::API::IFunction::Attribute;
+
+namespace {
+class ImplementsFunctionQDepends
+    : public Mantid::CurveFitting::Functions::FunctionQDepends {
+
+public:
+  std::string name() const override { return "ImplementsFunctionQDepends"; }
+
+  void function1D(double *out, const double *xValues,
+                  const size_t nData) const override {
+    double Q = this->getAttribute("Q").asDouble();
+    for (size_t i = 0; i < nData; i++) {
+      out[i] = Q * xValues[i];
+    }
+  }
+};
+} // end of namespace
+
+class FunctionQDependsTest : 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 FunctionQDependsTest *createSuite() {
+    return new FunctionQDependsTest();
+  }
+  static void destroySuite(FunctionQDependsTest *suite) { delete suite; }
+
+  void testConstruction() {
+    TS_ASSERT_THROWS_NOTHING(ImplementsFunctionQDepends f);
+  }
+
+  void testInitialization() {
+    ImplementsFunctionQDepends f;
+    TS_ASSERT_THROWS_NOTHING(f.initialize());
+  }
+
+  void testSetWorkspace() {
+    double startX{0.0}, endX{1.0};
+    ImplementsFunctionQDepends f;
+    f.initialize(); // declare attributes
+    // test with an non matrix workspace
+    TS_ASSERT_THROWS_NOTHING(
+        f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX));
+    // test with a non-suitable matrix workspace
+    TS_ASSERT_THROWS_NOTHING(
+        f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX));
+    // test with a workspace containing Q values in the vertical axis
+    TS_ASSERT_THROWS_NOTHING(
+        f.setMatrixWorkspace(this->withQonVerticalAxis(), 0, startX, endX));
+    // test with a workspace containing detectors for calculation of Q values
+    TS_ASSERT_THROWS_NOTHING(
+        f.setMatrixWorkspace(this->withDetectors(), 0, startX, endX));
+  }
+
+  void testQAttribute() {
+    double startX{0.0}, endX{1.0};
+    ImplementsFunctionQDepends f;
+    f.initialize(); // declare attributes
+    auto Q = f.getAttribute("Q").asDouble();
+    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
+    f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX);
+    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
+    f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX);
+    TS_ASSERT_EQUALS(Q, Mantid::EMPTY_DBL());
+    // test assigning Q when no matrix workspace has been set
+    f.setAttribute("Q", Attr(0.18));
+    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.18);
+    // test assigning Q when a workspace has been set
+    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
+    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q overwritten
+    f.setAttribute("Q", Attr(0.18));
+    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q not overwritten
+  }
+
+  void testWorkspaceIndexAttribute() {
+    double startX{0.0}, endX{1.0};
+    ImplementsFunctionQDepends f;
+    f.initialize(); // declare attributes
+    auto wi = f.getAttribute("WorkspaceIndex").asInt();
+    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
+    f.setMatrixWorkspace(this->unsuitableWS(), 0, startX, endX);
+    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
+    f.setMatrixWorkspace(this->withoutQ(), 0, startX, endX);
+    TS_ASSERT_EQUALS(wi, Mantid::EMPTY_INT());
+    // test assigning wi when no matrix workspace has been set
+    f.setAttribute("WorkspaceIndex", Attr(1));
+    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(),
+                     Mantid::EMPTY_INT()); // not overwritten
+    // test assigning wi when a workspace has been set
+    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
+    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(), 1);
+    f.setAttribute("WorkspaceIndex", Attr(0));
+    TS_ASSERT_EQUALS(f.getAttribute("WorkspaceIndex").asInt(),
+                     0); // WorkspaceIndex overwritten
+  }
+
+  void testWorkspaceIndexTiesQ() {
+    double startX{0.0}, endX{1.0};
+    ImplementsFunctionQDepends f;
+    f.initialize(); // declare attributes
+    f.setMatrixWorkspace(this->withQonVerticalAxis(), 1, startX, endX);
+    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.5); // Q overwritten
+    f.setAttribute("WorkspaceIndex", Attr(0));
+    TS_ASSERT_EQUALS(f.getAttribute("Q").asDouble(), 0.3); // Q overwritten
+    f.setMatrixWorkspace(this->withDetectors(), 9, startX, endX);
+    TS_ASSERT_DELTA(f.getAttribute("Q").asDouble(), 1.82,
+                    0.01); // Q overwritten
+    Mantid::API::AnalysisDataService::Instance().clear();
+  }
+
+private:
+  // return a MatrixWorkspace with Q values on the vertical axis
+  Mantid::DataObjects::Workspace2D_sptr withQonVerticalAxis() {
+    int nhist{4}, nbins{9};
+    // create an axis of Q-values
+    std::vector<double> qvalues{
+        0.3, 0.5, 0.5, 0.9}; // as many elements as the value of variable nhist
+    auto momenta = new Mantid::API::NumericAxis(qvalues);
+    momenta->setUnit("MomentumTransfer");
+    // create the matrix workspace
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins);
+    ws->replaceAxis(1, momenta);
+    return ws;
+  }
+
+  // return a MatrixWorkspace with detectors allowing computations of Q values
+  Mantid::API::MatrixWorkspace_sptr withDetectors() {
+    Mantid::DataHandling::LoadNexus loader;
+    loader.initialize();
+    loader.setPropertyValue("Filename", "irs26173_graphite002_red");
+    loader.setPropertyValue("OutputWorkspace", "irs26173");
+    TS_ASSERT_THROWS_NOTHING(loader.execute());
+    TS_ASSERT(loader.isExecuted());
+    return Mantid::API::AnalysisDataService::Instance()
+        .retrieveWS<Mantid::API::MatrixWorkspace>("irs26173");
+  }
+
+  // return a MatrixWorkspace without Q values
+  Mantid::DataObjects::Workspace2D_sptr withoutQ() {
+    int nhist{3}, nbins{9};
+    return WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nbins);
+  }
+
+  // return a Workspace not of MatrixWorkspace type
+  Mantid::DataObjects::EventWorkspace_sptr unsuitableWS() {
+    return WorkspaceCreationHelper::createEventWorkspace();
+  }
+};
+
+#endif /* MANTID_API_FUNCTIONQDEPENDSTEST_H */
diff --git a/Framework/CurveFitting/test/Functions/IkedaCarpenterPVTest.h b/Framework/CurveFitting/test/Functions/IkedaCarpenterPVTest.h
index 5ef06fa8236207d4497cf6154e477670faa9d2da..6285adf379bafde31d3faa212ef52e2567bae6ee 100644
--- a/Framework/CurveFitting/test/Functions/IkedaCarpenterPVTest.h
+++ b/Framework/CurveFitting/test/Functions/IkedaCarpenterPVTest.h
@@ -56,6 +56,20 @@ public:
     TS_ASSERT_DELTA(y[13], 77.7493, 1e-4);
     TS_ASSERT_DELTA(y[14], 53.8871, 1e-4);
   }
+
+  void test_intensity() {
+    IkedaCarpenterPV fn;
+    fn.initialize();
+    fn.setParameter("I", 67.2548);
+    fn.setParameter("Alpha0", 1.6);
+    fn.setParameter("Alpha1", 1.5);
+    fn.setParameter("Beta0", 31.9);
+    fn.setParameter("Kappa", 46.0);
+    fn.setParameter("SigmaSquared", 0.00281776);
+    fn.setParameter("Gamma", 0.125);
+    fn.setParameter("X0", 0);
+    TS_ASSERT_DELTA(fn.intensity(), 810.7256, 1e-4);
+  }
 };
 
 #endif /*IKEDACARPENTERPVTEST_H_*/
diff --git a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
index a89fdc30a80bc54c8a5cdf2a2f8afe622c83af6c..acd2ddcd4f044a5c4198e43c6ddb1cb46d45ec57 100644
--- a/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
+++ b/Framework/CurveFitting/test/Functions/ProcessBackgroundTest.h
@@ -6,6 +6,7 @@
 #include "MantidCurveFitting/Functions/ProcessBackground.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidKernel/MersenneTwister.h"
diff --git a/Framework/CurveFitting/test/Functions/ResolutionTest.h b/Framework/CurveFitting/test/Functions/ResolutionTest.h
index e247c61288866ab23c568449889a54023f142848..ff124dd187f4fd3ec3d4aefd4180ef6ca3084e22 100644
--- a/Framework/CurveFitting/test/Functions/ResolutionTest.h
+++ b/Framework/CurveFitting/test/Functions/ResolutionTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidCurveFitting/Functions/Resolution.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IPeakFunction.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h b/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
index 79b9ff4ad5e27c4531c8d324558d1f788ebde352..7211061ef362c52ffec2a05207e7893090ebef59 100644
--- a/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
+++ b/Framework/CurveFitting/test/Functions/TabulatedFunctionTest.h
@@ -123,7 +123,7 @@ public:
   }
 
   void test_loadWorkspace() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 1, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("TABULATEDFUNCTIONTEST_WS", ws);
     TabulatedFunction fun;
@@ -144,7 +144,7 @@ public:
   }
 
   void test_loadWorkspace_nondefault_index() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("TABULATEDFUNCTIONTEST_WS", ws);
     TabulatedFunction fun;
@@ -168,7 +168,7 @@ public:
   }
 
   void test_loadWorkspace_nondefault_wrong_index() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 3, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("TABULATEDFUNCTIONTEST_WS", ws);
     TabulatedFunction fun;
@@ -187,7 +187,7 @@ public:
   }
 
   void test_Derivatives() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 1, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("TABULATEDFUNCTIONTEST_WS", ws);
     TabulatedFunction fun;
@@ -244,7 +244,7 @@ public:
   }
 
   void test_factory_create_from_workspace() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspaceFromFunction(
+    auto ws = WorkspaceCreationHelper::create2DWorkspaceFromFunction(
         Fun(), 1, -5.0, 5.0, 0.1, false);
     AnalysisDataService::Instance().add("TABULATEDFUNCTIONTEST_WS", ws);
     std::string inif = "name=TabulatedFunction,Workspace=TABULATEDFUNCTIONTEST_"
diff --git a/Framework/CurveFitting/test/Functions/VoigtTest.h b/Framework/CurveFitting/test/Functions/VoigtTest.h
index 74c76e0aa518baa8c9d7ed76c45d70b2b04ea523..34d940fac854c525e2a8d2d8ec4f1a5b5d0ad6b1 100644
--- a/Framework/CurveFitting/test/Functions/VoigtTest.h
+++ b/Framework/CurveFitting/test/Functions/VoigtTest.h
@@ -14,6 +14,7 @@
 
 using Mantid::CurveFitting::Functions::Voigt;
 using Mantid::API::IFunction;
+using Mantid::API::IPeakFunction;
 
 class VoigtTest : public CxxTest::TestSuite {
 public:
@@ -104,7 +105,7 @@ public:
         boost::dynamic_pointer_cast<Mantid::API::IPeakFunction>(voigtFn);
 
     TS_ASSERT_DELTA(peakFn->centre(), pos, 1e-12);
-    TS_ASSERT_DELTA(peakFn->height(), 2.0 * a_L / 3.0, 1e-12);
+    TS_ASSERT_DELTA(peakFn->height(), 4.9570, 1e-4);
     TS_ASSERT_DELTA(peakFn->fwhm(), (gamma_L + gamma_G), 1e-12);
   }
 
@@ -128,16 +129,150 @@ public:
     TS_ASSERT_DELTA(peakFn->fwhm(), (gamma_L + gamma_G), 1e-12);
   }
 
+  void test_height() {
+    {
+      auto voigt = createFunction(0, 0, 0, 0);
+      TS_ASSERT_EQUALS(voigt->height(), 0.0);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(1, 0, 0, 0);
+      TS_ASSERT_EQUALS(voigt->height(), 0.0);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(1, 0, 1, 0);
+      TS_ASSERT_EQUALS(voigt->height(), 0.0);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 1, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 4.7123, 1e-4);
+    }
+    {
+      auto voigt = createFunction(1, 0, 0, 1);
+      TS_ASSERT_EQUALS(voigt->height(), 0.0);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 1, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.1933, 1e-4);
+    }
+    {
+      auto voigt = createFunction(0, 0, 1, 1);
+      TS_ASSERT_EQUALS(voigt->height(), 0.0);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 2, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 6.6795, 1e-4);
+    }
+    {
+      auto voigt = createFunction(4, 0, 2, 3);
+      TS_ASSERT_DELTA(voigt->height(), 2.3159, 1e-4);
+      voigt->setHeight(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 5, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 16.2778, 1e-4);
+    }
+  }
+
+  void test_intensity() {
+    {
+      auto voigt = createFunction(0, 0, 0, 0);
+      TS_ASSERT_EQUALS(voigt->intensity(), 0.0);
+      voigt->setIntensity(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 6068115080134125.22, 1e10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(1, 0, 0, 0);
+      TS_ASSERT_EQUALS(voigt->intensity(), 0.0);
+      voigt->setIntensity(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 6068115080134125.22, 1e10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(1, 0, 0, 1);
+      TS_ASSERT_EQUALS(voigt->intensity(), 0.0);
+      voigt->setIntensity(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 2.8183, 1e-4);
+      TS_ASSERT_DELTA(voigt->fwhm(), 1, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(1, 0, 1, 0);
+      TS_ASSERT_EQUALS(voigt->intensity(), 0.0);
+      voigt->setIntensity(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 1.9098, 1e-4);
+      TS_ASSERT_DELTA(voigt->fwhm(), 1, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(4, 0, 2, 3);
+      TS_ASSERT_DELTA(voigt->intensity(), 12.5663, 1e-4);
+      voigt->setIntensity(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 0.5528, 1e-4);
+      TS_ASSERT_DELTA(voigt->fwhm(), 5, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->IPeakFunction::intensity(), 3.0, 1e-2);
+    }
+  }
+
+  void test_fwhm() {
+    {
+      auto voigt = createFunction(0, 0, 0, 0);
+      TS_ASSERT_EQUALS(voigt->fwhm(), 0.0);
+      voigt->setFwhm(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 3, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 0.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("LorentzFWHM"), 1.5, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("GaussianFWHM"), 1.5, 1e-10);
+    }
+    {
+      auto voigt = createFunction(0, 0, 1, 0);
+      TS_ASSERT_EQUALS(voigt->fwhm(), 1.0);
+      voigt->setFwhm(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 3, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 0.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("LorentzFWHM"), 3.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("GaussianFWHM"), 0.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(0, 0, 0, 1);
+      TS_ASSERT_EQUALS(voigt->fwhm(), 1.0);
+      voigt->setFwhm(3.0);
+      TS_ASSERT_DELTA(voigt->height(), 0, 1e-10);
+      TS_ASSERT_DELTA(voigt->fwhm(), 3, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 0.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("LorentzFWHM"), 0.0, 1e-10);
+      TS_ASSERT_DELTA(voigt->getParameter("GaussianFWHM"), 3.0, 1e-10);
+    }
+    {
+      auto voigt = createFunction(2, 0, 2, 1);
+      TS_ASSERT_EQUALS(voigt->fwhm(), 3.0);
+      voigt->setFwhm(5.5);
+      TS_ASSERT_DELTA(voigt->fwhm(), 5.5, 1e-10);
+      TS_ASSERT_DELTA(voigt->intensity(), 11.5191, 1e-4);
+      TS_ASSERT_DELTA(voigt->getParameter("LorentzFWHM"), 3.6666, 1e-4);
+      TS_ASSERT_DELTA(voigt->getParameter("GaussianFWHM"), 1.8333, 1e-4);
+    }
+  }
+
 private:
-  boost::shared_ptr<IFunction> createFunction(const double a_L,
-                                              const double pos,
-                                              const double gamma_L,
-                                              const double gamma_G) {
+  boost::shared_ptr<Mantid::API::IPeakFunction>
+  createFunction(const double a_L, const double pos, const double gamma_L,
+                 const double gamma_G) {
     boost::shared_ptr<IFunction> voigtFn = boost::make_shared<Voigt>();
     auto peakFn =
         boost::dynamic_pointer_cast<Mantid::API::IPeakFunction>(voigtFn);
-    // Set a fairly wide radius for simple tests
-    peakFn->setPeakRadius(10);
     voigtFn->initialize();
 
     voigtFn->setParameter("LorentzAmp", a_L);
@@ -145,7 +280,7 @@ private:
     voigtFn->setParameter("LorentzFWHM", gamma_L);
     voigtFn->setParameter("GaussianFWHM", gamma_G);
 
-    return voigtFn;
+    return peakFn;
   }
 
   enum { g_domainSize = 10 };
diff --git a/Framework/CurveFitting/test/MultiDomainCreatorTest.h b/Framework/CurveFitting/test/MultiDomainCreatorTest.h
index 5cd23175905ea0f1deb7c21375c6e67e4592a0a2..cb866cd96783b78a21f02f007c34bb0112a0e469 100644
--- a/Framework/CurveFitting/test/MultiDomainCreatorTest.h
+++ b/Framework/CurveFitting/test/MultiDomainCreatorTest.h
@@ -22,6 +22,7 @@
 #include <algorithm>
 
 using namespace Mantid;
+using namespace Mantid::Kernel;
 using namespace Mantid::API;
 using namespace Mantid::CurveFitting;
 using namespace Mantid::CurveFitting::Functions;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
index 617cc786e77f0c42ddb9884e1c8dff09cb54f91a..a0fb1ea9053758fdc00dde82be7cb1762359074b 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/GroupDetectors2.h
@@ -1,12 +1,10 @@
 #ifndef MANTID_DATAHANDLING_GROUPDETECTORS2_H_
 #define MANTID_DATAHANDLING_GROUPDETECTORS2_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
+#include "MantidKernel/StringTokenizer.h"
 
 #include <map>
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Framework/DataHandling/inc/MantidDataHandling/Load.h
index faafaf643896e5ce7315dab94ccf69db535dbb3d..a36f9aac772a09f484429e4653270a06cd9cc4b3 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/Load.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/Load.h
@@ -1,10 +1,8 @@
 #ifndef MANTID_DATAHANDLING_LOAD_H_
 #define MANTID_DATAHANDLING_LOAD_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include <mutex>
 
 namespace Mantid {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h
index 8a8729c7f29139e547f09e38afe0ee7ac6b6f9ab..495855b384daa7f52bfa0836d072c14a9b5f299c 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii.h
@@ -1,12 +1,11 @@
 #ifndef MANTID_DATAHANDLING_LOADASCII_H_
 #define MANTID_DATAHANDLING_LOADASCII_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/IFileLoader.h"
 #include "MantidAPI/DeprecatedAlgorithm.h"
 
+#include <list>
+
 namespace Mantid {
 namespace DataHandling {
 /**
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
index 944c23c96662642f280e13280701611d688eea17..db7c394e41301412bb1f427fdc0142cba2925968 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadAscii2.h
@@ -1,13 +1,12 @@
 #ifndef MANTID_DATAHANDLING_LoadAscii2_H_
 #define MANTID_DATAHANDLING_LoadAscii2_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/IFileLoader.h"
 #include "MantidDataObjects/Histogram1D.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 
+#include <list>
+
 namespace Mantid {
 namespace DataHandling {
 /**
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D.h b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D.h
index 26a1f6b3aeba9a7465bbed7098b05704a905b881..2c1fc7c64621e2fb95246bbe2daa6c02df5b016e 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadCanSAS1D.h
@@ -1,14 +1,11 @@
 #ifndef MANTID_DATAHANDLING_LoadCanSAS1D_H
 #define MANTID_DATAHANDLING_LoadCanSAS1D_H
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/IFileLoader.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include <Poco/DOM/Element.h>
 #include <Poco/DOM/Node.h>
-//----------------------------------------------------------------------
 
 namespace Poco {
 namespace XML {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors.h
index 32454e84b3920f2956cae62b0d202c1cc19427c2..8b284a2c647a715b113d51a9873101461f9189bd 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors.h
@@ -2,6 +2,7 @@
 #define MANTID_DATAHANDLING_LOADNEXUSMONITORS_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace DataHandling {
@@ -40,8 +41,12 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 File change history is stored at: <https://github.com/mantidproject/mantid>
 */
-class DLLExport LoadNexusMonitors : public API::Algorithm {
+class DLLExport LoadNexusMonitors : public API::Algorithm,
+                                    public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  LoadNexusMonitors() { this->useAlgorithm("LoadNexusMonitors", 2); }
+
   /// Algorithm's name for identification overriding a virtual method
   const std::string name() const override { return "LoadNexusMonitors"; }
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
index fe074f92b010928a700deef80939c5736594e9c8..39157303eacc33ed780b58057992f4ad4703d680 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadNexusMonitors2.h
@@ -5,8 +5,8 @@
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidGeometry/IDTypes.h"
 #include <boost/scoped_array.hpp>
-#include <nexus/NeXusException.hpp>
 #include <nexus/NeXusFile.hpp>
+#include <nexus/NeXusException.hpp>
 
 namespace Mantid {
 namespace DataHandling {
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h b/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h
index 51293d676c6db9d1f2a1b80b873528030fcbfc6a..6d2faee4ef1d5cdc776e808e015554a003efb367 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadRawHelper.h
@@ -5,12 +5,10 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataHandling/ISISRunLogs.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include <boost/scoped_ptr.hpp>
 #include <climits>
 
-//----------------------------------------------------------------------
-// Forward declaration
-//----------------------------------------------------------------------
 class ISISRAW;
 class ISISRAW2;
 
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
index 473849ed9418813a9debc5999d0b31332b9925c2..3908d455a4337d8b1dfca2c637b94689857d9ed0 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpice2D.h
@@ -1,9 +1,7 @@
 #ifndef MANTID_DATAHANDLING_LoadSpice2D_H
 #define MANTID_DATAHANDLING_LoadSpice2D_H
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
+#include "MantidKernel/DateAndTime.h"
 #include "MantidAPI/IFileLoader.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataHandling/XmlHandler.h"
@@ -12,8 +10,6 @@
 #include <vector>
 #include <utility>
 
-//----------------------------------------------------------------------
-
 namespace Poco {
 namespace XML {
 class Element;
diff --git a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
index 2ca875626e948a142d4c34efaaea40519c43973e..ea13c77dc54ee1c22a7ff1b516503051e6121ad9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/LoadSpiceXML2DDet.h
@@ -133,6 +133,9 @@ private:
   std::string m_idfFileName;
   /// User specified wave length
   double m_userSpecifiedWaveLength;
+  /// shift of detector on X and Y direction
+  double m_detXShift;
+  double m_detYShift;
 };
 
 } // namespace DataHandling
diff --git a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
index ad4e8fa3a1ef783075c3a895bca1b4216a6a89a2..4c070da9edc4d139633ecc9e8cd16f6220f3f9a9 100644
--- a/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
+++ b/Framework/DataHandling/inc/MantidDataHandling/SaveISISNexus.h
@@ -1,16 +1,12 @@
 #ifndef MANTID_DATAHANDLING_SAVEISISNEXUS_H_
 #define MANTID_DATAHANDLING_SAVEISISNEXUS_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
 
+#include <nexus/NeXusFile.hpp>
+
 #include <climits>
 
-//----------------------------------------------------------------------
-// Forward declaration
-//----------------------------------------------------------------------
 class ISISRAW2;
 
 namespace Mantid {
diff --git a/Framework/DataHandling/src/AsciiPointBase.cpp b/Framework/DataHandling/src/AsciiPointBase.cpp
index 839c5b667b34765843ea29e5d0e80c8031cc3ccb..9d919bd677c1d96d1fac3aefdd986a708bbbff4b 100644
--- a/Framework/DataHandling/src/AsciiPointBase.cpp
+++ b/Framework/DataHandling/src/AsciiPointBase.cpp
@@ -4,14 +4,12 @@ SaveILLCosmosAscii and SaveANSTOAscii export-only Acii-based save formats. It is
 based on a python script by Maximilian Skoda, written for the ISIS Reflectometry
 GUI
 */
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/AsciiPointBase.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/ListValidator.h"
 
+#include <boost/lexical_cast.hpp>
 #include <boost/tokenizer.hpp>
 #include <boost/regex.hpp>
 #include <boost/make_shared.hpp>
diff --git a/Framework/DataHandling/src/CheckMantidVersion.cpp b/Framework/DataHandling/src/CheckMantidVersion.cpp
index 4f9929c48c692a132382cb2ad569c68f1688ade4..c5b1c4b9e581409a29b0839f70d0a8b728e38b5f 100644
--- a/Framework/DataHandling/src/CheckMantidVersion.cpp
+++ b/Framework/DataHandling/src/CheckMantidVersion.cpp
@@ -1,4 +1,5 @@
 #include "MantidDataHandling/CheckMantidVersion.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/GitHubApiHelper.h"
 #include "MantidKernel/MantidVersion.h"
 #include "MantidKernel/Strings.h"
@@ -22,8 +23,6 @@ using Mantid::API::WorkspaceProperty;
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(CheckMantidVersion)
 
-//----------------------------------------------------------------------------------------------
-
 /// Algorithms name for identification. @see Algorithm::name
 const std::string CheckMantidVersion::name() const {
   return "CheckMantidVersion";
@@ -43,7 +42,6 @@ const std::string CheckMantidVersion::summary() const {
          "the Github API";
 }
 
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void CheckMantidVersion::init() {
@@ -54,7 +52,6 @@ void CheckMantidVersion::init() {
                   Direction::Output);
 }
 
-//----------------------------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void CheckMantidVersion::exec() {
@@ -248,4 +245,4 @@ std::string CheckMantidVersion::getCurrentVersion() const {
 }
 
 } // namespace DataHandling
-} // namespace Mantid
\ No newline at end of file
+} // namespace Mantid
diff --git a/Framework/DataHandling/src/CreateSimulationWorkspace.cpp b/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
index 909b236e5004127f1a37ff8aef8ce2f52609ed12..fd3f4a929521219bcce38a07e143844eccda3a1a 100644
--- a/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
+++ b/Framework/DataHandling/src/CreateSimulationWorkspace.cpp
@@ -21,6 +21,8 @@
 
 #include <Poco/File.h>
 
+#include <boost/algorithm/string/predicate.hpp>
+
 namespace {
 
 struct StartAndEndTime {
diff --git a/Framework/DataHandling/src/DefineGaugeVolume.cpp b/Framework/DataHandling/src/DefineGaugeVolume.cpp
index da5db7396bd9c29d52e97e356cff9e2c350e7bcd..7c08358fa9d0858850eb3cb2156b59ca1557fb58 100644
--- a/Framework/DataHandling/src/DefineGaugeVolume.cpp
+++ b/Framework/DataHandling/src/DefineGaugeVolume.cpp
@@ -1,4 +1,5 @@
 #include "MantidDataHandling/DefineGaugeVolume.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
diff --git a/Framework/DataHandling/src/FindDetectorsInShape.cpp b/Framework/DataHandling/src/FindDetectorsInShape.cpp
index d22b07a6ac0a44b8c7d7c65d4752533b10e0428e..d78da0877a69b6732f5e79a039204bc711e64af2 100644
--- a/Framework/DataHandling/src/FindDetectorsInShape.cpp
+++ b/Framework/DataHandling/src/FindDetectorsInShape.cpp
@@ -1,7 +1,5 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/FindDetectorsInShape.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/DataHandling/src/GroupDetectors2.cpp b/Framework/DataHandling/src/GroupDetectors2.cpp
index b103f74b55a6120f4d88d380aa5fcd71099f18ef..e25a1f80153320eaac9fb3efaf9ef1d05083928b 100644
--- a/Framework/DataHandling/src/GroupDetectors2.cpp
+++ b/Framework/DataHandling/src/GroupDetectors2.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/GroupDetectors2.h"
 
 #include "MantidAPI/CommonBinsValidator.h"
@@ -15,7 +12,10 @@
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/ListValidator.h"
 
+#include <boost/algorithm/string/classification.hpp>
 #include <boost/regex.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 namespace Mantid {
 namespace DataHandling {
@@ -925,6 +925,7 @@ size_t GroupDetectors2::formGroups(API::MatrixWorkspace_const_sptr inputWS,
   // Only used for averaging behaviour. We may have a 1:1 map where a Divide
   // would be waste as it would be just dividing by 1
   bool requireDivide(false);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (storage_map::const_iterator it = m_GroupWsInds.begin();
        it != m_GroupWsInds.end(); ++it) {
     // This is the grouped spectrum
@@ -942,7 +943,6 @@ size_t GroupDetectors2::formGroups(API::MatrixWorkspace_const_sptr inputWS,
 
     // Keep track of number of detectors required for masking
     size_t nonMaskedSpectra(0);
-    const auto &spectrumInfo = inputWS->spectrumInfo();
 
     for (auto originalWI : it->second) {
       // detectors to add to firstSpecNum
@@ -1021,6 +1021,7 @@ GroupDetectors2::formGroupsEvent(DataObjects::EventWorkspace_const_sptr inputWS,
   // Only used for averaging behaviour. We may have a 1:1 map where a Divide
   // would be waste as it would be just dividing by 1
   bool requireDivide(false);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (storage_map::const_iterator it = m_GroupWsInds.begin();
        it != m_GroupWsInds.end(); ++it) {
     // This is the grouped spectrum
@@ -1044,12 +1045,7 @@ GroupDetectors2::formGroupsEvent(DataObjects::EventWorkspace_const_sptr inputWS,
 
       // detectors to add to the output spectrum
       outEL.addDetectorIDs(fromEL.getDetectorIDs());
-      try {
-        Geometry::IDetector_const_sptr det = inputWS->getDetector(originalWI);
-        if (!det->isMasked())
-          ++nonMaskedSpectra;
-      } catch (Exception::NotFoundError &) {
-        // If a detector cannot be found, it cannot be masked
+      if (!isMaskedDetector(spectrumInfo, originalWI)) {
         ++nonMaskedSpectra;
       }
     }
diff --git a/Framework/DataHandling/src/ImggAggregateWavelengths.cpp b/Framework/DataHandling/src/ImggAggregateWavelengths.cpp
index 3b8d5948b6ab3a4abed85ba54449baa7b25199ec..3d85d49a9507ade101a4295f1397d84201313ef4 100644
--- a/Framework/DataHandling/src/ImggAggregateWavelengths.cpp
+++ b/Framework/DataHandling/src/ImggAggregateWavelengths.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/make_unique.h"
@@ -9,6 +10,7 @@
 #include "MantidKernel/StringTokenizer.h"
 
 #include <fstream>
+#include <iomanip>
 
 #include <Poco/File.h>
 #include <Poco/DirectoryIterator.h>
@@ -558,7 +560,7 @@ ImggAggregateWavelengths::findInputSubdirs(const Poco::Path &path) {
 
     // there is at least one image file: take just the first level directory
     if (it->isFile()) {
-      const std::string name = it.name();
+      const std::string &name = it.name();
       const std::string extShort = name.substr(name.size() - 3);
       const std::string extLong = name.substr(name.size() - 4);
 
@@ -690,7 +692,7 @@ ImggAggregateWavelengths::buildOutputSubdirNamesFromUniformBands(
   std::vector<std::string> outputSubdirs;
   // get number of available images from first effective subdirectory
   std::vector<Poco::Path> images;
-  for (size_t idx = 0; idx < inputSubDirs.size() && 0 == images.size(); ++idx) {
+  for (size_t idx = 0; idx < inputSubDirs.size() && images.empty(); ++idx) {
     images = findInputImages(inputSubDirs[idx]);
   }
   auto outRanges = splitSizeIntoRanges(images.size(), bands);
diff --git a/Framework/DataHandling/src/Load.cpp b/Framework/DataHandling/src/Load.cpp
index aca068f9239cdd630ec367dcc7ebc106a6f4f066..67a48fdfd187c47c0fc89b2153238408a6693553 100644
--- a/Framework/DataHandling/src/Load.cpp
+++ b/Framework/DataHandling/src/Load.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/Load.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/FileProperty.h"
@@ -10,6 +7,7 @@
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidAPI/MultipleFileProperty.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/FacilityInfo.h"
 
@@ -245,7 +243,7 @@ void Load::declareLoaderProperties(const API::IAlgorithm_sptr &loader) {
   // THIS IS A COPY as the properties are mutated as we move through them
   const std::vector<Property *> existingProps = this->getProperties();
   for (auto existingProp : existingProps) {
-    const std::string name = existingProp->name();
+    const std::string &name = existingProp->name();
     // Wipe all properties except the Load native ones
     if (m_baseProps.find(name) == m_baseProps.end()) {
       this->removeProperty(name);
diff --git a/Framework/DataHandling/src/LoadBBY.cpp b/Framework/DataHandling/src/LoadBBY.cpp
index b109d4d6ba4a8a61ff3d597a7462df6c6a61c352..0bbe0669658b8aa6cf1640048eb1343c99d324a7 100644
--- a/Framework/DataHandling/src/LoadBBY.cpp
+++ b/Framework/DataHandling/src/LoadBBY.cpp
@@ -2,6 +2,7 @@
 #include <cstdio>
 
 #include "MantidDataHandling/LoadBBY.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/LogManager.h"
diff --git a/Framework/DataHandling/src/LoadCalFile.cpp b/Framework/DataHandling/src/LoadCalFile.cpp
index d41a66d19ec8f33529041582b59cb2345856cb97..804decf8b19cb974817c2fc411fe8c18d215bc08 100644
--- a/Framework/DataHandling/src/LoadCalFile.cpp
+++ b/Framework/DataHandling/src/LoadCalFile.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/Run.h"
 #include "MantidDataHandling/LoadCalFile.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
@@ -259,6 +260,9 @@ void LoadCalFile::readCalFile(const std::string &calFileName,
   int n, udet, select, group;
   double n_d, udet_d, offset, select_d, group_d;
 
+  SpectrumInfo *maskSpectrumInfo{nullptr};
+  if (maskWS)
+    maskSpectrumInfo = &maskWS->mutableSpectrumInfo();
   std::string str;
   while (getline(grFile, str)) {
     if (str.empty() || str[0] == '#')
@@ -309,7 +313,8 @@ void LoadCalFile::readCalFile(const std::string &calFileName,
 
         if (select <= 0) {
           // Not selected, then mask this detector
-          maskWS->maskWorkspaceIndex(wi);
+          maskWS->getSpectrum(wi).clearData();
+          maskSpectrumInfo->setMasked(wi, true);
           maskWS->mutableY(wi)[0] = 1.0;
         } else {
           // Selected, set the value to be 0
diff --git a/Framework/DataHandling/src/LoadDetectorInfo.cpp b/Framework/DataHandling/src/LoadDetectorInfo.cpp
index b337e626417afefdfe58308f2779c25f8c3c7164..e72c71f5ef986185b2d534d586bd63e2eabbfbc1 100644
--- a/Framework/DataHandling/src/LoadDetectorInfo.cpp
+++ b/Framework/DataHandling/src/LoadDetectorInfo.cpp
@@ -6,6 +6,7 @@
 #include "LoadRaw/isisraw2.h"
 
 #include <boost/algorithm/string/compare.hpp>
+#include <boost/algorithm/string/predicate.hpp>
 #include <nexus/NeXusFile.hpp>
 #include <Poco/Path.h>
 
diff --git a/Framework/DataHandling/src/LoadDetectorsGroupingFile.cpp b/Framework/DataHandling/src/LoadDetectorsGroupingFile.cpp
index 7abb622b8349d2a4cdcdfcb64cded3bd28bd75c6..e7805f49f3f681fea60acf2855ce21d49d6f9f7b 100644
--- a/Framework/DataHandling/src/LoadDetectorsGroupingFile.cpp
+++ b/Framework/DataHandling/src/LoadDetectorsGroupingFile.cpp
@@ -511,9 +511,9 @@ void LoadGroupXMLFile::parseXML() {
         std::string val_value =
             this->getAttributeValueByName(pNode, "val", valfound);
         std::string finalvalue;
-        if (valfound && value.size() > 0)
+        if (valfound && !value.empty())
           finalvalue = value + ", " + val_value;
-        else if (value.size() == 0)
+        else if (value.empty())
           finalvalue = val_value;
         else
           finalvalue = value;
@@ -534,9 +534,9 @@ void LoadGroupXMLFile::parseXML() {
         std::string val_value =
             this->getAttributeValueByName(pNode, "val", valfound);
         std::string finalvalue;
-        if (valfound && value.size() > 0)
+        if (valfound && !value.empty())
           finalvalue = value + ", " + val_value;
-        else if (value.size() == 0)
+        else if (value.empty())
           finalvalue = val_value;
         else
           finalvalue = value;
@@ -559,9 +559,9 @@ void LoadGroupXMLFile::parseXML() {
         std::string val_value =
             this->getAttributeValueByName(pNode, "val", valfound);
         std::string finalvalue;
-        if (valfound && value.size() > 0)
+        if (valfound && !value.empty())
           finalvalue = value + ", " + val_value;
-        else if (value.size() == 0)
+        else if (value.empty())
           finalvalue = val_value;
         else
           finalvalue = value;
diff --git a/Framework/DataHandling/src/LoadDspacemap.cpp b/Framework/DataHandling/src/LoadDspacemap.cpp
index 39519b4353896309f31dd4d6480db944e3f14344..e71748e59cc187f6705d320ae0478ac18688aa2d 100644
--- a/Framework/DataHandling/src/LoadDspacemap.cpp
+++ b/Framework/DataHandling/src/LoadDspacemap.cpp
@@ -121,8 +121,8 @@ void LoadDspacemap::CalculateOffsetsFromDSpacemapFile(
 
     // Compute the factor
     double offset = 0.0;
-    double factor = Instrument::calcConversion(l1, beamline, beamline_norm,
-                                               samplePos, det, offset);
+    double factor = Instrument::calcConversion(
+        l1, beamline, beamline_norm, samplePos, det->getPos(), offset);
     offset = dspace[detectorID] / factor - 1.0;
     // Save in the map
     try {
diff --git a/Framework/DataHandling/src/LoadEventNexus.cpp b/Framework/DataHandling/src/LoadEventNexus.cpp
index eb8d8b5b87486c429a91d1537401502391a9f899..1be3de61847257593af8a83867a5ed15e69052ac 100644
--- a/Framework/DataHandling/src/LoadEventNexus.cpp
+++ b/Framework/DataHandling/src/LoadEventNexus.cpp
@@ -9,6 +9,7 @@
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -864,7 +865,7 @@ void LoadEventNexus::init() {
 */
 void LoadEventNexus::setTopEntryName() {
   std::string nxentryProperty = getProperty("NXentryName");
-  if (nxentryProperty.size() > 0) {
+  if (!nxentryProperty.empty()) {
     m_top_entry_name = nxentryProperty;
     return;
   }
@@ -1940,8 +1941,7 @@ void LoadEventNexus::runLoadMonitorsAsEvents(API::Progress *const prog) {
           << "data workspace.\n";
       try {
         auto to = m_ws->getSingleHeldWorkspace();
-        auto from = dataWS;
-        copyLogs(from, to);
+        copyLogs(dataWS, to);
         g_log.information() << "Log data copied.\n";
       } catch (std::runtime_error &) {
         g_log.error()
diff --git a/Framework/DataHandling/src/LoadFITS.cpp b/Framework/DataHandling/src/LoadFITS.cpp
index a941b625844d24513927862af2808607bd8c7576..f8ed6a97fd9dbdfe18e10a69c48d537a53898f60 100644
--- a/Framework/DataHandling/src/LoadFITS.cpp
+++ b/Framework/DataHandling/src/LoadFITS.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadFITS.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/BoundedValidator.h"
@@ -472,19 +473,17 @@ void LoadFITS::doLoadFiles(const std::vector<std::string> &paths,
 
   // Create a group for these new workspaces, if the group already exists, add
   // to it.
-  std::string groupName = outWSName;
-
   size_t fileNumberInGroup = 0;
   WorkspaceGroup_sptr wsGroup;
 
-  if (!AnalysisDataService::Instance().doesExist(groupName)) {
-    wsGroup = WorkspaceGroup_sptr(new WorkspaceGroup());
-    wsGroup->setTitle(groupName);
+  if (!AnalysisDataService::Instance().doesExist(outWSName)) {
+    wsGroup = boost::make_shared<WorkspaceGroup>();
+    wsGroup->setTitle(outWSName);
   } else {
     // Get the name of the latest file in group to start numbering from
-    if (AnalysisDataService::Instance().doesExist(groupName))
+    if (AnalysisDataService::Instance().doesExist(outWSName))
       wsGroup =
-          AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(groupName);
+          AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(outWSName);
 
     std::string latestName = wsGroup->getNames().back();
     // Set next file number
@@ -860,10 +859,10 @@ void LoadFITS::readDataToWorkspace(const FITSInfo &fileInfo, double cmpp,
 
   PARALLEL_FOR_NO_WSP_CHECK()
   for (int i = 0; i < static_cast<int>(nrows); ++i) {
-    auto &dataX = ws->dataX(i);
-    auto &dataY = ws->dataY(i);
-    auto &dataE = ws->dataE(i);
-    std::fill(dataX.begin(), dataX.end(), static_cast<double>(i) * cmpp);
+    auto &xVals = ws->mutableX(i);
+    auto &yVals = ws->mutableY(i);
+    auto &eVals = ws->mutableE(i);
+    xVals = static_cast<double>(i) * cmpp;
 
     for (size_t j = 0; j < ncols; ++j) {
       // Map from 2D->1D index
@@ -890,8 +889,8 @@ void LoadFITS::readDataToWorkspace(const FITSInfo &fileInfo, double cmpp,
       }
 
       val = fileInfo.scale * val - fileInfo.offset;
-      dataY[j] = val;
-      dataE[j] = sqrt(val);
+      yVals[j] = val;
+      eVals[j] = sqrt(val);
     }
   }
 }
diff --git a/Framework/DataHandling/src/LoadFullprofResolution.cpp b/Framework/DataHandling/src/LoadFullprofResolution.cpp
index 223b9c06882d84d3db837bc5703c7f96e2d9b10d..e2e3e810de2117f6d97e7ce20333189a4ff0edb5 100644
--- a/Framework/DataHandling/src/LoadFullprofResolution.cpp
+++ b/Framework/DataHandling/src/LoadFullprofResolution.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/InstrumentDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
@@ -17,6 +18,7 @@
 #include <Poco/DOM/DOMWriter.h>
 #include <Poco/DOM/Element.h>
 #include <Poco/DOM/AutoPtr.h>
+#include <Poco/XML/XMLWriter.h>
 
 #include <fstream>
 
@@ -252,7 +254,7 @@ void LoadFullprofResolution::loadFile(string filename, vector<string> &lines) {
 
       // display the line we gathered:
       boost::algorithm::trim(line);
-      if (line.size() > 0)
+      if (!line.empty())
         lines.push_back(line);
     }
 
@@ -651,7 +653,7 @@ void LoadFullprofResolution::parseBankLine(string line, double &cwl,
                     << "'" << v[i] << "'\n";
       string candidate = v[i];
       boost::algorithm::trim(candidate);
-      if (candidate.size() > 0) {
+      if (!candidate.empty()) {
         cwl = atof(candidate.c_str());
         break;
       }
diff --git a/Framework/DataHandling/src/LoadGSASInstrumentFile.cpp b/Framework/DataHandling/src/LoadGSASInstrumentFile.cpp
index 74e8997744b26a8be6c2d3fb3d3108c872fd7066..239ea187ff49047152f221f36e53d16d585be4f9 100644
--- a/Framework/DataHandling/src/LoadGSASInstrumentFile.cpp
+++ b/Framework/DataHandling/src/LoadGSASInstrumentFile.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/InstrumentDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
@@ -225,7 +226,7 @@ void LoadGSASInstrumentFile::loadFile(string filename, vector<string> &lines) {
 
       // display the line we gathered:
       boost::algorithm::trim(line);
-      if (line.size() > 0)
+      if (!line.empty())
         lines.push_back(line);
     }
 
diff --git a/Framework/DataHandling/src/LoadGSS.cpp b/Framework/DataHandling/src/LoadGSS.cpp
index c0568da204a1044a4ba54258e5b060fb7af40106..cca84ae9e67e0ccd021055d506dcb499f8daf465 100644
--- a/Framework/DataHandling/src/LoadGSS.cpp
+++ b/Framework/DataHandling/src/LoadGSS.cpp
@@ -22,6 +22,7 @@
 
 using namespace Mantid::DataHandling;
 using namespace Mantid::API;
+using namespace Mantid::HistogramData;
 using namespace Mantid::Kernel;
 
 namespace Mantid {
@@ -113,7 +114,10 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
   std::vector<int> detectorIDs;
 
   // Vectors to store data
-  std::vector<std::vector<double>> gsasDataX, gsasDataY, gsasDataE;
+  std::vector<HistogramData::BinEdges> gsasDataX;
+  std::vector<HistogramData::Counts> gsasDataY;
+  std::vector<HistogramData::CountStandardDeviations> gsasDataE;
+
   std::vector<double> vecX, vecY, vecE;
 
   // progress
@@ -251,16 +255,12 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
       // Line start with Bank including file format, X0 information and etc.
       isOutOfHead = true;
 
-      // If there is, Save the previous to array and initialze new MantiVec for
+      // If there is, Save the previous to array and initialize new MantiVec for
       // (X, Y, E)
       if (!vecX.empty()) {
-        std::vector<double> storeX = vecX;
-        std::vector<double> storeY = vecY;
-        std::vector<double> storeE = vecE;
-
-        gsasDataX.push_back(storeX);
-        gsasDataY.push_back(storeY);
-        gsasDataE.push_back(storeE);
+        gsasDataX.emplace_back(std::move(vecX));
+        gsasDataY.emplace_back(std::move(vecY));
+        gsasDataE.emplace_back(std::move(vecE));
         vecX.clear();
         vecY.clear();
         vecE.clear();
@@ -387,20 +387,26 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
       }
 
       // store read in data (x, y, e) to vector
-      vecX.push_back(xValue);
-      vecY.push_back(yValue);
-      vecE.push_back(eValue);
+      vecX.push_back(std::move(xValue));
+      vecY.push_back(std::move(yValue));
+      vecE.push_back(std::move(eValue));
     } // Date Line
     else {
       g_log.warning() << "Line not defined: " << currentLine << '\n';
     }
-  } // ENDWHILE of readling all lines
+  } // ENDWHILE of reading all lines
+
+  // Get the sizes before using std::move
+  int nHist(static_cast<int>(gsasDataX.size()));
+  int xWidth(static_cast<int>(vecX.size()));
+  int yWidth(static_cast<int>(vecY.size()));
 
   // Push the vectors (X, Y, E) of the last bank to gsasData
   if (!vecX.empty()) { // Put final spectra into data
-    gsasDataX.push_back(vecX);
-    gsasDataY.push_back(vecY);
-    gsasDataE.push_back(vecE);
+    gsasDataX.emplace_back(std::move(vecX));
+    gsasDataY.emplace_back(std::move(vecY));
+    gsasDataE.emplace_back(std::move(vecE));
+    ++nHist;
   }
   input.close();
 
@@ -409,9 +415,6 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
   //********************************************************************************************
 
   // Create workspace & GSS Files data is always in TOF
-  int nHist(static_cast<int>(gsasDataX.size()));
-  int xWidth(static_cast<int>(vecX.size()));
-  int yWidth(static_cast<int>(vecY.size()));
 
   MatrixWorkspace_sptr outputWorkspace =
       boost::dynamic_pointer_cast<MatrixWorkspace>(
@@ -425,7 +428,7 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
   else
     outputWorkspace->setTitle(slogTitle);
 
-  // put data from MatidVec's into outputWorkspace
+  // put data from constructed histograms into outputWorkspace
   if (detectorIDs.size() != static_cast<size_t>(nHist)) {
     // File error is found
     std::ostringstream mess("");
@@ -436,9 +439,9 @@ API::MatrixWorkspace_sptr LoadGSS::loadGSASFile(const std::string &filename,
 
   for (int i = 0; i < nHist; ++i) {
     // Move data across
-    outputWorkspace->dataX(i) = gsasDataX[i];
-    outputWorkspace->dataY(i) = gsasDataY[i];
-    outputWorkspace->dataE(i) = gsasDataE[i];
+    outputWorkspace->setHistogram(
+        i, BinEdges(std::move(gsasDataX[i])), Counts(std::move(gsasDataY[i])),
+        CountStandardDeviations(std::move(gsasDataE[i])));
 
     // Reset spectrum number if
     if (useBankAsSpectrum) {
@@ -506,7 +509,6 @@ void LoadGSS::createInstrumentGeometry(
   // Create a new instrument and set its name
   Geometry::Instrument_sptr instrument(
       new Geometry::Instrument(instrumentname));
-  workspace->setInstrument(instrument);
 
   // Add dummy source and samplepos to instrument
   Geometry::ObjComponent *samplepos =
@@ -554,6 +556,7 @@ void LoadGSS::createInstrumentGeometry(
     instrument->markAsDetector(detector);
 
   } // ENDFOR (i: spectrum)
+  workspace->setInstrument(instrument);
 }
 
 } // namespace
diff --git a/Framework/DataHandling/src/LoadHelper.cpp b/Framework/DataHandling/src/LoadHelper.cpp
index fc456db0ed416202d873c91264a429d94464ca8c..2b7a2dfe2fd6be5694e4432e8e19f4f1293518b0 100644
--- a/Framework/DataHandling/src/LoadHelper.cpp
+++ b/Framework/DataHandling/src/LoadHelper.cpp
@@ -6,6 +6,7 @@
 
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument/ComponentHelper.h"
+#include "MantidKernel/PhysicalConstants.h"
 
 #include <nexus/napi.h>
 
diff --git a/Framework/DataHandling/src/LoadIDFFromNexus.cpp b/Framework/DataHandling/src/LoadIDFFromNexus.cpp
index 1cfc6d102c0e1e583a973f316f16be829f9be6be..ab9e7484b49498243529d3d619b5460b246b2643 100644
--- a/Framework/DataHandling/src/LoadIDFFromNexus.cpp
+++ b/Framework/DataHandling/src/LoadIDFFromNexus.cpp
@@ -1,11 +1,9 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/LoadIDFFromNexus.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidKernel/Strings.h"
 
 #include <Poco/DOM/Document.h>
 #include <Poco/DOM/DOMParser.h>
diff --git a/Framework/DataHandling/src/LoadILLIndirect.cpp b/Framework/DataHandling/src/LoadILLIndirect.cpp
index b651948cf026ca70b4465d649ff4f7defec2ecdb..48582c21f1b8918ca7912845059c3278c0e13900 100644
--- a/Framework/DataHandling/src/LoadILLIndirect.cpp
+++ b/Framework/DataHandling/src/LoadILLIndirect.cpp
@@ -4,12 +4,14 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidHistogramData/LinearGenerator.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidGeometry/Instrument/ComponentHelper.h"
 
 #include <boost/algorithm/string.hpp>
 
 #include <nexus/napi.h>
+#include <numeric>
 
 namespace Mantid {
 namespace DataHandling {
@@ -46,7 +48,7 @@ const std::string LoadILLIndirect::category() const {
 //----------------------------------------------------------------------------------------------
 
 /**
-* Return the confidence with with this algorithm can load the file
+* Return the confidence 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
@@ -239,10 +241,6 @@ void LoadILLIndirect::loadDataIntoTheWorkSpace(
   // load the counts from the file into memory
   dataSD.load();
 
-  // Assign calculated bins to first X axis
-  ////  m_localWorkspace->dataX(0).assign(detectorTofBins.begin(),
-  /// detectorTofBins.end());
-
   size_t spec = 0;
   size_t nb_monitors = monitorsData.size();
   size_t nb_SD_detectors = dataSD.dim0();
@@ -250,22 +248,17 @@ void LoadILLIndirect::loadDataIntoTheWorkSpace(
   Progress progress(this, 0, 1, m_numberOfTubes * m_numberOfPixelsPerTube +
                                     nb_monitors + nb_SD_detectors);
 
-  // Assign fake values to first X axis <<to be completed>>
-  for (size_t i = 0; i <= m_numberOfChannels; ++i) {
-    m_localWorkspace->dataX(0)[i] = double(i);
-  }
+  // Assign fake values to first X axis
+  const HistogramData::BinEdges histoBinEdges(
+      m_numberOfChannels + 1, HistogramData::LinearGenerator(1.0, 1.0));
 
   // First, Monitor
   for (size_t im = 0; im < nb_monitors; im++) {
 
-    if (im > 0) {
-      m_localWorkspace->dataX(im) = m_localWorkspace->readX(0);
-    }
-
-    // Assign Y
     int *monitor_p = monitorsData[im].data();
-    m_localWorkspace->dataY(im)
-        .assign(monitor_p, monitor_p + m_numberOfChannels);
+    const HistogramData::Counts histoCounts(monitor_p,
+                                            monitor_p + m_numberOfChannels);
+    m_localWorkspace->setHistogram(im, histoBinEdges, std::move(histoCounts));
 
     progress.report();
   }
@@ -274,18 +267,12 @@ void LoadILLIndirect::loadDataIntoTheWorkSpace(
   for (size_t i = 0; i < m_numberOfTubes; ++i) {
     for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) {
 
-      // just copy the time binning axis to every spectra
-      m_localWorkspace->dataX(spec + nb_monitors) = m_localWorkspace->readX(0);
-
       // Assign Y
       int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0);
-      m_localWorkspace->dataY(spec + nb_monitors)
-          .assign(data_p, data_p + m_numberOfChannels);
-
-      // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(spec + nb_monitors);
-      std::transform(data_p, data_p + m_numberOfChannels, E.begin(),
-                     LoadILLIndirect::calculateError);
+      const HistogramData::Counts histoCounts(data_p,
+                                              data_p + m_numberOfChannels);
+      m_localWorkspace->setHistogram((spec + nb_monitors), histoBinEdges,
+                                     std::move(histoCounts));
 
       ++spec;
       progress.report();
@@ -295,15 +282,16 @@ void LoadILLIndirect::loadDataIntoTheWorkSpace(
   // Then add Simple Detector (SD)
   for (int i = 0; i < dataSD.dim0(); ++i) {
 
-    // just copy again the time binning axis to every spectra
-    m_localWorkspace->dataX(spec + nb_monitors + i) =
-        m_localWorkspace->readX(0);
-
     // Assign Y
     int *dataSD_p = &dataSD(i, 0, 0);
-    m_localWorkspace->dataY(spec + nb_monitors + i)
-        .assign(dataSD_p, dataSD_p + m_numberOfChannels);
-
+    const HistogramData::Counts histoCounts(dataSD_p,
+                                            dataSD_p + m_numberOfChannels);
+    const HistogramData::CountStandardDeviations histoErrors(m_numberOfChannels,
+                                                             0.0);
+
+    m_localWorkspace->setHistogram((spec + nb_monitors + i), histoBinEdges,
+                                   std::move(histoCounts),
+                                   std::move(histoErrors));
     progress.report();
   }
 
diff --git a/Framework/DataHandling/src/LoadILLReflectometry.cpp b/Framework/DataHandling/src/LoadILLReflectometry.cpp
index 764704f022cec96af309759aaadb7a01f5ff4ee0..b41993fa16422c1b0ae64f52e68b3c16179834c2 100644
--- a/Framework/DataHandling/src/LoadILLReflectometry.cpp
+++ b/Framework/DataHandling/src/LoadILLReflectometry.cpp
@@ -52,7 +52,7 @@ const std::string LoadILLReflectometry::category() const {
 }
 
 /**
- * Return the confidence with with this algorithm can load the file
+ * Return the confidence 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
@@ -285,10 +285,6 @@ void LoadILLReflectometry::loadDataIntoTheWorkSpace(
   // load the counts from the file into memory
   data.load();
 
-  // Assign calculated bins to first X axis
-  ////  m_localWorkspace->dataX(0).assign(detectorTofBins.begin(),
-  /// detectorTofBins.end());
-
   size_t spec = 0;
   size_t nb_monitors = monitorsData.size();
 
@@ -368,50 +364,44 @@ void LoadILLReflectometry::loadDataIntoTheWorkSpace(
   }
   g_log.debug() << "t_TOF2: " << t_TOF2 << '\n';
 
+  std::vector<double> tofVals;
+  tofVals.reserve(m_localWorkspace->x(0).size());
+
   // 2) Compute tof values
   for (size_t timechannelnumber = 0; timechannelnumber <= m_numberOfChannels;
        ++timechannelnumber) {
     double t_TOF1 =
         (static_cast<int>(timechannelnumber) + 0.5) * m_channelWidth +
         tof_delay;
-    m_localWorkspace->dataX(0)[timechannelnumber] = t_TOF1 + t_TOF2;
+    tofVals.push_back(t_TOF1 + t_TOF2);
   }
 
+  HistogramData::BinEdges binEdges(tofVals);
+
   // Load monitors
   for (size_t im = 0; im < nb_monitors; im++) {
-    if (im > 0) {
-      m_localWorkspace->dataX(im) = m_localWorkspace->readX(0);
-    }
-
-    // Assign Y
     int *monitor_p = monitorsData[im].data();
-    m_localWorkspace->dataY(im)
-        .assign(monitor_p, monitor_p + m_numberOfChannels);
+    const HistogramData::Counts histoCounts(monitor_p,
+                                            monitor_p + m_numberOfChannels);
+    const HistogramData::CountStandardDeviations histoBlankError(
+        monitorsData[im].size(), 0.0);
+    m_localWorkspace->setHistogram(im, binEdges, std::move(histoCounts),
+                                   std::move(histoBlankError));
 
     progress.report();
   }
 
-  // Then Tubes
   for (size_t i = 0; i < m_numberOfTubes; ++i) {
     for (size_t j = 0; j < m_numberOfPixelsPerTube; ++j) {
-
-      // just copy the time binning axis to every spectra
-      m_localWorkspace->dataX(spec + nb_monitors) = m_localWorkspace->readX(0);
-
-      //// Assign Y
       int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0);
-      m_localWorkspace->dataY(spec + nb_monitors)
-          .assign(data_p, data_p + m_numberOfChannels);
-
-      // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(spec + nb_monitors);
-      std::transform(data_p, data_p + m_numberOfChannels, E.begin(),
-                     LoadHelper::calculateStandardError);
-
+      const HistogramData::Counts histoCounts(data_p,
+                                              data_p + m_numberOfChannels);
+      m_localWorkspace->setHistogram((spec + nb_monitors), binEdges,
+                                     std::move(histoCounts));
       ++spec;
       progress.report();
     }
-  } // for m_numberOfTubes
+  }
 
 } // LoadILLIndirect::loadDataIntoTheWorkSpace
 
diff --git a/Framework/DataHandling/src/LoadILLSANS.cpp b/Framework/DataHandling/src/LoadILLSANS.cpp
index d3f787b171862dacf76e1cd38f8c36269851ddc8..5f9ff358995cfde3a6d706a2c74e19898078b53c 100644
--- a/Framework/DataHandling/src/LoadILLSANS.cpp
+++ b/Framework/DataHandling/src/LoadILLSANS.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidHistogramData/LinearGenerator.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidKernel/UnitFactory.h"
@@ -252,18 +253,12 @@ LoadILLSANS::loadDataIntoWorkspaceFromMonitors(NeXus::NXEntry &firstEntry,
       std::vector<double> positionsBinning;
       positionsBinning.reserve(vectorSize);
 
-      for (size_t i = 0; i < vectorSize; i++)
-        positionsBinning.push_back(static_cast<double>(i));
+      const HistogramData::BinEdges histoBinEdges(
+          vectorSize, HistogramData::LinearGenerator(0.0, 1.0));
+      const HistogramData::Counts histoCounts(data(), data() + data.dim2());
 
-      // Assign X
-      m_localWorkspace->dataX(firstIndex)
-          .assign(positionsBinning.begin(), positionsBinning.end());
-      // Assign Y
-      m_localWorkspace->dataY(firstIndex).assign(data(), data() + data.dim2());
-      // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(firstIndex);
-      std::transform(data(), data() + data.dim2(), E.begin(),
-                     LoadHelper::calculateStandardError);
+      m_localWorkspace->setHistogram(firstIndex, std::move(histoBinEdges),
+                                     std::move(histoCounts));
 
       // Add average monitor counts to a property:
       double averageMonitorCounts =
@@ -298,30 +293,20 @@ size_t LoadILLSANS::loadDataIntoWorkspaceFromHorizontalTubes(
                 << "First bin = " << timeBinning[0] << '\n';
 
   // Workaround to get the number of tubes / pixels
-  size_t numberOfTubes = data.dim1();
-  size_t numberOfPixelsPerTube = data.dim0();
+  const size_t numberOfTubes = data.dim1();
+  const size_t numberOfPixelsPerTube = data.dim0();
 
   Progress progress(this, 0, 1, data.dim0() * data.dim1());
 
-  m_localWorkspace->dataX(firstIndex)
-      .assign(timeBinning.begin(), timeBinning.end());
-
   size_t spec = firstIndex;
-  for (size_t i = 0; i < numberOfTubes; ++i) { // iterate tubes
-    for (size_t j = 0; j < numberOfPixelsPerTube;
-         ++j) { // iterate pixels in the tube 256
-      if (spec > firstIndex) {
-        // just copy the time binning axis to every spectra
-        m_localWorkspace->dataX(spec) = m_localWorkspace->readX(firstIndex);
-      }
-      // Assign Y
-      int *data_p = &data(static_cast<int>(j), static_cast<int>(i), 0);
-      m_localWorkspace->dataY(spec).assign(data_p, data_p + data.dim2());
 
-      // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(spec);
-      std::transform(data_p, data_p + data.dim2(), E.begin(),
-                     LoadHelper::calculateStandardError);
+  const HistogramData::BinEdges binEdges(timeBinning);
+
+  for (size_t i = 0; i < numberOfTubes; ++i) {
+    for (size_t j = 0; j < numberOfPixelsPerTube; ++j) {
+      int *data_p = &data(static_cast<int>(j), static_cast<int>(i), 0);
+      const HistogramData::Counts histoCounts(data_p, data_p + data.dim2());
+      m_localWorkspace->setHistogram(spec, binEdges, std::move(histoCounts));
 
       ++spec;
       progress.report();
@@ -350,31 +335,20 @@ size_t LoadILLSANS::loadDataIntoWorkspaceFromVerticalTubes(
                 << "First bin = " << timeBinning[0] << '\n';
 
   // Workaround to get the number of tubes / pixels
-  size_t numberOfTubes = data.dim0();
-  size_t numberOfPixelsPerTube = data.dim1();
+  const size_t numberOfTubes = data.dim0();
+  const size_t numberOfPixelsPerTube = data.dim1();
 
   Progress progress(this, 0, 1, data.dim0() * data.dim1());
 
-  m_localWorkspace->dataX(firstIndex)
-      .assign(timeBinning.begin(), timeBinning.end());
-
+  const HistogramData::BinEdges binEdges(timeBinning);
   size_t spec = firstIndex;
-  for (size_t i = 0; i < numberOfTubes; ++i) { // iterate tubes
-    for (size_t j = 0; j < numberOfPixelsPerTube;
-         ++j) { // iterate pixels in the tube 256
-      if (spec > firstIndex) {
-        // just copy the time binning axis to every spectra
-        m_localWorkspace->dataX(spec) = m_localWorkspace->readX(firstIndex);
-      }
-      // Assign Y
-      int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0);
-      m_localWorkspace->dataY(spec).assign(data_p, data_p + data.dim2());
 
-      // Assign Error
-      MantidVec &E = m_localWorkspace->dataE(spec);
-      std::transform(data_p, data_p + data.dim2(), E.begin(),
-                     LoadHelper::calculateStandardError);
+  for (size_t i = 0; i < numberOfTubes; ++i) {
+    for (size_t j = 0; j < numberOfPixelsPerTube; ++j) {
+      int *data_p = &data(static_cast<int>(i), static_cast<int>(j), 0);
+      const HistogramData::Counts histoCounts(data_p, data_p + data.dim2());
 
+      m_localWorkspace->setHistogram(spec, binEdges, std::move(histoCounts));
       ++spec;
       progress.report();
     }
@@ -570,14 +544,6 @@ void LoadILLSANS::loadMetaData(const NeXus::NXEntry &entry,
     m_defaultBinning[0] = wavelength - wavelengthRes * wavelength * 0.01 / 2;
     m_defaultBinning[1] = wavelength + wavelengthRes * wavelength * 0.01 / 2;
   }
-
-  // Put the detector distances:
-  //	std::string detectorPath(instrumentNamePath + "/detector");
-  //	// Just for Sample - RearDetector
-  //	double sampleDetectorDistance =
-  // m_loader.getDoubleFromNexusPath(entry,detectorPath + "/det2_calc");
-  //	runDetails.addProperty("sample_detector_distance",
-  // sampleDetectorDistance);
 }
 
 /**
@@ -597,15 +563,12 @@ std::pair<double, double> LoadILLSANS::calculateQMaxQMin() {
   for (std::size_t i = 0; i < nHist; ++i) {
     Geometry::IDetector_const_sptr det = m_localWorkspace->getDetector(i);
     if (!det->isMonitor()) {
-      const MantidVec &lambdaBinning = m_localWorkspace->readX(i);
+      const auto &lambdaBinning = m_localWorkspace->x(i);
       Kernel::V3D detPos = det->getPos();
       double r, theta, phi;
       detPos.getSpherical(r, theta, phi);
       double v1 = calculateQ(*(lambdaBinning.begin()), theta);
       double v2 = calculateQ(*(lambdaBinning.end() - 1), theta);
-      // std::cout << "i=" << i << " theta="<<theta << " lambda_i=" <<
-      // *(lambdaBinning.begin()) << " lambda_f=" << *(lambdaBinning.end()-1) <<
-      // " v1=" << v1 << " v2=" << v2 << '\n';
       if (i == 0) {
         min = v1;
         max = v1;
diff --git a/Framework/DataHandling/src/LoadILLTOF.cpp b/Framework/DataHandling/src/LoadILLTOF.cpp
index f4206f45d1f72738fa10094dcd9965e126dec556..e30d0242da34e178a05e53d61c706cdb26140a9e 100644
--- a/Framework/DataHandling/src/LoadILLTOF.cpp
+++ b/Framework/DataHandling/src/LoadILLTOF.cpp
@@ -1,6 +1,3 @@
-//---------------------------------------------------
-// Includes
-//---------------------------------------------------
 #include "MantidDataHandling/LoadILLTOF.h"
 
 #include "MantidAPI/Axis.h"
@@ -11,6 +8,8 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/UnitFactory.h"
 
+#include <boost/algorithm/string/predicate.hpp>
+
 namespace Mantid {
 namespace DataHandling {
 
@@ -21,10 +20,6 @@ using namespace HistogramData;
 
 DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadILLTOF)
 
-//---------------------------------------------------
-// Private member functions
-//---------------------------------------------------
-
 /**
  * Return the confidence with with this algorithm can load the file
  * @param descriptor A descriptor for the file
diff --git a/Framework/DataHandling/src/LoadInstrument.cpp b/Framework/DataHandling/src/LoadInstrument.cpp
index 62d8c1a9269838bdc7002780b97177b273a5ef8f..3353a6d762e21731dd96ae0fcecf8476a4d438cd 100644
--- a/Framework/DataHandling/src/LoadInstrument.cpp
+++ b/Framework/DataHandling/src/LoadInstrument.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/InstrumentDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -11,6 +8,7 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/OptionalBool.h"
 #include "MantidKernel/MandatoryValidator.h"
+#include "MantidKernel/Strings.h"
 
 #include <Poco/DOM/DOMParser.h>
 #include <Poco/DOM/Document.h>
@@ -270,7 +268,7 @@ std::string LoadInstrument::getFullPathParamIDF(std::string directoryName) {
   directoryPath.makeDirectory();
   // Remove the path from the filename
   Poco::Path filePath(m_filename);
-  std::string instrumentFile = filePath.getFileName();
+  const std::string &instrumentFile = filePath.getFileName();
 
   // First check whether there is a parameter file whose name is the same as the
   // IDF file,
diff --git a/Framework/DataHandling/src/LoadInstrumentFromRaw.cpp b/Framework/DataHandling/src/LoadInstrumentFromRaw.cpp
index 72e363e248c09da685244ca13a30f388efcee8ef..6d75d43314794c25d770365b1fb30c1398f5077e 100644
--- a/Framework/DataHandling/src/LoadInstrumentFromRaw.cpp
+++ b/Framework/DataHandling/src/LoadInstrumentFromRaw.cpp
@@ -67,7 +67,6 @@ void LoadInstrumentFromRaw::exec() {
 
   // Create a new Instrument with the right name and add it to the workspace
   Geometry::Instrument_sptr instrument(new Instrument(iraw.i_inst));
-  localWorkspace->setInstrument(instrument);
 
   // Add dummy source and samplepos to instrument
   // The L2 and 2-theta values from Raw file assumed to be relative to sample
@@ -146,6 +145,7 @@ void LoadInstrumentFromRaw::exec() {
     prog += (0.5 / numDetector);
     progress(prog);
   }
+  localWorkspace->setInstrument(instrument);
 
   std::vector<detid_t> monitorList = instrument->getMonitors();
   setProperty("MonitorList", monitorList);
diff --git a/Framework/DataHandling/src/LoadIsawDetCal.cpp b/Framework/DataHandling/src/LoadIsawDetCal.cpp
index 696b8feb3c7861d50178f1f6ea38e40ad3979121..cdd51572f8afcaf56665255b62bdcbd96e3e55b4 100644
--- a/Framework/DataHandling/src/LoadIsawDetCal.cpp
+++ b/Framework/DataHandling/src/LoadIsawDetCal.cpp
@@ -13,9 +13,11 @@
 #include "MantidGeometry/Instrument/ObjCompAssembly.h"
 #include "MantidGeometry/Instrument/ComponentHelper.h"
 
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/V3D.h"
 
 #include <Poco/File.h>
+#include <boost/algorithm/string/trim.hpp>
 #include <sstream>
 #include <iostream>
 #include <fstream>
diff --git a/Framework/DataHandling/src/LoadLog.cpp b/Framework/DataHandling/src/LoadLog.cpp
index 62a2025aa429f27917d783c779a82b9eb0f478be..96e1840d73f7309fd9c3e15b01b8495660373a34 100644
--- a/Framework/DataHandling/src/LoadLog.cpp
+++ b/Framework/DataHandling/src/LoadLog.cpp
@@ -357,7 +357,7 @@ bool LoadLog::LoadSNSText() {
   // Go back to start
   inLogFile.seekg(0);
   while (Mantid::Kernel::Strings::extractToEOL(inLogFile, aLine)) {
-    if (aLine.size() == 0)
+    if (aLine.empty())
       break;
 
     if (SNSTextFormatColumns(aLine, cols)) {
diff --git a/Framework/DataHandling/src/LoadMLZ.cpp b/Framework/DataHandling/src/LoadMLZ.cpp
index cead7cb1e2dea549cb67ab19d832cf333abebef2..8a574397602efdf3dba67348a6e7c497a057ee54 100644
--- a/Framework/DataHandling/src/LoadMLZ.cpp
+++ b/Framework/DataHandling/src/LoadMLZ.cpp
@@ -1,9 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/LoadMLZ.h"
 #include "MantidDataHandling/LoadHelper.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Progress.h"
@@ -18,7 +16,6 @@
 #include <cmath>
 #include <limits>
 #include <vector>
-//-----------------------------------------------------------------------
 
 namespace Mantid {
 namespace DataHandling {
@@ -30,7 +27,6 @@ using namespace NeXus;
 // Register the algorithm into the AlgorithmFactory
 DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMLZ)
 
-//----------------------------------------------------------------------------------------------
 /** Constructor
  */
 LoadMLZ::LoadMLZ()
@@ -40,7 +36,6 @@ LoadMLZ::LoadMLZ()
       m_monitorCounts{0}, m_chopper_speed{0.0}, m_chopper_ratio{0}, m_l1{0.0},
       m_l2{0.0}, m_t1{0.0}, m_supportedInstruments{"TOFTOF", "DNS"} {}
 
-//---------------------------------------------------------------------------
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string LoadMLZ::name() const { return "LoadMLZ"; }
 
@@ -50,7 +45,6 @@ int LoadMLZ::version() const { return 1; }
 /// Algorithm's category for identification. @see Algorithm::category
 const std::string LoadMLZ::category() const { return "DataHandling\\Nexus"; }
 
-//---------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void LoadMLZ::init() {
@@ -64,7 +58,6 @@ void LoadMLZ::init() {
                   "The name to use for the output workspace");
 }
 
-//---------------------------------------------------------------------------
 /** Execute the algorithm.
  */
 void LoadMLZ::exec() {
@@ -126,34 +119,23 @@ void LoadMLZ::maskDetectors(NeXus::NXEntry &entry) {
   g_log.debug() << "Number of masked detectors: " << masked_detectors.size()
                 << '\n';
 
+  auto &detInfo = m_localWorkspace->mutableDetectorInfo();
+  std::vector<size_t> indicesToMask;
   for (auto masked_detector : masked_detectors) {
     g_log.debug() << "List of masked detectors: ";
     g_log.debug() << masked_detector;
     g_log.debug() << ", ";
+    try {
+      indicesToMask.push_back(detInfo.indexOf(masked_detector));
+    } catch (std::out_of_range &) {
+      g_log.warning() << "Invalid detector ID " << masked_detector
+                      << ". Found while running LoadMLZ\n";
+    }
   }
   g_log.debug() << '\n';
 
-  // Need to get hold of the parameter map
-  Geometry::ParameterMap &pmap = m_localWorkspace->instrumentParameters();
-
-  // If explicitly given a list of detectors to mask, just mark those.
-  // Otherwise, mask all detectors pointing to the requested spectra in
-  // indexlist loop below
-  std::vector<detid_t>::const_iterator it;
-  Geometry::Instrument_const_sptr instrument =
-      m_localWorkspace->getInstrument();
-  if (!masked_detectors.empty()) {
-    for (it = masked_detectors.begin(); it != masked_detectors.end(); ++it) {
-      try {
-        if (const Geometry::ComponentID det =
-                instrument->getDetector(*it)->getComponentID()) {
-          pmap.addBool(det, "masked", true);
-        }
-      } catch (Kernel::Exception::NotFoundError &e) {
-        g_log.warning() << e.what() << " Found while running MaskDetectors\n";
-      }
-    }
-  }
+  for (const auto index : indicesToMask)
+    detInfo.setMasked(index, true);
 }
 
 /**
diff --git a/Framework/DataHandling/src/LoadMask.cpp b/Framework/DataHandling/src/LoadMask.cpp
index 36f8d26745769b678c90e77f34c21fd8803becdc..8710f55f6a3dfdad3249ea64ecdcc4449e1494ad 100644
--- a/Framework/DataHandling/src/LoadMask.cpp
+++ b/Framework/DataHandling/src/LoadMask.cpp
@@ -164,7 +164,7 @@ void parseISISStringToVector(const std::string &ins,
       temps.insert(temps.begin() + 1, "-");
       splitstrings.erase(splitstrings.begin() + index);
       for (size_t ic = 0; ic < 3; ic++) {
-        if (temps[ic].size() > 0) {
+        if (!temps[ic].empty()) {
           splitstrings.insert(splitstrings.begin() + index, temps[ic]);
           index++;
         }
diff --git a/Framework/DataHandling/src/LoadMuonNexus1.cpp b/Framework/DataHandling/src/LoadMuonNexus1.cpp
index f8c27b233e3cf921c3fe0356a4f964674e2fd3e6..025dbdac56ea1825da749c34d52b5b80dbcd2cb2 100644
--- a/Framework/DataHandling/src/LoadMuonNexus1.cpp
+++ b/Framework/DataHandling/src/LoadMuonNexus1.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/ISISRunLogs.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/Workspace2D.h"
diff --git a/Framework/DataHandling/src/LoadMuonNexus2.cpp b/Framework/DataHandling/src/LoadMuonNexus2.cpp
index 16a8a2b54779676f01244345ca992cbc2475d697..f50c4f38723f7434adfd079adb418ba5a97328b1 100644
--- a/Framework/DataHandling/src/LoadMuonNexus2.cpp
+++ b/Framework/DataHandling/src/LoadMuonNexus2.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/UnitFactory.h"
diff --git a/Framework/DataHandling/src/LoadNXSPE.cpp b/Framework/DataHandling/src/LoadNXSPE.cpp
index 0dc488aa121cccc62cd513f2c6deacaa85d8f278..fb9ed5a8cabd553c6e8cd8d7f7b3cabfc2a5e17d 100644
--- a/Framework/DataHandling/src/LoadNXSPE.cpp
+++ b/Framework/DataHandling/src/LoadNXSPE.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
 #include <nexus/NeXusFile.hpp>
@@ -264,7 +265,6 @@ void LoadNXSPE::exec() {
   // generate instrument
   Geometry::Instrument_sptr instrument(new Geometry::Instrument(
       instrument_name.empty() ? "NXSPE" : instrument_name));
-  outputWS->setInstrument(instrument);
 
   Geometry::ObjComponent *source = new Geometry::ObjComponent("source");
   source->setPos(0.0, 0.0, -10.);
@@ -293,10 +293,11 @@ void LoadNXSPE::exec() {
     instrument->add(det);
     instrument->markAsDetector(det);
   }
+  outputWS->setInstrument(instrument);
 
-  Geometry::ParameterMap &pmap = outputWS->instrumentParameters();
   std::vector<double>::iterator itdata = data.begin(), iterror = error.begin(),
                                 itdataend, iterrorend;
+  auto &spectrumInfo = outputWS->mutableSpectrumInfo();
   API::Progress prog = API::Progress(this, 0.0, 0.9, numSpectra);
   for (std::size_t i = 0; i < numSpectra; ++i) {
     itdataend = itdata + numBins;
@@ -304,9 +305,7 @@ void LoadNXSPE::exec() {
     outputWS->dataX(i) = energies;
     if ((!std::isfinite(*itdata)) || (*itdata <= -1e10)) // masked bin
     {
-      outputWS->dataY(i) = std::vector<double>(numBins, 0);
-      outputWS->dataE(i) = std::vector<double>(numBins, 0);
-      pmap.addBool(outputWS->getDetector(i)->getComponentID(), "masked", true);
+      spectrumInfo.setMasked(i, true);
     } else {
       outputWS->dataY(i) = std::vector<double>(itdata, itdataend);
       outputWS->dataE(i) = std::vector<double>(iterror, iterrorend);
diff --git a/Framework/DataHandling/src/LoadNXcanSAS.cpp b/Framework/DataHandling/src/LoadNXcanSAS.cpp
index 993bb6f8a0ac9ff2c25f7531249e9b99174e30fe..dbfabd47a5a98d333f06bad186a48d14ebe1c9b7 100644
--- a/Framework/DataHandling/src/LoadNXcanSAS.cpp
+++ b/Framework/DataHandling/src/LoadNXcanSAS.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/Progress.h"
 #include "MantidAPI/RegisterFileLoader.h"
@@ -131,7 +132,7 @@ std::string extractIdfFileOnCurrentSystem(std::string idf) {
 
   // Get the specified IDF name
   Poco::Path path(idf);
-  auto fileName = path.getFileName();
+  const auto &fileName = path.getFileName();
 
   // Compare against all available IDFs
   const std::vector<std::string> &directoryNames =
diff --git a/Framework/DataHandling/src/LoadNexusLogs.cpp b/Framework/DataHandling/src/LoadNexusLogs.cpp
index 60b408c9c49bacfcb32778b1ae424cfaeab13f85..de96a1ff276c58a213a5045e50161b56ceff4265 100644
--- a/Framework/DataHandling/src/LoadNexusLogs.cpp
+++ b/Framework/DataHandling/src/LoadNexusLogs.cpp
@@ -69,6 +69,29 @@ bool loadAndApplyMeasurementInfo(::NeXus::File *const file,
   }
   return successfullyApplied;
 }
+
+/**
+* @brief loadAndApplyRunTitle
+* @param file : Nexus::File pointer
+* @param workspace : Pointer to the workspace to set logs on
+* @return True only if reading and execution successful.
+*/
+bool loadAndApplyRunTitle(::NeXus::File *const file,
+                          API::MatrixWorkspace &workspace) {
+
+  bool successfullyApplied = false;
+  try {
+    file->openData("title");
+    workspace.mutableRun().addLogData(
+        new Mantid::Kernel::PropertyWithValue<std::string>("run_title",
+                                                           file->getStrData()));
+    file->closeData();
+    successfullyApplied = true;
+  } catch (::NeXus::Exception &) {
+    successfullyApplied = false;
+  }
+  return successfullyApplied;
+}
 }
 
 /// Empty default constructor
@@ -175,6 +198,8 @@ void LoadNexusLogs::exec() {
 
   // If there's measurement information, load that info as logs.
   loadAndApplyMeasurementInfo(&file, *workspace);
+  // If there's title information, load that info as logs.
+  loadAndApplyRunTitle(&file, *workspace);
 
   // Freddie Akeroyd 12/10/2011
   // current ISIS implementation contains an additional indirection between
diff --git a/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Framework/DataHandling/src/LoadNexusProcessed.cpp
index 518fbd67fe6c3146e8a52e8b7eba99fef50caa62..f11fa22ae7cf40cefe2c7b55fedf0664492a9765 100644
--- a/Framework/DataHandling/src/LoadNexusProcessed.cpp
+++ b/Framework/DataHandling/src/LoadNexusProcessed.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataHandling/LoadNexusProcessed.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/RebinnedOutput.h"
diff --git a/Framework/DataHandling/src/LoadPDFgetNFile.cpp b/Framework/DataHandling/src/LoadPDFgetNFile.cpp
index 524ea6463cbd0fc8e8cca0d73a7bcbf2c80d4f11..ffaca18040e9a7a37ed8a0f2cdfcf8a4d35bde4e 100644
--- a/Framework/DataHandling/src/LoadPDFgetNFile.cpp
+++ b/Framework/DataHandling/src/LoadPDFgetNFile.cpp
@@ -8,6 +8,7 @@
 #include "MantidKernel/UnitFactory.h"
 
 #include <fstream>
+#include <iomanip>
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/trim.hpp>
diff --git a/Framework/DataHandling/src/LoadParameterFile.cpp b/Framework/DataHandling/src/LoadParameterFile.cpp
index 9075c9c841656477dea6db6f45be7f5ead260a71..bf8c811d7705ca062596bdfb1524249868b9c953 100644
--- a/Framework/DataHandling/src/LoadParameterFile.cpp
+++ b/Framework/DataHandling/src/LoadParameterFile.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/LoadParameterFile.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -8,6 +5,7 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Component.h"
 #include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
+#include "MantidKernel/ConfigService.h"
 
 #include <Poco/DOM/DOMParser.h>
 #include <Poco/DOM/Document.h>
diff --git a/Framework/DataHandling/src/LoadQKK.cpp b/Framework/DataHandling/src/LoadQKK.cpp
index 88a220ba15d822f908a0dd48d1b9a92a3ed8911a..7463ec3de93cec7ba96fe7566593e4d3923e599a 100644
--- a/Framework/DataHandling/src/LoadQKK.cpp
+++ b/Framework/DataHandling/src/LoadQKK.cpp
@@ -132,7 +132,6 @@ void LoadQKK::exec() {
   std::string instrumentname = "QUOKKA";
   Geometry::Instrument_sptr instrument(
       new Geometry::Instrument(instrumentname));
-  outputWorkspace->setInstrument(instrument);
 
   // Add dummy source and samplepos to instrument
 
@@ -210,6 +209,8 @@ void LoadQKK::exec() {
   // Position the detector so the z axis goes through its centre
   bank->setPos(-width / 2, -height / 2, 0);
 
+  outputWorkspace->setInstrument(instrument);
+
   // Set the workspace title
   outputWorkspace->setTitle(entry.getString("experiment/title"));
   // Attach the created workspace to the OutputWorkspace property. The workspace
diff --git a/Framework/DataHandling/src/LoadRawHelper.cpp b/Framework/DataHandling/src/LoadRawHelper.cpp
index 9aa49ef2b95339cbc2ca1385dcc1b65fb28bb500..b1ce18e6b2f4b0322ca983a12deaaa0609a378df 100644
--- a/Framework/DataHandling/src/LoadRawHelper.cpp
+++ b/Framework/DataHandling/src/LoadRawHelper.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ArrayProperty.h"
diff --git a/Framework/DataHandling/src/LoadSassena.cpp b/Framework/DataHandling/src/LoadSassena.cpp
index 785472d7a1053611bc14d117794f021840c0b5d3..b00d3dff3e19c93df0c161c24f2f178b1f30a4c8 100644
--- a/Framework/DataHandling/src/LoadSassena.cpp
+++ b/Framework/DataHandling/src/LoadSassena.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/RegisterFileLoader.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Unit.h"
diff --git a/Framework/DataHandling/src/LoadSpiceAscii.cpp b/Framework/DataHandling/src/LoadSpiceAscii.cpp
index b627d8292452dab5ba1850ef6cd955ed9f5ac40e..d0124230bb1eca10da4c2b6cd6f8ebd94d7b4eaa 100644
--- a/Framework/DataHandling/src/LoadSpiceAscii.cpp
+++ b/Framework/DataHandling/src/LoadSpiceAscii.cpp
@@ -236,7 +236,7 @@ void LoadSpiceAscii::parseSPICEAscii(
     // Strip
     boost::trim(line);
     // skip for empyt line
-    if (line.size() == 0)
+    if (line.empty())
       continue;
 
     // Comment line for run information
diff --git a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
index 67dec0804108200b2f81732527c4fda3a2a470a7..a0381cf324144ee9596c980b18c3d9858f528fe9 100644
--- a/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
+++ b/Framework/DataHandling/src/LoadSpiceXML2DDet.cpp
@@ -68,24 +68,24 @@ void SpiceXMLNode::setParameters(const std::string &nodetype,
   }
 
   // unit
-  if (nodeunit.size() > 0) {
+  if (!nodeunit.empty()) {
     m_unit = nodeunit;
   }
 
   // description
-  if (nodedescription.size() > 0)
+  if (!nodedescription.empty())
     m_description = nodedescription;
 }
 
 /** Check whether XML has unit set
  */
-bool SpiceXMLNode::hasUnit() const { return (m_unit.size() > 0); }
+bool SpiceXMLNode::hasUnit() const { return (!m_unit.empty()); }
 
 /** Check whether XML node has value set
  * @brief SpiceXMLNode::hasValue
  * @return
  */
-bool SpiceXMLNode::hasValue() const { return (m_value.size() > 0); }
+bool SpiceXMLNode::hasValue() const { return (!m_value.empty()); }
 
 /** Is this node of string type?
  * @brief SpiceXMLNode::isString
@@ -201,15 +201,23 @@ void LoadSpiceXML2DDet::init() {
   declareProperty("PtNumber", 0,
                   "Pt. value for the row to get sample log from. ");
 
+  declareProperty("UserSpecifiedWaveLength", EMPTY_DBL(),
+                  "User can specify the wave length of the instrument if it is "
+                  "drifted from the designed value."
+                  "It happens often.");
+
   declareProperty(
       "ShiftedDetectorDistance", 0.,
       "Amount of shift of the distance between source and detector centre."
       "It is used to apply instrument calibration.");
 
-  declareProperty("UserSpecifiedWaveLength", EMPTY_DBL(),
-                  "User can specify the wave length of the instrument if it is "
-                  "drifted from the designed value."
-                  "It haappens often.");
+  declareProperty("DetectorCenterXShift", 0.0, "The amount of shift of "
+                                               "detector center along X "
+                                               "direction in the unit meter.");
+
+  declareProperty("DetectorCenterYShift", 0.0, "The amount of shift of "
+                                               "detector center along Y "
+                                               "direction in the unit meter.");
 }
 
 /** Process inputs arguments
@@ -232,7 +240,7 @@ void LoadSpiceXML2DDet::processInputs() {
 
   // Retreive sample environment data from SPICE scan table workspace
   std::string spicetablewsname = getPropertyValue("SpiceTableWorkspace");
-  if (spicetablewsname.size() > 0)
+  if (!spicetablewsname.empty())
     m_hasScanTable = true;
   else
     m_hasScanTable = false;
@@ -240,6 +248,9 @@ void LoadSpiceXML2DDet::processInputs() {
   m_ptNumber4Log = getProperty("PtNumber");
 
   m_userSpecifiedWaveLength = getProperty("UserSpecifiedWaveLength");
+
+  m_detXShift = getProperty("DetectorCenterXShift");
+  m_detYShift = getProperty("DetectorCenterYShift");
 }
 
 /** Set up sample logs especially 2theta and diffr for loading instrument
@@ -254,12 +265,13 @@ bool LoadSpiceXML2DDet::setupSampleLogs(API::MatrixWorkspace_sptr outws) {
     setupSampleLogFromSpiceTable(outws, spicetablews, m_ptNumber4Log);
   }
 
+  Kernel::DateAndTime anytime(1000);
+
   // Process 2theta
   bool return_true = true;
   if (!outws->run().hasProperty("2theta") &&
       outws->run().hasProperty("_2theta")) {
     // Set up 2theta if it is not set up yet
-    Kernel::DateAndTime anytime(1000);
     double logvalue =
         atof(outws->run().getProperty("_2theta")->value().c_str());
     TimeSeriesProperty<double> *newlogproperty =
@@ -275,8 +287,16 @@ bool LoadSpiceXML2DDet::setupSampleLogs(API::MatrixWorkspace_sptr outws) {
     return_true = false;
   }
 
+  // set up the caibrated detector center to beam
+  TimeSeriesProperty<double> *det_dx = new TimeSeriesProperty<double>("deltax");
+  det_dx->addValue(anytime, m_detXShift);
+  outws->mutableRun().addProperty(det_dx);
+
+  TimeSeriesProperty<double> *det_dy = new TimeSeriesProperty<double>("deltay");
+  det_dy->addValue(anytime, m_detYShift);
+  outws->mutableRun().addProperty(det_dy);
+
   // set up Sample-detetor distance calibration
-  Kernel::DateAndTime anytime(1000);
   double sampledetdistance = m_detSampleDistanceShift;
   TimeSeriesProperty<double> *distproperty =
       new TimeSeriesProperty<double>("diffr");
@@ -465,20 +485,20 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspace(
                     << "\n";
 
       // XML file records data in the order of column-major
-      size_t icol = 0;
+      size_t i_col = 0;
       for (size_t i = 0; i < vecLines.size(); ++i) {
         std::string &line = vecLines[i];
 
         // Skip empty line
-        if (line.size() == 0) {
+        if (line.empty()) {
           g_log.debug() << "\tFound empty Line at " << i << "\n";
           continue;
         }
 
         // Check whether it exceeds boundary
-        if (icol == numpixelx) {
+        if (i_col == numpixelx) {
           std::stringstream errss;
-          errss << "Number of non-empty rows (" << icol + 1
+          errss << "Number of non-empty rows (" << i_col + 1
                 << ") in detector data "
                 << "exceeds user defined geometry size " << numpixelx << ".";
           throw std::runtime_error(errss.str());
@@ -492,18 +512,20 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspace(
         // in Y direction
         if (veccounts.size() != numpixely) {
           std::stringstream errss;
-          errss << "Row " << icol << " contains " << veccounts.size()
+          errss << "Row " << i_col << " contains " << veccounts.size()
                 << " items other than " << numpixely
                 << " counts specified by user.";
           throw std::runtime_error(errss.str());
         }
 
-        // scan per row
+        // scan per column
         for (size_t j_row = 0; j_row < veccounts.size(); ++j_row) {
           double counts = atof(veccounts[j_row].c_str());
 
           if (loadinstrument) {
-            size_t wsindex = j_row * numpixely + icol;
+            // the detector ID and ws index are set up in column-major too!
+            size_t wsindex = i_col * numpixelx + j_row;
+            //  size_t wsindex = j_row * numpixely + icol;
             // size_t wsindex = icol * numpixelx + j_row;
             outws->dataX(wsindex)[0] = static_cast<double>(wsindex);
             outws->dataY(wsindex)[0] = counts;
@@ -513,12 +535,12 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspace(
               outws->dataE(wsindex)[0] = 1.0;
 
           } else {
-            outws->dataX(j_row)[icol] = static_cast<double>(j_row);
-            outws->dataY(j_row)[icol] = counts;
+            outws->dataX(j_row)[i_col] = static_cast<double>(j_row);
+            outws->dataY(j_row)[i_col] = counts;
             if (counts > 0)
-              outws->dataE(j_row)[icol] = sqrt(counts);
+              outws->dataE(j_row)[i_col] = sqrt(counts);
             else
-              outws->dataE(j_row)[icol] = 1.0;
+              outws->dataE(j_row)[i_col] = 1.0;
           }
 
           // record max count
@@ -527,8 +549,8 @@ MatrixWorkspace_sptr LoadSpiceXML2DDet::createMatrixWorkspace(
           }
         }
 
-        // Update irow
-        icol += 1;
+        // Update column index (i.e., column number)
+        i_col += 1;
       } // END-FOR (i-vec line)
 
       // Set flag
@@ -709,7 +731,7 @@ void LoadSpiceXML2DDet::loadInstrument(API::MatrixWorkspace_sptr matrixws,
   API::IAlgorithm_sptr loadinst = createChildAlgorithm("LoadInstrument");
   loadinst->initialize();
   loadinst->setProperty("Workspace", matrixws);
-  if (idffilename.size() > 0) {
+  if (!idffilename.empty()) {
     loadinst->setProperty("Filename", idffilename);
   } else
     loadinst->setProperty("InstrumentName", "HB3A");
diff --git a/Framework/DataHandling/src/LoadTOFRawNexus.cpp b/Framework/DataHandling/src/LoadTOFRawNexus.cpp
index 064855fe9d38f8c30bc7c2ee75a5918ac977e1fd..3acf135a655ca8fa4d04fa929fb91daa52d9fbdb 100644
--- a/Framework/DataHandling/src/LoadTOFRawNexus.cpp
+++ b/Framework/DataHandling/src/LoadTOFRawNexus.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/cow_ptr.h"
 #include <nexus/NeXusFile.hpp>
 
diff --git a/Framework/DataHandling/src/LoadVulcanCalFile.cpp b/Framework/DataHandling/src/LoadVulcanCalFile.cpp
index 7a66d7defd77d85ade19b6b82c064026dc9bdee3..5e9bfe7d1d85eeab8a49d924d950eaaffdc0ccb5 100644
--- a/Framework/DataHandling/src/LoadVulcanCalFile.cpp
+++ b/Framework/DataHandling/src/LoadVulcanCalFile.cpp
@@ -2,6 +2,7 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/Run.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
 #include "MantidDataObjects/MaskWorkspace.h"
@@ -255,7 +256,7 @@ void LoadVulcanCalFile::setupGroupingWorkspace() {
 void LoadVulcanCalFile::setupMaskWorkspace() {
 
   // Skip if bad pixel file is not given
-  if (m_badPixFilename.size() == 0)
+  if (m_badPixFilename.empty())
     return;
 
   // Open file
@@ -288,9 +289,11 @@ void LoadVulcanCalFile::setupMaskWorkspace() {
 
   // Mask workspace index
   std::ostringstream msg;
+  auto &spectrumInfo = m_maskWS->mutableSpectrumInfo();
   for (size_t i = 0; i < m_maskWS->getNumberHistograms(); ++i) {
     if (m_maskWS->readY(i)[0] > 0.5) {
-      m_maskWS->maskWorkspaceIndex(i);
+      m_maskWS->getSpectrum(i).clearData();
+      spectrumInfo.setMasked(i, true);
       m_maskWS->dataY(i)[0] = 1.0;
       msg << "Spectrum " << i << " is masked. DataY = " << m_maskWS->readY(i)[0]
           << "\n";
@@ -628,6 +631,9 @@ void LoadVulcanCalFile::readCalFile(const std::string &calFileName,
   int n, udet, select, group;
   double n_d, udet_d, offset, select_d, group_d;
 
+  SpectrumInfo *maskSpectrumInfo{nullptr};
+  if (maskWS)
+    maskSpectrumInfo = &maskWS->mutableSpectrumInfo();
   std::string str;
   while (getline(grFile, str)) {
     if (str.empty() || str[0] == '#')
@@ -674,7 +680,8 @@ void LoadVulcanCalFile::readCalFile(const std::string &calFileName,
 
         if (select <= 0) {
           // Not selected, then mask this detector
-          maskWS->maskWorkspaceIndex(wi);
+          maskWS->getSpectrum(wi).clearData();
+          maskSpectrumInfo->setMasked(wi, true);
           maskWS->dataY(wi)[0] = 1.0;
         } else {
           // Selected, set the value to be 0
diff --git a/Framework/DataHandling/src/MaskDetectors.cpp b/Framework/DataHandling/src/MaskDetectors.cpp
index 87c9e673c5d3bb6bb29913e6334a70bafa68d786..2bfc5875cb1ac700ddc732a92c23c35c28312888 100644
--- a/Framework/DataHandling/src/MaskDetectors.cpp
+++ b/Framework/DataHandling/src/MaskDetectors.cpp
@@ -1,11 +1,10 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/MaskDetectors.h"
 
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/MaskWorkspace.h"
 
+#include "MantidAPI/DetectorInfo.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
@@ -211,10 +210,12 @@ void MaskDetectors::exec() {
   }
 
   // Get a reference to the spectra-detector map to get hold of detector ID's
+  auto &spectrumInfo = WS->mutableSpectrumInfo();
   double prog = 0.0;
-  std::vector<size_t>::const_iterator wit;
-  for (wit = indexList.begin(); wit != indexList.end(); ++wit) {
-    WS->maskWorkspaceIndex(*wit);
+  for (const auto i : indexList) {
+    WS->getSpectrum(i).clearData();
+    if (spectrumInfo.hasDetectors(i))
+      spectrumInfo.setMasked(i, true);
 
     // Progress
     prog += (1.0 / static_cast<int>(indexList.size()));
@@ -335,61 +336,39 @@ void MaskDetectors::execPeaks(PeaksWorkspace_sptr WS) {
     return;
   }
 
-  // Need to get hold of the parameter map and instrument
-  Geometry::ParameterMap &pmap = WS->instrumentParameters();
-  Instrument_const_sptr instrument = WS->getInstrument();
+  auto &detInfo = WS->mutableDetectorInfo();
+  std::vector<size_t> indicesToMask;
+  for (const auto &detID : detectorList) {
+    try {
+      indicesToMask.push_back(detInfo.indexOf(detID));
+    } catch (std::out_of_range &) {
+      g_log.warning() << "Invalid detector ID " << detID
+                      << ". Found while running MaskDetectors\n";
+    }
+  }
 
   // If we have a workspace that could contain masking,copy that in too
-
   if (prevMasking) {
     DataObjects::MaskWorkspace_sptr maskWS =
         boost::dynamic_pointer_cast<DataObjects::MaskWorkspace>(prevMasking);
     if (maskWS) {
-      const auto &maskPmap = maskWS->constInstrumentParameters();
-      Instrument_const_sptr maskInstrument = maskWS->getInstrument();
-      if (maskInstrument->getDetectorIDs().size() !=
-          WS->getInstrument()->getDetectorIDs().size()) {
+      const auto &maskDetInfo = maskWS->detectorInfo();
+      if (detInfo.size() != maskDetInfo.size()) {
         throw std::runtime_error(
             "Size mismatch between input Workspace and MaskWorkspace");
       }
 
       g_log.debug() << "Extracting mask from MaskWorkspace (" << maskWS->name()
                     << ")\n";
-      std::vector<detid_t> detectorIDs = maskInstrument->getDetectorIDs();
-      std::vector<detid_t>::const_iterator it;
-      for (it = detectorIDs.begin(); it != detectorIDs.end(); ++it) {
-        try {
-          if (const Geometry::ComponentID det =
-                  maskInstrument->getDetector(*it)->getComponentID()) {
-            Geometry::Parameter_sptr maskedParam = maskPmap.get(det, "masked");
-            int detID =
-                static_cast<int>(maskInstrument->getDetector(*it)->getID());
-            if (maskedParam)
-              detectorList.push_back(detID);
-          }
-        } catch (Kernel::Exception::NotFoundError &e) {
-          g_log.warning() << e.what() << " Found while running MaskDetectors\n";
-        }
-      }
-    }
-  }
 
-  // If explicitly given a list of detectors to mask, just mark those.
-  // Otherwise, mask all detectors pointing to the requested spectra in
-  // index list loop below
-  std::vector<detid_t>::const_iterator it;
-  if (!detectorList.empty()) {
-    for (it = detectorList.begin(); it != detectorList.end(); ++it) {
-      try {
-        if (const Geometry::ComponentID det =
-                instrument->getDetector(*it)->getComponentID()) {
-          pmap.addBool(det, "masked", true);
-        }
-      } catch (Kernel::Exception::NotFoundError &e) {
-        g_log.warning() << e.what() << " Found while running MaskDetectors\n";
-      }
+      for (size_t i = 0; i < maskDetInfo.size(); ++i)
+        if (maskDetInfo.isMasked(i))
+          indicesToMask.push_back(i);
     }
   }
+
+  for (const auto index : indicesToMask)
+    detInfo.setMasked(index, true);
 }
 
 /* Convert a list of spectra numbers into the corresponding workspace indices.
@@ -450,33 +429,21 @@ void MaskDetectors::appendToIndexListFromWS(
   size_t endIndex = std::get<1>(range_info);
   bool range_constrained = std::get<2>(range_info);
 
+  const auto &spectrumInfo = sourceWS->spectrumInfo();
   if (range_constrained) {
     constrainIndexInRange(indexList, tmp_index, startIndex, endIndex);
 
     for (size_t i = startIndex; i <= endIndex; ++i) {
-      IDetector_const_sptr det;
-      try {
-        det = sourceWS->getDetector(i);
-      } catch (Exception::NotFoundError &) {
-        continue;
-      }
-      if (det->isMasked()) {
+      if (spectrumInfo.hasDetectors(i) && spectrumInfo.isMasked(i)) {
         tmp_index.push_back(i);
       }
     }
-
   } else {
     tmp_index.swap(indexList);
 
     endIndex = sourceWS->getNumberHistograms();
     for (size_t i = 0; i < endIndex; ++i) {
-      IDetector_const_sptr det;
-      try {
-        det = sourceWS->getDetector(i);
-      } catch (Exception::NotFoundError &) {
-        continue;
-      }
-      if (det->isMasked()) {
+      if (spectrumInfo.hasDetectors(i) && spectrumInfo.isMasked(i)) {
         tmp_index.push_back(i);
       }
     }
diff --git a/Framework/DataHandling/src/MergeLogs.cpp b/Framework/DataHandling/src/MergeLogs.cpp
index 6ec1beea82d23f2b02327fe10d09271554079ef4..b371ac206b0b5f977f42ab066075d46e7bf69bf0 100644
--- a/Framework/DataHandling/src/MergeLogs.cpp
+++ b/Framework/DataHandling/src/MergeLogs.cpp
@@ -39,7 +39,7 @@ void Merge2WorkspaceLogs::exec() {
   double logvalue2 = this->getProperty("LogValue2");
 
   // 2. Check
-  if (logname1.size() == 0 || logname2.size() == 0 || mlogname.size() == 0) {
+  if (logname1.empty() || logname2.empty() || mlogname.empty()) {
     g_log.error() << "One or more than one log name is not given!\n";
     throw std::invalid_argument("One or more than one log name is not give");
   }
diff --git a/Framework/DataHandling/src/ModifyDetectorDotDatFile.cpp b/Framework/DataHandling/src/ModifyDetectorDotDatFile.cpp
index 76c392072aebc8f0259735ed0b03c33a67569e43..9112b6a1abcf4f67847026bb3cd425d38e058cd2 100644
--- a/Framework/DataHandling/src/ModifyDetectorDotDatFile.cpp
+++ b/Framework/DataHandling/src/ModifyDetectorDotDatFile.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidDataHandling/ModifyDetectorDotDatFile.h"
@@ -111,6 +112,8 @@ void ModifyDetectorDotDatFile::exec() {
   int wCode = 6;   // Field width of Code
   int wAng = 12;   // Field width of angles
 
+  const auto &detectorInfo = ws->detectorInfo();
+
   // Read input file line by line, modify line as necessary and put line into
   // output file
   while (getline(in, str)) {
@@ -135,11 +138,9 @@ void ModifyDetectorDotDatFile::exec() {
       istr >> dump; // get phi
 
     if (code == 3) {
-      // This is detector will look for it in workspace and if found use its
-      // position
-      Geometry::IDetector_const_sptr det = ws->getDetectorByID(detID);
-      if (det) {
-        V3D pos = det->getPos();
+      try {
+        // indexOf throws for invalided detID
+        V3D pos = detectorInfo.position(detectorInfo.indexOf(detID));
         double l2;
         double theta;
         double phi;
@@ -159,7 +160,7 @@ void ModifyDetectorDotDatFile::exec() {
         std::string suffix = str.substr(width, std::string::npos);
         out << prefix << suffix << "\n";
         i++;
-      } else { // Detector not found, don't modify
+      } catch (std::out_of_range &) { // Detector not found, don't modify
         out << str << "\n";
       }
     } else {
diff --git a/Framework/DataHandling/src/PDLoadCharacterizations.cpp b/Framework/DataHandling/src/PDLoadCharacterizations.cpp
index 72052295aa88195008d256f41cc5eaddb3c20011..13a815e78fbc1091c5c62aaf6a42261cbd522e8f 100644
--- a/Framework/DataHandling/src/PDLoadCharacterizations.cpp
+++ b/Framework/DataHandling/src/PDLoadCharacterizations.cpp
@@ -12,6 +12,7 @@
 #include <boost/regex.hpp>
 #include <fstream>
 #include <set>
+#include <iostream>
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
diff --git a/Framework/DataHandling/src/PatchBBY.cpp b/Framework/DataHandling/src/PatchBBY.cpp
index 8f3887424421e9e0439ab89077cb6fc8bb5da805..5f177a346cec5cb4c761b7b18f7a3da3836786c1 100644
--- a/Framework/DataHandling/src/PatchBBY.cpp
+++ b/Framework/DataHandling/src/PatchBBY.cpp
@@ -301,7 +301,7 @@ void PatchBBY::exec() {
   }
 
   std::string logContentNew = logContentNewBuffer.str();
-  if (logContentNew.size() == 0)
+  if (logContentNew.empty())
     throw std::invalid_argument("nothing to patch");
 
   // merge log content
diff --git a/Framework/DataHandling/src/SaveAscii2.cpp b/Framework/DataHandling/src/SaveAscii2.cpp
index bd5d594f1bcb694298de522a5b93a8a4fccfd0c6..d2f0a5b002e7ea4566c2cb4a558da46dd021015f 100644
--- a/Framework/DataHandling/src/SaveAscii2.cpp
+++ b/Framework/DataHandling/src/SaveAscii2.cpp
@@ -129,7 +129,7 @@ void SaveAscii2::exec() {
   m_isCommonBins = m_ws->isCommonBins(); // checking for ragged workspace
   m_writeID = getProperty("WriteSpectrumID");
   std::string metaDataString = getPropertyValue("SpectrumMetaData");
-  if (metaDataString.size() != 0) {
+  if (!metaDataString.empty()) {
     m_metaData = stringListToVector(metaDataString);
     auto containsSpectrumNumber =
         findElementInUnorderedStringVector(m_metaData, "spectrumnumber");
@@ -256,7 +256,7 @@ void SaveAscii2::exec() {
     file << '\n';
   }
   // populate the meta data map
-  if (m_metaData.size() > 0) {
+  if (!m_metaData.empty()) {
     populateAllMetaData();
   }
   if (idx.empty()) {
diff --git a/Framework/DataHandling/src/SaveCSV.cpp b/Framework/DataHandling/src/SaveCSV.cpp
index 72edec787aad196f00e8a92ef108709c091b78ea..d4ec94836026b51923a0731bc7b5deb90494071a 100644
--- a/Framework/DataHandling/src/SaveCSV.cpp
+++ b/Framework/DataHandling/src/SaveCSV.cpp
@@ -19,14 +19,12 @@
  File change history is stored at: <https://github.com/mantidproject/mantid>
  */
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/SaveCSV.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidAPI/FileProperty.h"
 
 #include <fstream> // used to get ofstream
+#include <iomanip>
 
 /* @class SaveCSV
 
diff --git a/Framework/DataHandling/src/SaveCanSAS1D.cpp b/Framework/DataHandling/src/SaveCanSAS1D.cpp
index 04915a0708262b9a1dfde19c621cdbb8e376d6dd..c5dc7a65e31e70b042e2ebe274232f276b4c6a9c 100644
--- a/Framework/DataHandling/src/SaveCanSAS1D.cpp
+++ b/Framework/DataHandling/src/SaveCanSAS1D.cpp
@@ -1,6 +1,3 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/SaveCanSAS1D.h"
 
 #include "MantidAPI/FileProperty.h"
@@ -16,8 +13,9 @@
 #include "MantidKernel/ListValidator.h"
 
 #include <boost/shared_ptr.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
-//-----------------------------------------------------------------------------
 namespace {
 void encode(std::string &data) {
   std::string buffer;
diff --git a/Framework/DataHandling/src/SaveDiffFittingAscii.cpp b/Framework/DataHandling/src/SaveDiffFittingAscii.cpp
index f0422f8941b6ca02c2c9933e4668109cb8e90124..b9c75fdd93de58cf5a69a6dc2771e69ff1b57c40 100644
--- a/Framework/DataHandling/src/SaveDiffFittingAscii.cpp
+++ b/Framework/DataHandling/src/SaveDiffFittingAscii.cpp
@@ -1,10 +1,8 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/SaveDiffFittingAscii.h"
 
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/DataHandling/src/SaveDspacemap.cpp b/Framework/DataHandling/src/SaveDspacemap.cpp
index 34d8e59ddcfe26f2ea847221934b17984f681ce1..92352c01a35ae5051c37b8b0e2ca419bc389d8f5 100644
--- a/Framework/DataHandling/src/SaveDspacemap.cpp
+++ b/Framework/DataHandling/src/SaveDspacemap.cpp
@@ -86,9 +86,9 @@ void SaveDspacemap::CalculateDspaceFromCal(
     it = allDetectors.find(i);
     if (it != allDetectors.end()) {
       det = it->second;
-      factor =
-          Instrument::calcConversion(l1, beamline, beamline_norm, samplePos,
-                                     det, offsetsWS->getValue(i, 0.0));
+      factor = Instrument::calcConversion(l1, beamline, beamline_norm,
+                                          samplePos, det->getPos(),
+                                          offsetsWS->getValue(i, 0.0));
       // Factor of 10 between ISAW and Mantid
       factor *= 0.1;
       if (factor < 0)
diff --git a/Framework/DataHandling/src/SaveFITS.cpp b/Framework/DataHandling/src/SaveFITS.cpp
index aee2911ddbb392259e72612c4ece6e041c6cf7d3..2a8c458c504f2afb6155947486e4d7a96b21ca7a 100644
--- a/Framework/DataHandling/src/SaveFITS.cpp
+++ b/Framework/DataHandling/src/SaveFITS.cpp
@@ -7,6 +7,7 @@
 #include "MantidKernel/make_unique.h"
 
 #include <fstream>
+#include <iomanip>
 
 #include <boost/pointer_cast.hpp>
 
diff --git a/Framework/DataHandling/src/SaveFullprofResolution.cpp b/Framework/DataHandling/src/SaveFullprofResolution.cpp
index 39047131ac7bba532d80a25fc3023fcdb0b64708..0e508d349dcd80f9910cd4bd3486162629a7ee36 100644
--- a/Framework/DataHandling/src/SaveFullprofResolution.cpp
+++ b/Framework/DataHandling/src/SaveFullprofResolution.cpp
@@ -9,6 +9,7 @@
 #include <Poco/File.h>
 
 #include <fstream>
+#include <iomanip>
 
 using namespace Mantid;
 using namespace Mantid::API;
@@ -117,7 +118,7 @@ void SaveFullprofResolution::processProperties() {
 
   // Output file and operation
   m_outIrfFilename = getPropertyValue("OutputFilename");
-  if (m_outIrfFilename.size() == 0)
+  if (m_outIrfFilename.empty())
     throw runtime_error("Input file name invalid. ");
   m_append = getProperty("Append");
   if (m_append) {
diff --git a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
index 812f2b15f9a284ab468843dd9f69dd012bb21522..8c98bf1e5ee7453d4890e8c9bee6ab544966af5a 100644
--- a/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
+++ b/Framework/DataHandling/src/SaveGSASInstrumentFile.cpp
@@ -6,7 +6,11 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidAPI/TableRow.h"
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 #include <cstdio>
+#include <iomanip>
 
 using namespace Mantid;
 using namespace Mantid::API;
@@ -230,7 +234,7 @@ ChopperConfiguration::parseStringDbl(const string &instring) const {
 
   vector<double> vecdouble;
   for (auto &str : strs) {
-    if (str.size() > 0) {
+    if (!str.empty()) {
       double item = atof(str.c_str());
       vecdouble.push_back(item);
       // cout << "[C] |" << strs[i] << "|" << item << "\n";
@@ -253,7 +257,7 @@ ChopperConfiguration::parseStringUnsignedInt(const string &instring) const {
 
   vector<unsigned int> vecinteger;
   for (auto &str : strs) {
-    if (str.size() > 0) {
+    if (!str.empty()) {
       int item = atoi(str.c_str());
       if (item < 0) {
         throw runtime_error(
diff --git a/Framework/DataHandling/src/SaveGSS.cpp b/Framework/DataHandling/src/SaveGSS.cpp
index fa9c252fb9e2e7dc7b8e0bd1b9b5f747dfd3daaa..6935f94c8752268208314dc612dabe33e73b81cb 100644
--- a/Framework/DataHandling/src/SaveGSS.cpp
+++ b/Framework/DataHandling/src/SaveGSS.cpp
@@ -3,6 +3,8 @@
 #include "MantidAPI/AlgorithmHistory.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/TimeSeriesProperty.h"
@@ -160,8 +162,7 @@ void SaveGSS::exec() {
 
   // Check whether append or not
   if (!split) {
-    const std::string file(filename);
-    Poco::File fileobj(file);
+    Poco::File fileobj(filename);
     if (fileobj.exists() && !append) {
       // Non-append mode and will be overwritten
       g_log.warning() << "Target GSAS file " << filename
@@ -208,19 +209,17 @@ void SaveGSS::writeGSASFile(const std::string &outfilename, bool append,
   int nHist = static_cast<int>(inputWS->getNumberHistograms());
   Progress p(this, 0.0, 1.0, nHist);
 
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (int iws = 0; iws < nHist; iws++) {
     // Determine whether to skip the spectrum due to being masked
     if (has_instrument) {
-      try {
-        Geometry::IDetector_const_sptr det =
-            inputWS->getDetector(static_cast<size_t>(iws));
-        if (det->isMasked())
-          continue;
-      } catch (const Kernel::Exception::NotFoundError &) {
+      if (!spectrumInfo.hasDetectors(iws)) {
         has_instrument = false;
         g_log.warning() << "There is no detector associated with spectrum "
                         << iws
                         << ". Workspace is treated as NO-INSTRUMENT case. \n";
+      } else if (spectrumInfo.isMasked(iws)) {
+        continue;
       }
     }
 
diff --git a/Framework/DataHandling/src/SaveIsawDetCal.cpp b/Framework/DataHandling/src/SaveIsawDetCal.cpp
index b00ab53fe8926898fbad359552196344fea87467..ce10be85d4aa9d9781cb462365f84e1fbed0f2df 100644
--- a/Framework/DataHandling/src/SaveIsawDetCal.cpp
+++ b/Framework/DataHandling/src/SaveIsawDetCal.cpp
@@ -5,11 +5,14 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
-#include <fstream>
 #include "MantidAPI/Workspace.h"
 #include "MantidAPI/ExperimentInfo.h"
+
 #include <Poco/File.h>
+#include <boost/algorithm/string/trim.hpp>
+#include <fstream>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/DataHandling/src/SaveNXSPE.cpp b/Framework/DataHandling/src/SaveNXSPE.cpp
index ebb53c4b93a1224d1e50a328e1339e0d757e326c..d5a6521d4e93df13073904f206151d04fe3fb012 100644
--- a/Framework/DataHandling/src/SaveNXSPE.cpp
+++ b/Framework/DataHandling/src/SaveNXSPE.cpp
@@ -3,13 +3,13 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/HistogramValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 
 #include "MantidDataHandling/FindDetectorsPar.h"
 #include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/Detector.h"
 
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/MantidVersion.h"
@@ -228,20 +228,15 @@ void SaveNXSPE::exec() {
   // Write the data
   Progress progress(this, 0, 1, nHist);
   int64_t bufferCounter(0);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (int64_t i = 0; i < nHist; ++i) {
     progress.report();
 
-    Geometry::IDetector_const_sptr det;
-    try { // detector exist
-      det = inputWS->getDetector(i);
-    } catch (Exception::NotFoundError &) {
-    }
-
     double *signalBufferStart = signalBuffer.get() + bufferCounter * nBins;
     double *errorBufferStart = errorBuffer.get() + bufferCounter * nBins;
-    if (det && !det->isMonitor()) {
+    if (spectrumInfo.hasDetectors(i) && !spectrumInfo.isMonitor(i)) {
       // a detector but not a monitor
-      if (!det->isMasked()) {
+      if (!spectrumInfo.isMasked(i)) {
         const auto &inY = inputWS->readY(i);
         std::copy(inY.begin(), inY.end(), signalBufferStart);
         const auto &inE = inputWS->readE(i);
diff --git a/Framework/DataHandling/src/SaveNXTomo.cpp b/Framework/DataHandling/src/SaveNXTomo.cpp
index 730d4f25162480b69591aba54cafa26db12ff700..134e8ebf033dd5158888a8f4d8c5419f94551be0 100644
--- a/Framework/DataHandling/src/SaveNXTomo.cpp
+++ b/Framework/DataHandling/src/SaveNXTomo.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include "MantidDataHandling/FindDetectorsPar.h"
 
diff --git a/Framework/DataHandling/src/SaveNXcanSAS.cpp b/Framework/DataHandling/src/SaveNXcanSAS.cpp
index 57ce9ae061ce20852de8e46eb2f3dc71c0079ac4..dfa527692cdd5eb737ef7359351e482f8ef8ff5c 100644
--- a/Framework/DataHandling/src/SaveNXcanSAS.cpp
+++ b/Framework/DataHandling/src/SaveNXcanSAS.cpp
@@ -19,6 +19,7 @@
 #include <H5Cpp.h>
 #include <boost/make_shared.hpp>
 #include <boost/regex.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 #include <Poco/File.h>
 #include <Poco/Path.h>
diff --git a/Framework/DataHandling/src/SaveNexus.cpp b/Framework/DataHandling/src/SaveNexus.cpp
index 90631e8c9df5d5ecf74827521b58fb948727dc1f..c2b74e2a5ea9102fe4a68aae6846b71c6bce26a9 100644
--- a/Framework/DataHandling/src/SaveNexus.cpp
+++ b/Framework/DataHandling/src/SaveNexus.cpp
@@ -1,13 +1,11 @@
 // SaveNeXus
 // @author Freddie Akeroyd, STFC ISIS Faility
 // @author Ronald Fowler, STFC eScience. Modified to fit with SaveNexusProcessed
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidDataHandling/SaveNexus.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidAPI/FileProperty.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/BoundedValidator.h"
 
 #include <cmath>
diff --git a/Framework/DataHandling/src/SaveNexusProcessed.cpp b/Framework/DataHandling/src/SaveNexusProcessed.cpp
index e3747e14fc569a94fb39b45b118667e527e19c4c..f69accd921644586de57350139e3ff76fa29c7a5 100644
--- a/Framework/DataHandling/src/SaveNexusProcessed.cpp
+++ b/Framework/DataHandling/src/SaveNexusProcessed.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidDataHandling/SaveNexusProcessed.h"
 #include "MantidDataObjects/EventWorkspace.h"
diff --git a/Framework/DataHandling/src/SaveSPE.cpp b/Framework/DataHandling/src/SaveSPE.cpp
index 32785555f38b79a079ad37474ac5e2b8890d9d0b..6bd6409c2b73e4ad2868de4f75d9dfc5dd427ba9 100644
--- a/Framework/DataHandling/src/SaveSPE.cpp
+++ b/Framework/DataHandling/src/SaveSPE.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/HistogramValidator.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/IDetector.h"
@@ -223,11 +224,11 @@ void SaveSPE::writeHists(const API::MatrixWorkspace_const_sptr WS,
   std::vector<int> spuriousSpectra;
   // used only for debugging
   int nMasked = 0;
+  const auto &spectrumInfo = WS->spectrumInfo();
   // Loop over the spectra, writing out Y and then E values for each
   for (int i = 0; i < static_cast<int>(nHist); i++) {
-    try { // need to check if _all_ the detectors for the spectrum are masked,
-          // as we don't have output values for those
-      if (isNumericAxis || !WS->getDetector(i)->isMasked()) {
+    if (spectrumInfo.hasDetectors(i)) {
+      if (isNumericAxis || !spectrumInfo.isMasked(i)) {
         // there's no masking, write the data
         writeHist(WS, outFile, i);
       } else { // all the detectors are masked, write the masking value from the
@@ -236,11 +237,8 @@ void SaveSPE::writeHists(const API::MatrixWorkspace_const_sptr WS,
         writeMaskFlags(outFile);
         nMasked++;
       }
-    } catch (Exception::NotFoundError &) { // WS->getDetector(i) throws this if
-                                           // the detector isn't in the
-                                           // instrument definition file, write
-                                           // mask values and prepare to log
-                                           // what happened
+    } else { // if the detector isn't in the instrument definition file, write
+             // mask values and prepare to log what happened
       spuriousSpectra.push_back(i);
       writeMaskFlags(outFile);
     }
diff --git a/Framework/DataHandling/src/SaveSavuTomoConfig.cpp b/Framework/DataHandling/src/SaveSavuTomoConfig.cpp
index e88e6eccd8676266df10dfe83fc99d282d212cae..80c331018d6b4dc1161f1283b76857dca07f7ffb 100644
--- a/Framework/DataHandling/src/SaveSavuTomoConfig.cpp
+++ b/Framework/DataHandling/src/SaveSavuTomoConfig.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidDataHandling/SaveSavuTomoConfig.h"
diff --git a/Framework/DataHandling/src/SetSample.cpp b/Framework/DataHandling/src/SetSample.cpp
index b216716c00bc089f516d3caeeffc6b51bb67b350..3fc2e9c80c9b9c4312c887bae87be1ed96514e20 100644
--- a/Framework/DataHandling/src/SetSample.cpp
+++ b/Framework/DataHandling/src/SetSample.cpp
@@ -33,13 +33,13 @@ namespace {
  * the value.
  * @param args Dictionary-type containing the argument
  */
-long getAxisIndex(const Kernel::PropertyManager &args) {
+int64_t getAxisIndex(const Kernel::PropertyManager &args) {
   using Kernel::Property;
   using Kernel::PropertyWithValue;
-  long axisIdx(1);
+  int64_t axisIdx(1);
   if (args.existsProperty("Axis")) {
     Kernel::Property *axisProp = args.getProperty("Axis");
-    axisIdx = static_cast<PropertyWithValue<long> *>(axisProp)->operator()();
+    axisIdx = static_cast<PropertyWithValue<int64_t> *>(axisProp)->operator()();
     if (axisIdx < 0 || axisIdx > 2)
       throw std::invalid_argument(
           "Geometry.Axis value must be either 0,1,2 (X,Y,Z)");
@@ -55,7 +55,7 @@ long getAxisIndex(const Kernel::PropertyManager &args) {
   * @param axis The index of the height-axis of the cylinder
   */
 V3D cylBaseCentre(const std::vector<double> &cylCentre, double height,
-                  long axisIdx) {
+                  int64_t axisIdx) {
   const V3D halfHeight = [&]() {
     switch (axisIdx) {
     case 0:
@@ -76,7 +76,7 @@ V3D cylBaseCentre(const std::vector<double> &cylCentre, double height,
  * @param axisIdx Index 0,1,2 for the axis of a cylinder
  * @return A string containing the axis tag for this index
  */
-std::string axisXML(long axisIdx) {
+std::string axisXML(int64_t axisIdx) {
   switch (axisIdx) {
   case 0:
     return "<axis x=\"1\" y=\"0\" z=\"0\" />";
@@ -386,7 +386,7 @@ SetSample::createCylinderLikeXML(const Kernel::PropertyManager &args,
   double outerRadius =
       hollow ? args.getProperty("OuterRadius") : args.getProperty("Radius");
   std::vector<double> centre = args.getProperty("Center");
-  long axisIdx = getAxisIndex(args);
+  int64_t axisIdx = getAxisIndex(args);
   // convert to metres
   height *= 0.01;
   innerRadius *= 0.01;
diff --git a/Framework/DataHandling/src/SetSampleMaterial.cpp b/Framework/DataHandling/src/SetSampleMaterial.cpp
index 84256b5df47dd54c72a89f59118a8b770c234cef..5786e4433ad86fd5da4c106c96ea06329cd50cdf 100644
--- a/Framework/DataHandling/src/SetSampleMaterial.cpp
+++ b/Framework/DataHandling/src/SetSampleMaterial.cpp
@@ -1,6 +1,3 @@
-//--------------------------------
-// Includes
-//--------------------------------
 #include "MantidDataHandling/SetSampleMaterial.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/Workspace.h"
@@ -17,6 +14,7 @@
 #include <boost/scoped_ptr.hpp>
 
 #include <cmath>
+#include <iostream>
 
 using namespace Mantid::PhysicalConstants;
 
diff --git a/Framework/DataHandling/test/CompressEventsTest.h b/Framework/DataHandling/test/CompressEventsTest.h
index 1516f7a8fda2f09e0b95e4dcf285a27f64661279..9d87bba6b3435e427c6c396738d5370751f868ff 100644
--- a/Framework/DataHandling/test/CompressEventsTest.h
+++ b/Framework/DataHandling/test/CompressEventsTest.h
@@ -41,7 +41,7 @@ public:
      * 200 events; two in each bin, at time 0.5, 1.5, etc.
      * PulseTime = 1 second, 2 seconds, etc.
      */
-    input = WorkspaceCreationHelper::CreateEventWorkspace(numPixels, 100, 100,
+    input = WorkspaceCreationHelper::createEventWorkspace(numPixels, 100, 100,
                                                           0.0, 1.0, 2);
     AnalysisDataService::Instance().addOrReplace(inputName, input);
     // Quick initial check
diff --git a/Framework/DataHandling/test/CreateChopperModelTest.h b/Framework/DataHandling/test/CreateChopperModelTest.h
index 26791ab88fd88c74597bbf61ff168df4c90a26f9..0ca6677ca31cad519e1824733a3dd5ebcd88e9a0 100644
--- a/Framework/DataHandling/test/CreateChopperModelTest.h
+++ b/Framework/DataHandling/test/CreateChopperModelTest.h
@@ -109,7 +109,7 @@ private:
   }
 
   Mantid::API::MatrixWorkspace_sptr createTestWorkspace() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     ws->mutableRun().addProperty("Ei", 45.0);
     ws->mutableRun().addProperty("ChopperSpeed", 150.0);
     return ws;
diff --git a/Framework/DataHandling/test/CreateChunkingFromInstrumentTest.h b/Framework/DataHandling/test/CreateChunkingFromInstrumentTest.h
index eaa50ed4042d8a3d2e3dd0c593673be0dcda1db8..0f11d5fbac794d1ecedc67d6aba9ebb6243fce74 100644
--- a/Framework/DataHandling/test/CreateChunkingFromInstrumentTest.h
+++ b/Framework/DataHandling/test/CreateChunkingFromInstrumentTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidDataHandling/CreateChunkingFromInstrument.h"
 
diff --git a/Framework/DataHandling/test/CreateModeratorModelTest.h b/Framework/DataHandling/test/CreateModeratorModelTest.h
index e21d49af90c8f9044e64baaf3b720309ba180c27..0c3e0393bdd7c02707f3a1ad790e27ce2fa10e98 100644
--- a/Framework/DataHandling/test/CreateModeratorModelTest.h
+++ b/Framework/DataHandling/test/CreateModeratorModelTest.h
@@ -113,7 +113,7 @@ private:
 
   Mantid::API::MatrixWorkspace_sptr createTestWorkspace() {
     using Mantid::API::MatrixWorkspace_sptr;
-    return WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    return WorkspaceCreationHelper::create2DWorkspace(1, 10);
   }
 
   const std::string m_inputName;
diff --git a/Framework/DataHandling/test/CreateSampleShapeTest.h b/Framework/DataHandling/test/CreateSampleShapeTest.h
index bf194e2b4c511ce3cf70013278ea6fdd7f1530e7..b950764814f48238a0b01e7693b00d44c172832e 100644
--- a/Framework/DataHandling/test/CreateSampleShapeTest.h
+++ b/Framework/DataHandling/test/CreateSampleShapeTest.h
@@ -57,7 +57,7 @@ public:
     using Mantid::Kernel::V3D;
     using Mantid::PhysicalConstants::getNeutronAtom;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto sampleShape = ComponentCreationHelper::createSphere(0.5);
     sampleShape->setID("mysample");
     Material alum("Al", getNeutronAtom(13), 2.6989);
@@ -83,7 +83,7 @@ public:
     // Need a test workspace
     Mantid::API::AnalysisDataService::Instance().add(
         "TestWorkspace",
-        WorkspaceCreationHelper::Create2DWorkspace123(22, 10, 1));
+        WorkspaceCreationHelper::create2DWorkspace123(22, 10, 1));
 
     CreateSampleShape alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize());
diff --git a/Framework/DataHandling/test/CreateSimulationWorkspaceTest.h b/Framework/DataHandling/test/CreateSimulationWorkspaceTest.h
index c93b75abbf355ffc9d13e5656d759d27627170f1..7713089510f1016c6ee4bcb8dfac8ad771447370 100644
--- a/Framework/DataHandling/test/CreateSimulationWorkspaceTest.h
+++ b/Framework/DataHandling/test/CreateSimulationWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/CreateSimulationWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/DataHandling/test/DefineGaugeVolumeTest.h b/Framework/DataHandling/test/DefineGaugeVolumeTest.h
index 4cc6dcc15c9ed6fa8b279107aa8fce72aa80a636..5249777dc0aaaef183b7497b482433929625638d 100644
--- a/Framework/DataHandling/test/DefineGaugeVolumeTest.h
+++ b/Framework/DataHandling/test/DefineGaugeVolumeTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/DefineGaugeVolume.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/DetermineChunkingTest.h b/Framework/DataHandling/test/DetermineChunkingTest.h
index b15a648fa30b8751bfc4dd1e4ccfe52778001314..07e8488a6c8226b44d0cd31524cdf5b3408814df 100644
--- a/Framework/DataHandling/test/DetermineChunkingTest.h
+++ b/Framework/DataHandling/test/DetermineChunkingTest.h
@@ -7,6 +7,7 @@
 
 #include "MantidDataHandling/DetermineChunking.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 
 using namespace Mantid;
diff --git a/Framework/DataHandling/test/DownloadInstrumentTest.h b/Framework/DataHandling/test/DownloadInstrumentTest.h
index 22eb88013767523dfca8d79040591ed96c020d39..45a8dec95f9d09cc7ae2d1cb8b1faeedd475a1ad 100644
--- a/Framework/DataHandling/test/DownloadInstrumentTest.h
+++ b/Framework/DataHandling/test/DownloadInstrumentTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/DownloadInstrument.h"
+#include "MantidKernel/ConfigService.h"
 
 #include <Poco/Net/HTTPResponse.h>
 #include <Poco/Glob.h>
diff --git a/Framework/DataHandling/test/ExtractMonitorWorkspaceTest.h b/Framework/DataHandling/test/ExtractMonitorWorkspaceTest.h
index 6ddecf8e56e062c312a42f892a4f3806be6829e9..fa7a6ee512f5f098170af80857116e6b6cbd76c4 100644
--- a/Framework/DataHandling/test/ExtractMonitorWorkspaceTest.h
+++ b/Framework/DataHandling/test/ExtractMonitorWorkspaceTest.h
@@ -29,7 +29,7 @@ public:
   }
 
   void test_fails_if_no_monitor_workspace() {
-    auto inws = WorkspaceCreationHelper::Create1DWorkspaceRand(1);
+    auto inws = WorkspaceCreationHelper::create1DWorkspaceRand(1);
 
     ExtractMonitorWorkspace alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize())
@@ -77,8 +77,8 @@ public:
   }
 
   void test_2D_2D() {
-    auto inws = WorkspaceCreationHelper::Create1DWorkspaceRand(1);
-    auto monws = WorkspaceCreationHelper::Create1DWorkspaceFib(1);
+    auto inws = WorkspaceCreationHelper::create1DWorkspaceRand(1);
+    auto monws = WorkspaceCreationHelper::create1DWorkspaceFib(1);
     doTest(inws, monws);
   }
 
@@ -86,20 +86,20 @@ public:
   // type
 
   void test_2D_event() {
-    auto inws = WorkspaceCreationHelper::Create1DWorkspaceRand(1);
-    auto monws = WorkspaceCreationHelper::CreateEventWorkspace2(1, 1);
+    auto inws = WorkspaceCreationHelper::create1DWorkspaceRand(1);
+    auto monws = WorkspaceCreationHelper::createEventWorkspace2(1, 1);
     doTest(inws, monws);
   }
 
   void test_event_2D() {
-    auto inws = WorkspaceCreationHelper::CreateEventWorkspace2(1, 1);
-    auto monws = WorkspaceCreationHelper::Create1DWorkspaceRand(1);
+    auto inws = WorkspaceCreationHelper::createEventWorkspace2(1, 1);
+    auto monws = WorkspaceCreationHelper::create1DWorkspaceRand(1);
     doTest(inws, monws);
   }
 
   void test_event_event() {
-    auto inws = WorkspaceCreationHelper::CreateEventWorkspace2(1, 1);
-    auto monws = WorkspaceCreationHelper::CreateEventWorkspace2(1, 1);
+    auto inws = WorkspaceCreationHelper::createEventWorkspace2(1, 1);
+    auto monws = WorkspaceCreationHelper::createEventWorkspace2(1, 1);
     doTest(inws, monws);
   }
 
diff --git a/Framework/DataHandling/test/FindDetectorsInShapeTest.h b/Framework/DataHandling/test/FindDetectorsInShapeTest.h
index 350fa43e77e4256e60dc5b789fc2d434f0739f1e..e8918c444a31b6449c5ef0624586a2379ae6f508 100644
--- a/Framework/DataHandling/test/FindDetectorsInShapeTest.h
+++ b/Framework/DataHandling/test/FindDetectorsInShapeTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/FindDetectorsInShape.h"
 #include "MantidDataHandling/LoadEmptyInstrument.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 class FindDetectorsInShapeTest : public CxxTest::TestSuite {
 public:
diff --git a/Framework/DataHandling/test/FindDetectorsParTest.h b/Framework/DataHandling/test/FindDetectorsParTest.h
index f68e3cec6f8c10513c83d3d757e92b5a04399436..78c8e4d29cead1b2674d54f17a73a997793ee376 100644
--- a/Framework/DataHandling/test/FindDetectorsParTest.h
+++ b/Framework/DataHandling/test/FindDetectorsParTest.h
@@ -418,7 +418,7 @@ private:
   MatrixWorkspace_sptr buildUngroupedWS(const std::string &WS_Name) {
     const int NHIST = 3;
 
-    inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(NHIST, 10, 1.0);
+    inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(NHIST, 10, 1.0);
 
     for (int j = 0; j < NHIST; ++j) {
       // Just set the spectrum number to match the index
@@ -450,7 +450,7 @@ private:
         ComponentCreationHelper::createRingOfCylindricalDetectors(4, 5, 4));
     const size_t NDET = pDet->nDets();
 
-    inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 10, 1.0);
+    inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 10, 1.0);
 
     boost::shared_ptr<Geometry::Instrument> spInst(
         new Geometry::Instrument("basic_ring"));
diff --git a/Framework/DataHandling/test/GenerateGroupingPowderTest.h b/Framework/DataHandling/test/GenerateGroupingPowderTest.h
index 1567bd6da07367acd92974731e1b97837df5a1b8..9176052888fc24c19d35b03f10196e8dad2530b9 100644
--- a/Framework/DataHandling/test/GenerateGroupingPowderTest.h
+++ b/Framework/DataHandling/test/GenerateGroupingPowderTest.h
@@ -8,6 +8,7 @@
 #include "MantidDataHandling/LoadEmptyInstrument.h"
 #include "MantidDataHandling/GenerateGroupingPowder.h"
 #include "MantidDataHandling/LoadDetectorsGroupingFile.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidGeometry/Crystal/AngleUnits.h"
 
 using namespace Mantid;
diff --git a/Framework/DataHandling/test/GroupDetectors2Test.h b/Framework/DataHandling/test/GroupDetectors2Test.h
index e567ef92b9bb9eca0b358e52f6aba3300d3d3b38..434772d6e0811380e43a28dc6ac270b7121bc1a0 100644
--- a/Framework/DataHandling/test/GroupDetectors2Test.h
+++ b/Framework/DataHandling/test/GroupDetectors2Test.h
@@ -91,7 +91,7 @@ public:
 
   void testAveragingWithNoInstrument() {
     Workspace2D_sptr testWS =
-        WorkspaceCreationHelper::Create2DWorkspace123(3, 3, false);
+        WorkspaceCreationHelper::create2DWorkspace123(3, 3, false);
     GroupDetectors2 grouper;
     grouper.initialize();
     grouper.setChild(true);
@@ -528,7 +528,7 @@ public:
     int numPixels = 5;
     int numBins = 5;
     int numEvents = 200;
-    EventWorkspace_sptr input = WorkspaceCreationHelper::CreateEventWorkspace(
+    EventWorkspace_sptr input = WorkspaceCreationHelper::createEventWorkspace(
         numPixels, numBins, numEvents, 0, 1, 4);
     AnalysisDataService::Instance().addOrReplace("GDEvents", input);
     GroupDetectors2 alg2;
diff --git a/Framework/DataHandling/test/GroupDetectorsTest.h b/Framework/DataHandling/test/GroupDetectorsTest.h
index 4cc67d38032948633205828d9c4e8a65c7ed24c3..4ae58ace1837dfde443a8cf7587ada069b0e4068 100644
--- a/Framework/DataHandling/test/GroupDetectorsTest.h
+++ b/Framework/DataHandling/test/GroupDetectorsTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidDataHandling/GroupDetectors.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceProperty.h"
diff --git a/Framework/DataHandling/test/InstrumentRayTracerTest.h b/Framework/DataHandling/test/InstrumentRayTracerTest.h
index 1241629492be517f9f992eb512ecdd46bd63f89a..403a4d4f92e249a1b8cc3b372c04b51af8480c4d 100644
--- a/Framework/DataHandling/test/InstrumentRayTracerTest.h
+++ b/Framework/DataHandling/test/InstrumentRayTracerTest.h
@@ -47,7 +47,7 @@ public:
   InstrumentRayTracerTestPerformance() {
     m_inst = ComponentCreationHelper::createTestInstrumentRectangular(2, 100);
 
-    topazWS = WorkspaceCreationHelper::Create2DWorkspace(1, 2);
+    topazWS = WorkspaceCreationHelper::create2DWorkspace(1, 2);
     AnalysisDataService::Instance().add("TOPAZ_2010", topazWS);
     // Load a small test file
     FrameworkManager::Instance().exec(
diff --git a/Framework/DataHandling/test/LoadCalFileTest.h b/Framework/DataHandling/test/LoadCalFileTest.h
index f5c96908b2384523e6132c95b100d1504ebb65cd..bd53ec47bed97c2d7cff0af781d6133e095b53dd 100644
--- a/Framework/DataHandling/test/LoadCalFileTest.h
+++ b/Framework/DataHandling/test/LoadCalFileTest.h
@@ -4,6 +4,8 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/Run.h"
 
 #include "MantidDataHandling/LoadCalFile.h"
@@ -89,10 +91,11 @@ public:
     TS_ASSERT_EQUALS(int(maskWS->getValue(101003)), 1);
     TS_ASSERT_EQUALS(int(maskWS->getValue(101008)), 1);
     TS_ASSERT_EQUALS(int(maskWS->getValue(715079)), 0);
-    TS_ASSERT(!maskWS->getInstrument()->getDetector(101001)->isMasked());
-    TS_ASSERT(maskWS->getInstrument()->getDetector(101003)->isMasked());
-    TS_ASSERT(maskWS->getInstrument()->getDetector(101008)->isMasked());
-    TS_ASSERT(!maskWS->getInstrument()->getDetector(715079)->isMasked());
+    const auto &detectorInfo = maskWS->detectorInfo();
+    TS_ASSERT(!detectorInfo.isMasked(detectorInfo.indexOf(101001)));
+    TS_ASSERT(detectorInfo.isMasked(detectorInfo.indexOf(101003)));
+    TS_ASSERT(detectorInfo.isMasked(detectorInfo.indexOf(101008)));
+    TS_ASSERT(!detectorInfo.isMasked(detectorInfo.indexOf(715079)));
     // Check if filename is saved
     TS_ASSERT_EQUALS(alg.getPropertyValue("CalFilename"),
                      maskWS->run().getProperty("Filename")->value());
diff --git a/Framework/DataHandling/test/LoadCanSAS1dTest.h b/Framework/DataHandling/test/LoadCanSAS1dTest.h
index 1efb62318e742a2605a76ec82c2594f8bf92da65..488e24632fefbb9252ced8cc2be08ae7ac0994eb 100644
--- a/Framework/DataHandling/test/LoadCanSAS1dTest.h
+++ b/Framework/DataHandling/test/LoadCanSAS1dTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include <Poco/Path.h>
 
 class LoadCanSAS1dTest : public CxxTest::TestSuite {
diff --git a/Framework/DataHandling/test/LoadDetectorInfoTest.h b/Framework/DataHandling/test/LoadDetectorInfoTest.h
index 401e8da890e5f9031159f70e945e7dc56b01369b..1ade97d303c03c42ec1b09660febdb720e84c83d 100644
--- a/Framework/DataHandling/test/LoadDetectorInfoTest.h
+++ b/Framework/DataHandling/test/LoadDetectorInfoTest.h
@@ -6,6 +6,7 @@
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidDataHandling/LoadDetectorInfo.h"
 #include "MantidDataHandling/LoadRaw3.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FileFinder.h"
 #include "MantidAPI/WorkspaceFactory.h"
@@ -223,7 +224,6 @@ void makeTestWorkspace(const int ndets, const int nbins,
   }
 
   Instrument_sptr instr(new Instrument);
-  space2D->setInstrument(instr);
   ObjComponent *samplePos = new ObjComponent("sample-pos", instr.get());
   instr->markAsSamplePos(samplePos);
 
@@ -233,6 +233,7 @@ void makeTestWorkspace(const int ndets, const int nbins,
     Detector *d = new Detector(os.str(), i, 0);
     instr->markAsDetector(d);
   }
+  space2D->setInstrument(instr);
 
   // Register the workspace in the data service
   AnalysisDataService::Instance().add(ads_name, space2D);
diff --git a/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h b/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
index 8b5b8b5cb54bd3057990bdacd38141c182cba5ca..9c77c21fea1a4421522bb6bd34276a7de89f0c9f 100644
--- a/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
+++ b/Framework/DataHandling/test/LoadDetectorsGroupingFileTest.h
@@ -4,6 +4,7 @@
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidDataHandling/LoadDetectorsGroupingFile.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
diff --git a/Framework/DataHandling/test/LoadDiffCalTest.h b/Framework/DataHandling/test/LoadDiffCalTest.h
index 097f6fe5b9a1d9e72e87215391d8ad07b7003ba4..733638d3d4efc1b6286062a2d4e6cdbf7a08bc6a 100644
--- a/Framework/DataHandling/test/LoadDiffCalTest.h
+++ b/Framework/DataHandling/test/LoadDiffCalTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidDataHandling/LoadDiffCal.h"
 // reuse what another test has for creating dummy workspaces
diff --git a/Framework/DataHandling/test/LoadDspacemapTest.h b/Framework/DataHandling/test/LoadDspacemapTest.h
index d00455638b4fb0e6c1aa1a1cd2077560b1c4c5c8..436509e27c298a9ae1478dd5d06deeaa03311cde 100644
--- a/Framework/DataHandling/test/LoadDspacemapTest.h
+++ b/Framework/DataHandling/test/LoadDspacemapTest.h
@@ -4,6 +4,7 @@
 #include "MantidDataHandling/LoadDspacemap.h"
 #include "MantidDataHandling/LoadEmptyInstrument.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
diff --git a/Framework/DataHandling/test/LoadEventPreNexus2Test.h b/Framework/DataHandling/test/LoadEventPreNexus2Test.h
index f18db11ae8b6bc3b2bd0f23c043957c609b7f728..1b2b1a7175dd4281ad4847c9890adcc9d66cfbf7 100644
--- a/Framework/DataHandling/test/LoadEventPreNexus2Test.h
+++ b/Framework/DataHandling/test/LoadEventPreNexus2Test.h
@@ -12,6 +12,7 @@
 
 #include "MantidDataHandling/LoadEventPreNexus2.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/LoadEventPreNexusTest.h b/Framework/DataHandling/test/LoadEventPreNexusTest.h
index 59e16806de12bb8f4290b18b73265e64aeee888a..d55a51010044cf8d7409f012e53f0011f8503815 100644
--- a/Framework/DataHandling/test/LoadEventPreNexusTest.h
+++ b/Framework/DataHandling/test/LoadEventPreNexusTest.h
@@ -12,6 +12,7 @@
 
 #include "MantidDataHandling/LoadEventPreNexus.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/LoadFITSTest.h b/Framework/DataHandling/test/LoadFITSTest.h
index 875959d9bda5fad58a43485d0c9add20ea4b4bc1..c68e416ee1cd01ce3bb82c4d16fe80d17d2639d3 100644
--- a/Framework/DataHandling/test/LoadFITSTest.h
+++ b/Framework/DataHandling/test/LoadFITSTest.h
@@ -6,6 +6,7 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadFITS.h"
 #include <MantidAPI/FrameworkManager.h>
 
@@ -163,12 +164,12 @@ public:
 
     // Sum the two bins from the last spectra - should be 70400
     double sumY =
-        ws1->readY(g_SPECTRA_COUNT - 1)[0] + ws2->readY(g_SPECTRA_COUNT - 1)[0];
+        ws1->y(g_SPECTRA_COUNT - 1)[0] + ws2->y(g_SPECTRA_COUNT - 1)[0];
     TS_ASSERT_EQUALS(sumY, 275);
     // Check the sum of the error values for the last spectra in each file -
     // should be 375.183
     double sumE =
-        ws1->readE(g_SPECTRA_COUNT - 1)[0] + ws2->readE(g_SPECTRA_COUNT - 1)[0];
+        ws1->e(g_SPECTRA_COUNT - 1)[0] + ws2->e(g_SPECTRA_COUNT - 1)[0];
     TS_ASSERT_LESS_THAN(std::abs(sumE - 23.4489), 0.0001); // Include a small
     // tolerance check with
     // the assert - not
@@ -209,9 +210,9 @@ public:
       TS_ASSERT_EQUALS(ws->getNumberHistograms(), g_SPECTRA_COUNT);
 
       // check Y and Error
-      TS_ASSERT_EQUALS(ws->readY(g_SPECTRA_COUNT - 100)[0], expectedY[i]);
+      TS_ASSERT_EQUALS(ws->y(g_SPECTRA_COUNT - 100)[0], expectedY[i]);
       TS_ASSERT_LESS_THAN(
-          std::abs(ws->readE(g_SPECTRA_COUNT - 100)[0] - expectedE[i]), 0.0001);
+          std::abs(ws->e(g_SPECTRA_COUNT - 100)[0] - expectedE[i]), 0.0001);
     }
   }
 
@@ -347,15 +348,15 @@ public:
     size_t n = ws0->getNumberHistograms();
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (first one) is not as expected",
-        ws0->readY(n - 1)[0], 137);
+        ws0->y(n - 1)[0], 137);
 
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (middle one) is not as expected",
-        ws0->readY(n - 1)[g_SPECTRA_COUNT_ASRECT / 2], 159);
+        ws0->y(n - 1)[g_SPECTRA_COUNT_ASRECT / 2], 159);
 
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (last one) is not as expected",
-        ws0->readY(n - 1).back(), 142);
+        ws0->y(n - 1).back(), 142);
 
     MatrixWorkspace_sptr ws1;
     TS_ASSERT_THROWS_NOTHING(
@@ -366,15 +367,15 @@ public:
                       ws1->getTitle(), g_smallFname2);
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (first one) is not as expected",
-        ws1->readY(n - 1)[0], 155);
+        ws1->y(n - 1)[0], 155);
 
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (middle one) is not as expected",
-        ws1->readY(n - 1)[g_SPECTRA_COUNT_ASRECT / 2], 199);
+        ws1->y(n - 1)[g_SPECTRA_COUNT_ASRECT / 2], 199);
 
     TSM_ASSERT_EQUALS(
         "The value at a given spectrum and bin (last one) is not as expected",
-        ws1->readY(n - 1).back(), 133);
+        ws1->y(n - 1).back(), 133);
   }
 
   void test_loadEmpty() {
diff --git a/Framework/DataHandling/test/LoadFullprofResolutionTest.h b/Framework/DataHandling/test/LoadFullprofResolutionTest.h
index 63d8c9537a4999e5477cccdc827c8083ee8d27e4..892f17551c5e930adf3b74a2c2b8cc0a4b21e432 100644
--- a/Framework/DataHandling/test/LoadFullprofResolutionTest.h
+++ b/Framework/DataHandling/test/LoadFullprofResolutionTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadInstrument.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
diff --git a/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h b/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h
index c77d1da9fd6399c00d5005c5f6799c63d489ebb4..3d4e3add2b2ec3040e268ac302b6f6fb925079f7 100644
--- a/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h
+++ b/Framework/DataHandling/test/LoadGSASInstrumentFileTest.h
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadInstrument.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidGeometry/Instrument.h"
diff --git a/Framework/DataHandling/test/LoadGSSTest.h b/Framework/DataHandling/test/LoadGSSTest.h
index 69b211b760bd3fa7f000288d7321c005d633002a..c42f27213775d8cab750e847225bce675a460719 100644
--- a/Framework/DataHandling/test/LoadGSSTest.h
+++ b/Framework/DataHandling/test/LoadGSSTest.h
@@ -4,6 +4,7 @@
 #include "cxxtest/TestSuite.h"
 #include "MantidDataHandling/LoadGSS.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidTestHelpers/ScopedFileHelper.h"
@@ -27,13 +28,14 @@ public:
   void test_load_gss_txt() {
     API::IAlgorithm_sptr loader = createAlgorithm();
     loader->setPropertyValue("Filename", "gss.txt");
-    TS_ASSERT(loader->execute())
+    loader->setRethrows(true);
+    TS_ASSERT_THROWS_NOTHING(loader->execute());
     API::MatrixWorkspace_const_sptr ws = loader->getProperty("OutputWorkspace");
     // Check a few things in the workspace
     checkWorkspace(ws, 8, 816);
-    auto x1 = ws->readX(0)[99];
-    auto x2 = ws->readX(0)[100];
-    auto y = ws->readY(0)[99];
+    auto x1 = ws->x(0)[99];
+    auto x2 = ws->x(0)[100];
+    auto y = ws->y(0)[99];
     TS_ASSERT_DELTA((x1 + x2) / 2, 40844.0625, 1e-6);
     TS_ASSERT_DELTA(y, 145304004.625, 1e-6);
   }
@@ -71,16 +73,16 @@ public:
     TS_ASSERT(loader->execute());
     TS_ASSERT_EQUALS(loader->isExecuted(), true);
     API::MatrixWorkspace_const_sptr ws = loader->getProperty("OutputWorkspace");
-    auto x1 = ws->readX(0)[0];
-    auto x2 = ws->readX(0)[1];
+    auto x1 = ws->x(0)[0];
+    auto x2 = ws->x(0)[1];
     auto dx = x2 - x1;
-    auto y = ws->readY(0)[0] * dx;
+    auto y = ws->y(0)[0] * dx;
     TS_ASSERT_DELTA((x1 + x2) / 2, 115202.20029, 1e-6);
     TS_ASSERT_DELTA(y, 123456.00000002, 1e-10);
-    x1 = ws->readX(0)[3];
-    x2 = ws->readX(0)[4];
+    x1 = ws->x(0)[3];
+    x2 = ws->x(0)[4];
     dx = x2 - x1;
-    y = ws->readY(0)[3] * dx;
+    y = ws->y(0)[3] * dx;
     TS_ASSERT_DELTA(y, 123456789.00000005, 1e-10);
 
     const auto source = ws->getInstrument()->getSource();
@@ -177,4 +179,43 @@ private:
   }
 };
 
+class LoadGSSTestPerformance : public CxxTest::TestSuite {
+public:
+  void setUp() override {
+    for (int i = 0; i < numberOfIterations; ++i) {
+      loadAlgPtrs.emplace_back(setupAlg());
+    }
+  }
+
+  void testLoadGSSPerformance() {
+    for (auto alg : loadAlgPtrs) {
+      TS_ASSERT_THROWS_NOTHING(alg->execute());
+    }
+  }
+
+  void tearDown() override {
+    for (int i = 0; i < numberOfIterations; i++) {
+      delete loadAlgPtrs[i];
+      loadAlgPtrs[i] = nullptr;
+    }
+    API::AnalysisDataService::Instance().remove(outWsName);
+  }
+
+private:
+  std::vector<LoadGSS *> loadAlgPtrs;
+  const int numberOfIterations = 100;
+  const std::string outWsName = "TestWS";
+
+  LoadGSS *setupAlg() {
+    LoadGSS *loadAlg = new LoadGSS();
+    loadAlg->initialize();
+
+    loadAlg->setPropertyValue("Filename", "gss1.txt");
+    loadAlg->setProperty("OutputWorkspace", outWsName);
+    loadAlg->setProperty("UseBankIDasSpectrumNumber", true);
+
+    loadAlg->setRethrows(true);
+    return loadAlg;
+  }
+};
 #endif // LOADGSSTEST_H_
diff --git a/Framework/DataHandling/test/LoadILLIndirectTest.h b/Framework/DataHandling/test/LoadILLIndirectTest.h
index 4c7af1051fa4c891e7a3e65e9ce92b4ab7c7bb92..3e9422433131f5fc862b98780898566f67f99c77 100644
--- a/Framework/DataHandling/test/LoadILLIndirectTest.h
+++ b/Framework/DataHandling/test/LoadILLIndirectTest.h
@@ -89,8 +89,49 @@ public:
   }
 
 private:
-  std::string m_dataFile2013;
-  std::string m_dataFile2015;
+  const std::string m_dataFile2013;
+  const std::string m_dataFile2015;
 };
 
+class LoadILLIndirectTestPerformance : public CxxTest::TestSuite {
+public:
+  void setUp() override {
+    for (int i = 0; i < numberOfIterations; ++i) {
+      loadAlgPtrs.emplace_back(setupAlg());
+    }
+  }
+
+  void testLoadILLIndirectPerformance() {
+    for (auto alg : loadAlgPtrs) {
+      TS_ASSERT_THROWS_NOTHING(alg->execute());
+    }
+  }
+
+  void tearDown() override {
+    for (int i = 0; i < numberOfIterations; i++) {
+      delete loadAlgPtrs[i];
+      loadAlgPtrs[i] = nullptr;
+    }
+    Mantid::API::AnalysisDataService::Instance().remove(outWSName);
+  }
+
+private:
+  std::vector<LoadILLIndirect *> loadAlgPtrs;
+
+  const int numberOfIterations = 5;
+
+  const std::string inFileName = "ILLIN16B_127500.nxs";
+  const std::string outWSName = "LoadILLWsOut";
+
+  LoadILLIndirect *setupAlg() {
+    LoadILLIndirect *loader = new LoadILLIndirect;
+    loader->initialize();
+    loader->isInitialized();
+    loader->setPropertyValue("Filename", inFileName);
+    loader->setPropertyValue("OutputWorkspace", outWSName);
+
+    loader->setRethrows(true);
+    return loader;
+  }
+};
 #endif /* MANTID_DATAHANDLING_LOADILLINDIRECTTEST_H_ */
diff --git a/Framework/DataHandling/test/LoadILLSANSTest.h b/Framework/DataHandling/test/LoadILLSANSTest.h
index 1e1328d6cc4e4990d450c116d84508a407e691c9..1182d8675e2a96d40313539e7b7db13eb8b83931 100644
--- a/Framework/DataHandling/test/LoadILLSANSTest.h
+++ b/Framework/DataHandling/test/LoadILLSANSTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/LoadILLSANS.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 using Mantid::DataHandling::LoadILLSANS;
diff --git a/Framework/DataHandling/test/LoadInstrumentTest.h b/Framework/DataHandling/test/LoadInstrumentTest.h
index 61d85995c6820d712eff1108f928d7f86caa4fe6..a050a7c8fa587bbaad395d001bf5ccc9bb495b09 100644
--- a/Framework/DataHandling/test/LoadInstrumentTest.h
+++ b/Framework/DataHandling/test/LoadInstrumentTest.h
@@ -646,7 +646,7 @@ public:
   MatrixWorkspace_sptr ws;
 
   void setUp() override {
-    ws = WorkspaceCreationHelper::Create2DWorkspace(1, 2);
+    ws = WorkspaceCreationHelper::create2DWorkspace(1, 2);
   }
 
   void doTest(std::string filename, size_t numTimes = 1) {
diff --git a/Framework/DataHandling/test/LoadLLBTest.h b/Framework/DataHandling/test/LoadLLBTest.h
index 788811a1ffec8a8d101e46a4974cd6223c77bb15..3f638dcf051512f951258c7a8e9d4ade1637e227 100644
--- a/Framework/DataHandling/test/LoadLLBTest.h
+++ b/Framework/DataHandling/test/LoadLLBTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/LoadLLB.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 using namespace Mantid::API;
diff --git a/Framework/DataHandling/test/LoadMaskTest.h b/Framework/DataHandling/test/LoadMaskTest.h
index af0b7551195de92e6f6aaaf039a9970fbee2e2b5..03405c6dbcaaf8242ccaf1ffb5cdc9adf8b5ae32 100644
--- a/Framework/DataHandling/test/LoadMaskTest.h
+++ b/Framework/DataHandling/test/LoadMaskTest.h
@@ -10,6 +10,8 @@
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidTestHelpers/ScopedFileHelper.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 using namespace Mantid;
 using namespace Mantid::DataHandling;
@@ -259,9 +261,10 @@ public:
     // masked
     std::vector<detid_t> maskSourceDet, maskTargDet;
 
+    const auto &spectrumInfo = source->spectrumInfo();
     size_t n_steps = source->getNumberHistograms();
     for (size_t i = 0; i < n_steps; ++i) {
-      bool source_masked = source->getDetector(i)->isMasked();
+      bool source_masked = spectrumInfo.isMasked(i);
       if (source_masked) {
         maskSourceDet.push_back(source->getDetector(i)->getID());
       }
diff --git a/Framework/DataHandling/test/LoadMcStasNexusTest.h b/Framework/DataHandling/test/LoadMcStasNexusTest.h
index 27902f836b5a0edd69e3c372128e6d2a6e418582..36a36c38722887a2749355508b72829184dc8107 100644
--- a/Framework/DataHandling/test/LoadMcStasNexusTest.h
+++ b/Framework/DataHandling/test/LoadMcStasNexusTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadMcStasNexus.h"
 // These includes seem to make the difference between initialization of the
 // workspace names (workspace2D/1D etc), instrument classes and not for this
diff --git a/Framework/DataHandling/test/LoadMcStasTest.h b/Framework/DataHandling/test/LoadMcStasTest.h
index e9ebc98da5d18a6c32ab5dd0c2035e5e3345e319..6d178168e198220bcc11faba60c5127097843f90 100644
--- a/Framework/DataHandling/test/LoadMcStasTest.h
+++ b/Framework/DataHandling/test/LoadMcStasTest.h
@@ -8,6 +8,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadMcStas.h"
 // These includes seem to make the difference between initialization of the
 // workspace names (workspace2D/1D etc), instrument classes and not for this
diff --git a/Framework/DataHandling/test/LoadMuonNexus1Test.h b/Framework/DataHandling/test/LoadMuonNexus1Test.h
index 4d936fb662567c06100d88efed3378dc5e7fc5b4..9428b1ec308fc6af0fe3e6c20b93c9c869537a87 100644
--- a/Framework/DataHandling/test/LoadMuonNexus1Test.h
+++ b/Framework/DataHandling/test/LoadMuonNexus1Test.h
@@ -20,6 +20,7 @@
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/ScopedWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/Unit.h"
diff --git a/Framework/DataHandling/test/LoadNXSPETest.h b/Framework/DataHandling/test/LoadNXSPETest.h
index 878755526a32996dc852ff394ab75f252862a440..6557806cd91ce21e6aa6d412e119c31e7cb0046f 100644
--- a/Framework/DataHandling/test/LoadNXSPETest.h
+++ b/Framework/DataHandling/test/LoadNXSPETest.h
@@ -2,6 +2,7 @@
 #define MANTID_DATAHANDLING_LOADNXSPETEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/DeltaEMode.h"
diff --git a/Framework/DataHandling/test/LoadNXcanSASTest.h b/Framework/DataHandling/test/LoadNXcanSASTest.h
index a322f61cb8e7825fb448f16fa2f59418b1f8c1f3..7ff7c3ca011db961dc9877a6dbe1e4c132133fe2 100644
--- a/Framework/DataHandling/test/LoadNXcanSASTest.h
+++ b/Framework/DataHandling/test/LoadNXcanSASTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
diff --git a/Framework/DataHandling/test/LoadNexusLogsTest.h b/Framework/DataHandling/test/LoadNexusLogsTest.h
index 38b10895647caffca67aae37b40fb0a19a5ef0ed..d530d8e5641b8fb849eca30ab54267d71eaa8e2a 100644
--- a/Framework/DataHandling/test/LoadNexusLogsTest.h
+++ b/Framework/DataHandling/test/LoadNexusLogsTest.h
@@ -39,7 +39,7 @@ public:
     Run &run = ws->mutableRun();
     // Do we have all we expect
     const std::vector<Property *> &logs = run.getLogData();
-    TS_ASSERT_EQUALS(logs.size(), 74);
+    TS_ASSERT_EQUALS(logs.size(), 75);
     Property *prop;
     TimeSeriesProperty<double> *dProp;
 
@@ -84,7 +84,7 @@ public:
     const API::Run &run = testWS->run();
     const std::vector<Property *> &logs = run.getLogData();
     TS_ASSERT_EQUALS(logs.size(),
-                     34); // 33 logs in file + 1 synthetic nperiods log
+                     35); // 34 logs in file + 1 synthetic nperiods log
 
     TimeSeriesProperty<std::string> *slog =
         dynamic_cast<TimeSeriesProperty<std::string> *>(
@@ -170,6 +170,27 @@ public:
                       uniquePeriods.size());
   }
 
+  void test_extract_run_title_from_event_nexus() {
+
+    auto testWS = createTestWorkspace();
+    auto run = testWS->run();
+
+    LoadNexusLogs loader;
+    loader.setChild(true);
+    loader.initialize();
+    loader.setProperty("Workspace", testWS);
+    loader.setPropertyValue("Filename", "LARMOR00003368.nxs");
+    loader.execute();
+    run = testWS->run();
+
+    const bool hasTitle = run.hasProperty("run_title");
+    TSM_ASSERT("Should have run_title now we have run LoadNexusLogs", hasTitle);
+
+    std::string title = run.getPropertyValueAsType<std::string>("run_title");
+    TSM_ASSERT_EQUALS("Run title is not correct",
+                      "3He polariser test 0.9bar Long Polariser 0.75A", title);
+  }
+
   void test_log_non_default_entry() {
     auto testWS = createTestWorkspace();
     LoadNexusLogs loader;
diff --git a/Framework/DataHandling/test/LoadNexusMonitorsTest.h b/Framework/DataHandling/test/LoadNexusMonitorsTest.h
index 80e14001c17c9cc993593bd741258641a905c1a1..954956529b291537c60f50b2ac656de6016410dd 100644
--- a/Framework/DataHandling/test/LoadNexusMonitorsTest.h
+++ b/Framework/DataHandling/test/LoadNexusMonitorsTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidDataObjects/EventWorkspace.h"
diff --git a/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Framework/DataHandling/test/LoadNexusProcessedTest.h
index 02ce669e70ef7a5ee38db81b465a87f65fd03f64..beac902bee1349f0badc5de8ad901752a6be68f4 100644
--- a/Framework/DataHandling/test/LoadNexusProcessedTest.h
+++ b/Framework/DataHandling/test/LoadNexusProcessedTest.h
@@ -7,6 +7,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/PeakShapeSpherical.h"
 #include "MantidDataObjects/Peak.h"
@@ -962,7 +963,7 @@ public:
     std::string workspaceName = "test_workspace_name";
     for (size_t index = 0; index < 2; ++index) {
       // Create a sample workspace and add it to the ADS, so it gets a name.
-      auto ws = WorkspaceCreationHelper::Create1DWorkspaceConstant(
+      auto ws = WorkspaceCreationHelper::create1DWorkspaceConstant(
           3, static_cast<double>(index), static_cast<double>(index));
       AnalysisDataService::Instance().addOrReplace(workspaceName, ws);
       alg.setProperty("InputWorkspace",
@@ -1245,7 +1246,7 @@ private:
     groups[5].push_back(20);
 
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateGroupedEventWorkspace(groups, 30, 1.0);
+        WorkspaceCreationHelper::createGroupedEventWorkspace(groups, 30, 1.0);
     ws->getSpectrum(4).clear();
 
     TS_ASSERT_EQUALS(ws->getNumberHistograms(), groups.size());
diff --git a/Framework/DataHandling/test/LoadNexusTest.h b/Framework/DataHandling/test/LoadNexusTest.h
index 8ca3c98b46f1bc9878e644b2b0a4fdc63af2843b..ef781f83fb4a483a09b21a6df8e2cefbebd71403 100644
--- a/Framework/DataHandling/test/LoadNexusTest.h
+++ b/Framework/DataHandling/test/LoadNexusTest.h
@@ -8,6 +8,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Unit.h"
 #include "MantidDataHandling/LoadNexus.h"
 // These includes seem to make the difference between initialization of the
diff --git a/Framework/DataHandling/test/LoadPDFgetNFileTest.h b/Framework/DataHandling/test/LoadPDFgetNFileTest.h
index e77c0db0cfed94c97ae35c604a0c60495bcf5fb2..d5bd74bbf2ca4e22916cf85c6a9f7e9271a6150e 100644
--- a/Framework/DataHandling/test/LoadPDFgetNFileTest.h
+++ b/Framework/DataHandling/test/LoadPDFgetNFileTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/LoadPDFgetNFile.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using Mantid::DataHandling::LoadPDFgetNFile;
 using namespace Mantid;
diff --git a/Framework/DataHandling/test/LoadPreNexusTest.h b/Framework/DataHandling/test/LoadPreNexusTest.h
index e6cb64d3ac25f84204127d6a4c53db006d896880..8a63e21ea94d66576bb43df7c06c4e7ab10a7844 100644
--- a/Framework/DataHandling/test/LoadPreNexusTest.h
+++ b/Framework/DataHandling/test/LoadPreNexusTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/LoadPreNexus.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
diff --git a/Framework/DataHandling/test/LoadQKKTest.h b/Framework/DataHandling/test/LoadQKKTest.h
index e41eb78c3f7bd069c5c84ab64c0f1ce59446da9f..d7e2f42d50c4c648b7a215f284ff5b99a5ece15e 100644
--- a/Framework/DataHandling/test/LoadQKKTest.h
+++ b/Framework/DataHandling/test/LoadQKKTest.h
@@ -1,11 +1,9 @@
 #ifndef LOADQKKTEST_H_
 #define LOADQKKTEST_H_
 
-//-----------------
-// Includes
-//-----------------
 #include "MantidDataHandling/LoadQKK.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/ConfigService.h"
 #include <cxxtest/TestSuite.h>
 #include <Poco/Path.h>
diff --git a/Framework/DataHandling/test/LoadRKHTest.h b/Framework/DataHandling/test/LoadRKHTest.h
index eed7b29b0d96e0e7f6633b88d1bcf224e0ffaf9d..c1baec0c8c4854397e2eb076d35f78ebe0d18415 100644
--- a/Framework/DataHandling/test/LoadRKHTest.h
+++ b/Framework/DataHandling/test/LoadRKHTest.h
@@ -1,10 +1,8 @@
 #ifndef LOADRKHTEST_H_
 #define LOADRKHTEST_H_
 
-//-----------------
-// Includes
-//-----------------
 #include "MantidDataHandling/LoadRKH.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/ConfigService.h"
diff --git a/Framework/DataHandling/test/LoadRaw3Test.h b/Framework/DataHandling/test/LoadRaw3Test.h
index 32bbf029c0f236db6f5b396c442fb57e9f06a785..a1bf006f2e3ad4ee3689726e355ac7c28ac8bcc8 100644
--- a/Framework/DataHandling/test/LoadRaw3Test.h
+++ b/Framework/DataHandling/test/LoadRaw3Test.h
@@ -12,6 +12,7 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/Unit.h"
+#include <boost/lexical_cast.hpp>
 #include <cxxtest/TestSuite.h>
 
 using namespace Mantid;
@@ -1154,8 +1155,8 @@ private:
     PropertyWithValue<int> *current_period_property =
         dynamic_cast<PropertyWithValue<int> *>(prop);
     TS_ASSERT(current_period_property != NULL);
-    int actual_period;
-    Kernel::toValue<int>(current_period_property->value(), actual_period);
+    int actual_period =
+        boost::lexical_cast<int>(current_period_property->value());
     TS_ASSERT_EQUALS(expected_period, actual_period);
     // Check the period n property.
     std::stringstream stream;
diff --git a/Framework/DataHandling/test/LoadRawBin0Test.h b/Framework/DataHandling/test/LoadRawBin0Test.h
index b22a7d886d0a3b60da977a7671a339ddd3dd1b51..189d36505cc31adefc5afd929e85cf057954df0b 100644
--- a/Framework/DataHandling/test/LoadRawBin0Test.h
+++ b/Framework/DataHandling/test/LoadRawBin0Test.h
@@ -13,6 +13,7 @@
 #include "MantidKernel/Unit.h"
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
+#include <boost/lexical_cast.hpp>
 #include <Poco/Path.h>
 
 using namespace Mantid::API;
@@ -156,8 +157,7 @@ private:
         dynamic_cast<PropertyWithValue<int> *>(prop);
     TS_ASSERT(current_period_property != NULL);
     int actual_period;
-    Mantid::Kernel::toValue<int>(current_period_property->value(),
-                                 actual_period);
+    actual_period = boost::lexical_cast<int>(current_period_property->value());
     TS_ASSERT_EQUALS(expected_period, actual_period);
     // Check the period n property.
     std::stringstream stream;
diff --git a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
index a0eb1bed4c0cf877f2a96389e50f5b33c456ebd6..f6cf518eefa5273c3d92d5a970f648e4abf17937 100644
--- a/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
+++ b/Framework/DataHandling/test/LoadRawSaveNxsLoadNxsTest.h
@@ -13,6 +13,7 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataHandling/LoadMuonNexus.h"
 #include "MantidDataHandling/LoadNexus.h"
diff --git a/Framework/DataHandling/test/LoadRawSpectrum0Test.h b/Framework/DataHandling/test/LoadRawSpectrum0Test.h
index a3f831dbe4bc3c68784fd387123fc461e0eec9fa..481139c8b82073aa90ffbae27597ecb28e92d976 100644
--- a/Framework/DataHandling/test/LoadRawSpectrum0Test.h
+++ b/Framework/DataHandling/test/LoadRawSpectrum0Test.h
@@ -14,6 +14,7 @@
 #include "MantidKernel/Unit.h"
 #include "MantidGeometry/Instrument.h"
 
+#include <boost/lexical_cast.hpp>
 #include <Poco/Path.h>
 
 using namespace Mantid::API;
@@ -150,8 +151,7 @@ private:
         dynamic_cast<PropertyWithValue<int> *>(prop);
     TS_ASSERT(current_period_property != NULL);
     int actual_period;
-    Mantid::Kernel::toValue<int>(current_period_property->value(),
-                                 actual_period);
+    actual_period = boost::lexical_cast<int>(current_period_property->value());
     TS_ASSERT_EQUALS(expected_period, actual_period);
     // Check the period n property.
     std::stringstream stream;
diff --git a/Framework/DataHandling/test/LoadSINQFocusTest.h b/Framework/DataHandling/test/LoadSINQFocusTest.h
index cb1410ef5a548c1879fe5fb627837c0bc9e99411..86013e43e899d4a1bfcaf60328e1c340cce4b712 100644
--- a/Framework/DataHandling/test/LoadSINQFocusTest.h
+++ b/Framework/DataHandling/test/LoadSINQFocusTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/LoadSINQFocus.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 using namespace Mantid::API;
diff --git a/Framework/DataHandling/test/LoadSNSspecTest.h b/Framework/DataHandling/test/LoadSNSspecTest.h
index 761eefc00a237164f1d08126102b274f46d8ce40..45e1c54cc773a1cd19e11aaba43ca012afb221df 100644
--- a/Framework/DataHandling/test/LoadSNSspecTest.h
+++ b/Framework/DataHandling/test/LoadSNSspecTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/LoadSNSspec.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
 using namespace Mantid::API;
diff --git a/Framework/DataHandling/test/LoadSPETest.h b/Framework/DataHandling/test/LoadSPETest.h
index 0c86b26b16037d1119d44c5b6b6d25e85bda29ec..2143a174defa2ba605e5f562583834457486e662 100644
--- a/Framework/DataHandling/test/LoadSPETest.h
+++ b/Framework/DataHandling/test/LoadSPETest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/LoadSPE.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Unit.h"
diff --git a/Framework/DataHandling/test/LoadSassenaTest.h b/Framework/DataHandling/test/LoadSassenaTest.h
index 5fcdbe5eb4cad18ba4234ed3532bb53b2b1a662e..235e583c912c2526263399850920027904d49dae 100644
--- a/Framework/DataHandling/test/LoadSassenaTest.h
+++ b/Framework/DataHandling/test/LoadSassenaTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/LoadSassena.h"
 #include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid;
 
diff --git a/Framework/DataHandling/test/LoadSaveAsciiTest.h b/Framework/DataHandling/test/LoadSaveAsciiTest.h
index 50693391e6d1e99af3a267369ecdf68b5491b2d7..1571f24f690017dca9ff62127f2f91e0513bb54c 100644
--- a/Framework/DataHandling/test/LoadSaveAsciiTest.h
+++ b/Framework/DataHandling/test/LoadSaveAsciiTest.h
@@ -6,6 +6,7 @@
 #include "MantidDataHandling/LoadAscii.h"
 #include "MantidDataHandling/SaveAscii.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/LoadSpice2dTest.h b/Framework/DataHandling/test/LoadSpice2dTest.h
index 498f3a7a8543dc01ef4a461ec13d3f6a304590a9..1ebec15ccb8588e71f2383673c8c31cd4e143948 100644
--- a/Framework/DataHandling/test/LoadSpice2dTest.h
+++ b/Framework/DataHandling/test/LoadSpice2dTest.h
@@ -9,6 +9,7 @@
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/Instrument/Parameter.h"
 #include "MantidKernel/PropertyWithValue.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include <Poco/Path.h>
 #include <vector>
diff --git a/Framework/DataHandling/test/LoadSpiceAsciiTest.h b/Framework/DataHandling/test/LoadSpiceAsciiTest.h
index d8f8c1a37e508f4151a5843c3b634db0393d2b09..d0f2137d3a0012677a3e18394b66ab29bcf8af06 100644
--- a/Framework/DataHandling/test/LoadSpiceAsciiTest.h
+++ b/Framework/DataHandling/test/LoadSpiceAsciiTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/LoadSpiceAscii.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
diff --git a/Framework/DataHandling/test/LoadSpiceXML2DDetTest.h b/Framework/DataHandling/test/LoadSpiceXML2DDetTest.h
index 1d27805f05e4b5461c70f93738aec5d403d3160b..d5ab96dc8938af0e3303ed7698a87f99b73f5eec 100644
--- a/Framework/DataHandling/test/LoadSpiceXML2DDetTest.h
+++ b/Framework/DataHandling/test/LoadSpiceXML2DDetTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/LoadSpiceXML2DDet.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -42,9 +43,13 @@ public:
 
   //----------------------------------------------------------------------------------------------
   /** Sample test load data without instrument
-   * @brief test_LoadHB3AXML
+   * test data: HB3A_exp355_scan0001_0522
+   *   2theta = 42.70975 degree
+   * check:
+   *   sample logs: including run_start, monitor, omega, chi, phi and 2theta
+   * @brief Load data without instrument
    */
-  void test_LoadHB3AXML() {
+  void test_LoadDataNoInstrument() {
     LoadSpiceXML2DDet loader;
     loader.initialize();
 
@@ -121,13 +126,15 @@ public:
 
   //----------------------------------------------------------------------------------------------
   /** Test algorithm with loading HB3A with instrument and presense of SPICE
-   * scan table
-   *  such that it can be set to zero-2-theta position
-   * @brief test_LoadHB3AXML2InstrumentedWS
-   * Testing include
-   * 1. 2theta = 0 degree: scattering angle of all 4 corners should be same;
+   * scan table such that it will override 2theta value in the XML file
+   * Test: Set 2theta = 0
+   *  1. Detector should be symmetric along the X-axis and about the center of
+   * detector;
+   *  2. All pixels on the X-axis will have position Y value zero;
+   *  3. All pixels on the Y-axis will have position X value zero
+   * @brief test: load data with instrument whose detector's 2theta value is 0.
    */
-  void test_LoadHB3ADataZeroPosition() {
+  void test_LoadDataOverwrite2ThetaZero() {
     // Test 2theta at 0 degree
     LoadSpiceXML2DDet loader;
     loader.initialize();
@@ -142,7 +149,7 @@ public:
     loader.setProperty("DetectorGeometry", sizelist);
     loader.setProperty("LoadInstrument", true);
     loader.setProperty("SpiceTableWorkspace", scantablews);
-    loader.setProperty("PtNumber", 3);
+    loader.setProperty("PtNumber", 3); // pt number 3 has 2theta value as 0.0
     loader.setProperty("ShiftedDetectorDistance", 0.);
 
     loader.execute();
@@ -154,9 +161,11 @@ public:
     TS_ASSERT(outws);
     TS_ASSERT_EQUALS(outws->getNumberHistograms(), 256 * 256);
 
-    // Value
-    TS_ASSERT_DELTA(outws->readY(255 * 256)[0], 1.0, 0.0001);
-    TS_ASSERT_DELTA(outws->readY(9 * 256 + 253)[0], 1.0, 0.00001);
+    // test signal value on various pixels
+    // pixel at (256, 1): column 1
+    TS_ASSERT_DELTA(outws->readY(255)[0], 1.0, 0.0001);
+    // pixel at (254, 256): colun 256
+    TS_ASSERT_DELTA(outws->readY(255 * 256 + 138)[0], 2.0, 0.00001);
 
     // Instrument
     TS_ASSERT(outws->getInstrument());
@@ -167,14 +176,54 @@ public:
     // check center of the detector @ (128, 115)
     size_t center_col = 128;
     size_t center_row = 115;
-    size_t center_ws_index = (center_row - 1) * 256 + (center_col - 1);
+    size_t center_ws_index = (center_row - 1) + (center_col - 1) * 256;
     Kernel::V3D det_center = outws->getDetector(center_ws_index)->getPos();
     // distance to sample
     double dist_r = det_center.distance(sample);
     TS_ASSERT_DELTA(dist_r, 0.3750, 0.0001);
     // center of the detector must be at zero
     TS_ASSERT_DELTA(det_center.X(), 0.0, 0.0000001);
-    TS_ASSERT_DELTA(det_center.Y(), 0.0, 0.0000001)
+    TS_ASSERT_DELTA(det_center.Y(), 0.0, 0.0000001);
+
+    // check the sequence of the detector to each ws index
+    detid_t det0id = outws->getDetector(0)->getID();
+    TS_ASSERT_EQUALS(det0id, 0);
+    detid_t det1id = outws->getDetector(1)->getID();
+    TS_ASSERT_EQUALS(det1id, 1);
+    detid_t detlastid = outws->getDetector(256 * 255 + 255)->getID();
+    TS_ASSERT_EQUALS(detlastid, 255 * 256 + 255);
+    // test the whole sequence
+    for (size_t irow = 1; irow < 250; ++irow)
+      for (size_t jcol = 10; jcol < 20; ++jcol) {
+        size_t iws = irow + jcol * 256;
+        detid_t detid = outws->getDetector(iws)->getID();
+        TS_ASSERT_EQUALS(detid, static_cast<detid_t>(iws));
+      }
+
+    // test the geometry position whether det ID is from lower right corner and
+    // move along positive Y direction
+    // right most column
+    Kernel::V3D det0pos = outws->getDetector(0)->getPos();
+    TS_ASSERT_DELTA(det0pos.X(), 0.0252015625, 0.000001);
+    TS_ASSERT_DELTA(det0pos.Y(), -0.022621875, 0.000001);
+    TS_ASSERT_DELTA(det0pos.Z(), 0.375, 0.0001);
+
+    double dY = 0.0001984375;
+
+    Kernel::V3D det1pos = outws->getDetector(1)->getPos();
+    TS_ASSERT_DELTA(det1pos.X(), 0.0252015625, 0.000001);
+    TS_ASSERT_DELTA(det1pos.Y(), -0.022621875 + dY, 0.000001);
+    TS_ASSERT_DELTA(det1pos.Z(), 0.375, 0.0001);
+
+    // center is tested before
+
+    // lower left column
+    size_t i_wsll = 255 * 256 + 1;
+    double dX = -0.0001984375;
+    Kernel::V3D detllpos = outws->getDetector(i_wsll)->getPos();
+    TS_ASSERT_DELTA(detllpos.X(), 0.0252015625 + 255 * dX, 0.000001);
+    TS_ASSERT_DELTA(detllpos.Y(), -0.022621875 + dY, 0.000001);
+    TS_ASSERT_DELTA(detllpos.Z(), 0.375, 0.0001);
 
     // test the detectors with symmetric to each other
     // they should have opposite X or Y
@@ -182,22 +231,22 @@ public:
     // ll: low-left, lr: low-right, ul: upper-left; ur: upper-right
     size_t row_ll = 0;
     size_t col_ll = 2;
-    size_t ws_index_ll = row_ll * 256 + col_ll;
+    size_t ws_index_ll = row_ll + col_ll * 256;
     Kernel::V3D det_ll_pos = outws->getDetector(ws_index_ll)->getPos();
 
     size_t row_lr = 0;
     size_t col_lr = 2 * 127 - 2;
-    size_t ws_index_lr = row_lr * 256 + col_lr;
+    size_t ws_index_lr = row_lr + col_lr * 256;
     Kernel::V3D det_lr_pos = outws->getDetector(ws_index_lr)->getPos();
 
     size_t row_ul = 114 * 2;
     size_t col_ul = 2;
-    size_t ws_index_ul = row_ul * 256 + col_ul;
+    size_t ws_index_ul = row_ul + col_ul * 256;
     Kernel::V3D det_ul_pos = outws->getDetector(ws_index_ul)->getPos();
 
     size_t row_ur = 114 * 2;
     size_t col_ur = 2 * 127 - 2;
-    size_t ws_index_ur = row_ur * 256 + col_ur;
+    size_t ws_index_ur = row_ur + col_ur * 256;
     Kernel::V3D det_ur_pos = outws->getDetector(ws_index_ur)->getPos();
 
     double det_size = 0.0508; // meter
@@ -221,12 +270,16 @@ public:
   }
 
   //----------------------------------------------------------------------------------------------
-  /** Test with loading instrument but without Spice scan Table.
-   *  Other tests include check the positions of detectors
-   *  2-theta = 42.797
-   * @brief test_LoadHB3AXMLInstrumentNoTable
+  /** Test with loading instrument without Spice scan Table, while the 2theta
+   * value is from sample
+   *    sample log
+   *  Testing includes:
+   *  1. Load the instrument without Spice Table;
+   *  2. Check the positions of detectors.
+   *    (a) at center pixel, 2-theta = 42.797
+   * @brief Load data and instrument with sample log value
    */
-  void test_LoadHB3AXMLInstrumentNoTable() {
+  void test_loadDataUsingSampleLogValue() {
     // initialize the algorithm
     LoadSpiceXML2DDet loader;
     loader.initialize();
@@ -253,8 +306,11 @@ public:
     TS_ASSERT_EQUALS(outws->getNumberHistograms(), 256 * 256);
 
     // Value
-    TS_ASSERT_DELTA(outws->readY(255 * 256)[0], 1.0, 0.0001);
-    TS_ASSERT_DELTA(outws->readY(9 * 256 + 253)[0], 1.0, 0.00001);
+    // test signal value on various pixels
+    // pixel at (256, 1): column 1
+    TS_ASSERT_DELTA(outws->readY(255)[0], 1.0, 0.0001);
+    // pixel at (254, 256): colun 256
+    TS_ASSERT_DELTA(outws->readY(255 * 256 + 138)[0], 2.0, 0.00001);
 
     // Instrument
     TS_ASSERT(outws->getInstrument());
@@ -279,7 +335,7 @@ public:
     // check the center position
     size_t center_row = 115 - 1;
     size_t center_col = 128 - 1;
-    size_t center_ws_index = 256 * center_row + center_col;
+    size_t center_ws_index = 256 * center_col + center_row;
     Kernel::V3D center_det_pos = outws->getDetector(center_ws_index)->getPos();
     TS_ASSERT_DELTA(center_det_pos.Y(), 0., 0.00000001);
     double sample_center_distance = sample.distance(center_det_pos);
@@ -294,7 +350,7 @@ public:
     double ll_sample_r = sample.distance(ll_det_pos);
     TS_ASSERT_DELTA(ll_sample_r, 0.37597, 0.001);
 
-    size_t lu_ws_index = 255 * 256; // row = 255, col = 1
+    size_t lu_ws_index = 255; // row = 255, col = 1
     Kernel::V3D lu_det_pos = outws->getDetector(lu_ws_index)->getPos();
     double lu_sample_r = sample.distance(lu_det_pos);
     TS_ASSERT_DELTA(lu_sample_r, 0.37689, 0.001);
@@ -344,8 +400,11 @@ public:
     TS_ASSERT_EQUALS(outws->getNumberHistograms(), 256 * 256);
 
     // Value
-    TS_ASSERT_DELTA(outws->readY(255 * 256)[0], 1.0, 0.0001);
-    TS_ASSERT_DELTA(outws->readY(9 * 256 + 253)[0], 1.0, 0.00001);
+    // test signal value on various pixels
+    // pixel at (256, 1): column 1
+    TS_ASSERT_DELTA(outws->readY(255)[0], 1.0, 0.0001);
+    // pixel at (254, 256): colun 256
+    TS_ASSERT_DELTA(outws->readY(255 * 256 + 138)[0], 2.0, 0.00001);
 
     // Instrument
     TS_ASSERT(outws->getInstrument());
@@ -357,7 +416,7 @@ public:
     // check center of the detector @ (128, 115)
     size_t center_col = 128;
     size_t center_row = 115;
-    size_t center_ws_index = (center_row - 1) * 256 + (center_col - 1);
+    size_t center_ws_index = (center_row - 1) + (center_col - 1) * 256;
     Kernel::V3D center_det_pos = outws->getDetector(center_ws_index)->getPos();
     // distance to sample
     double dist_r = center_det_pos.distance(sample);
@@ -373,22 +432,22 @@ public:
     // ll: low-left, lr: low-right, ul: upper-left; ur: upper-right
     size_t row_ll = 0;
     size_t col_ll = 2;
-    size_t ws_index_ll = row_ll * 256 + col_ll;
+    size_t ws_index_ll = row_ll + col_ll * 256;
     Kernel::V3D det_ll_pos = outws->getDetector(ws_index_ll)->getPos();
 
     size_t row_lr = 0;
     size_t col_lr = 2 * 127 - 2;
-    size_t ws_index_lr = row_lr * 256 + col_lr;
+    size_t ws_index_lr = row_lr + col_lr * 256;
     Kernel::V3D det_lr_pos = outws->getDetector(ws_index_lr)->getPos();
 
     size_t row_ul = 114 * 2;
     size_t col_ul = 2;
-    size_t ws_index_ul = row_ul * 256 + col_ul;
+    size_t ws_index_ul = row_ul + col_ul * 256;
     Kernel::V3D det_ul_pos = outws->getDetector(ws_index_ul)->getPos();
 
     size_t row_ur = 114 * 2;
     size_t col_ur = 2 * 127 - 2;
-    size_t ws_index_ur = row_ur * 256 + col_ur;
+    size_t ws_index_ur = row_ur + col_ur * 256;
     Kernel::V3D det_ur_pos = outws->getDetector(ws_index_ur)->getPos();
 
     // Check symmetry
@@ -403,6 +462,131 @@ public:
     AnalysisDataService::Instance().remove("Exp0335_S0038D");
   }
 
+  //----------------------------------------------------------------------------------------------
+  /** Test with loading instrument without Spice scan Table and detector is
+   *shifted from original
+   *  center
+   *
+   *  Testing includes:
+   *  1. Load the instrument without Spice Table;
+   *  2. Check the positions of shifted detector: from (115, 128) to (127,137)
+   *    (a) at center pixel, 2-theta = 42.797 and pixel ID
+   *  3. Check the symmetry of the peak positions
+   * @brief Load data and instrument with sample log value
+   */
+  void test_loadDataShiftDetectorCenter() {
+    // initialize the algorithm
+    LoadSpiceXML2DDet loader;
+    loader.initialize();
+
+    // calculate shift of the detector center from (115, 128) to (127, 127)
+    double det_step_x = -0.0001984375;
+    double shift_x = static_cast<double>(137 - 128) * det_step_x *
+                     -1.; // shift x comes from column
+    double det_step_y = 0.0001984375;
+    double shift_y = static_cast<double>(127 - 115) * det_step_y *
+                     -1; // shift y comes from row
+
+    // set up properties
+    const std::string filename("HB3A_exp355_scan0001_0522.xml");
+    TS_ASSERT_THROWS_NOTHING(loader.setProperty("Filename", filename));
+    TS_ASSERT_THROWS_NOTHING(
+        loader.setProperty("OutputWorkspace", "Exp0335_S0038C"));
+    std::vector<size_t> sizelist(2);
+    sizelist[0] = 256;
+    sizelist[1] = 256;
+    loader.setProperty("DetectorGeometry", sizelist);
+    loader.setProperty("LoadInstrument", true);
+    loader.setProperty("ShiftedDetectorDistance", 0.);
+    loader.setProperty("DetectorCenterXShift", shift_x);
+    loader.setProperty("DetectorCenterYShift", shift_y);
+
+    loader.execute();
+    TS_ASSERT(loader.isExecuted());
+
+    // Get data
+    MatrixWorkspace_sptr outws = boost::dynamic_pointer_cast<MatrixWorkspace>(
+        AnalysisDataService::Instance().retrieve("Exp0335_S0038C"));
+    TS_ASSERT(outws);
+    TS_ASSERT_EQUALS(outws->getNumberHistograms(), 256 * 256);
+
+    // Value
+    // test signal value on various pixels
+    // pixel at (256, 1): column 1
+    TS_ASSERT_DELTA(outws->readY(255)[0], 1.0, 0.0001);
+    // pixel at (254, 256): column 256
+    TS_ASSERT_DELTA(outws->readY(255 * 256 + 138)[0], 2.0, 0.00001);
+
+    // Instrument
+    TS_ASSERT(outws->getInstrument());
+
+    // get 2theta from workspace
+    double twotheta_raw =
+        atof(outws->run().getProperty("_2theta")->value().c_str());
+
+    Kernel::Property *raw_property = outws->run().getProperty("2theta");
+    Kernel::TimeSeriesProperty<double> *twotheta_property =
+        dynamic_cast<Kernel::TimeSeriesProperty<double> *>(raw_property);
+    TS_ASSERT(twotheta_property);
+    double twotheta_log = twotheta_property->valuesAsVector()[0];
+    TS_ASSERT_DELTA(twotheta_log, 42.70975, 0.0001);
+
+    TS_ASSERT_EQUALS(twotheta_raw, twotheta_log);
+
+    // check the center of the detector
+    Kernel::V3D source = outws->getInstrument()->getSource()->getPos();
+    Kernel::V3D sample = outws->getInstrument()->getSample()->getPos();
+
+    // check the center position
+    size_t center_row = 127 - 1;
+    size_t center_col = 137 - 1;
+    size_t center_ws_index = 256 * center_col + center_row;
+    // y should be 0. in the Z-Y plane
+    Kernel::V3D center_det_pos = outws->getDetector(center_ws_index)->getPos();
+    TS_ASSERT_DELTA(center_det_pos.Y(), 0., 0.00000001);
+    double sample_center_distance = sample.distance(center_det_pos);
+    // distance
+    std::cout << "Sample center distance: " << sample_center_distance << "\n";
+    TS_ASSERT_DELTA(sample_center_distance, 0.3750, 0.0000001);
+    // 2-theta angle
+    double sample_center_angle =
+        (sample - source).angle(center_det_pos - sample);
+    TS_ASSERT_DELTA(sample_center_angle * 180. / M_PI, twotheta_log, 0.0001);
+
+    // symmetry from now on!
+    size_t ws_d_row = 10;
+    size_t ws_d_col = 15;
+
+    size_t ll_ws_index =
+        (center_row - ws_d_row) + (center_col - ws_d_col) * 256;
+    Kernel::V3D ll_det_pos = outws->getDetector(ll_ws_index)->getPos();
+    double ll_sample_r = sample.distance(ll_det_pos);
+
+    size_t lr_ws_index =
+        (center_row + ws_d_row) + (center_col - ws_d_col) * 256;
+    Kernel::V3D lr_det_pos = outws->getDetector(lr_ws_index)->getPos();
+    double lr_sample_r = sample.distance(lr_det_pos);
+
+    TS_ASSERT_DELTA(ll_sample_r, lr_sample_r, 0.0000001);
+
+    size_t ur_ws_index =
+        (center_row + ws_d_row) + (center_col + ws_d_col) * 256;
+    Kernel::V3D ur_det_pos = outws->getDetector(ur_ws_index)->getPos();
+    double ur_sample_r = sample.distance(ur_det_pos);
+
+    TS_ASSERT_DELTA(ll_sample_r, ur_sample_r, 0.0000001);
+
+    size_t ul_ws_index =
+        (center_row - ws_d_row) + (center_col + ws_d_col) * 256;
+    Kernel::V3D ul_det_pos = outws->getDetector(ul_ws_index)->getPos();
+    double ul_sample_r = sample.distance(ul_det_pos);
+
+    TS_ASSERT_DELTA(ul_sample_r, ur_sample_r, 0.0000001);
+
+    // Clean
+    AnalysisDataService::Instance().remove("Exp0335_S0038C");
+  }
+
   /** Create SPICE scan table workspace
    * @brief createSpiceScanTable
    * @return
diff --git a/Framework/DataHandling/test/LoadVulcanCalFileTest.h b/Framework/DataHandling/test/LoadVulcanCalFileTest.h
index 55ec9327339d4b29b653698d8c2ec310d692c6d8..a1fd723afebe0aeaca0d9eb4fe788accf78ef750 100644
--- a/Framework/DataHandling/test/LoadVulcanCalFileTest.h
+++ b/Framework/DataHandling/test/LoadVulcanCalFileTest.h
@@ -4,7 +4,9 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 #include "MantidDataHandling/LoadVulcanCalFile.h"
 #include "MantidDataObjects/GroupingWorkspace.h"
@@ -144,11 +146,12 @@ public:
     if (!maskWS)
       return;
 
+    const auto &spectrumInfo = maskWS->spectrumInfo();
     size_t nummasked = 0;
     for (size_t i = 0; i < maskWS->getNumberHistograms(); ++i) {
       if (maskWS->readY(i)[0] > 0.5) {
         ++nummasked;
-        TS_ASSERT(maskWS->getDetector(i)->isMasked());
+        TS_ASSERT(spectrumInfo.isMasked(i));
       }
     }
 
diff --git a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
index 97797a41e912bd5a456d5117192b3647d53422ef..8ef1fc33059fca35fb2c442b6af77269a961748e 100644
--- a/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
+++ b/Framework/DataHandling/test/MaskDetectorsInShapeTest.h
@@ -7,6 +7,8 @@
 #include "MantidDataHandling/LoadEmptyInstrument.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FrameworkManager.h"
 
 using namespace Mantid::API;
@@ -81,10 +83,9 @@ public:
     // check that the detectors have actually been marked dead
     std::vector<int> expectedDetectorArray =
         convertStringToVector(expectedHits);
-    Mantid::Geometry::Instrument_const_sptr i = outWS->getInstrument();
-    for (std::vector<int>::iterator it = expectedDetectorArray.begin();
-         it != expectedDetectorArray.end(); ++it) {
-      TS_ASSERT(i->getDetector((*it))->isMasked())
+    const auto &detectorInfo = outWS->detectorInfo();
+    for (const auto detID : expectedDetectorArray) {
+      TS_ASSERT(detectorInfo.isMasked(detectorInfo.indexOf(detID)));
     }
   }
 
diff --git a/Framework/DataHandling/test/MaskDetectorsTest.h b/Framework/DataHandling/test/MaskDetectorsTest.h
index cdd82dfc4e78547a7b036607750db4c8681fad93..b70408589e48a94a2b729f393a66f70bc80cbecc 100644
--- a/Framework/DataHandling/test/MaskDetectorsTest.h
+++ b/Framework/DataHandling/test/MaskDetectorsTest.h
@@ -5,6 +5,8 @@
 
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidDataHandling/MaskDetectors.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidDataObjects/Workspace2D.h"
@@ -14,6 +16,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 #include "MantidGeometry/IDetector.h"
 
@@ -170,11 +173,12 @@ public:
     TS_ASSERT_EQUALS(outputWS->dataE(3)[0], zeroes);
     TS_ASSERT_EQUALS(outputWS->dataY(4)[0], ones);
     TS_ASSERT_EQUALS(outputWS->dataE(4)[0], ones);
-    TS_ASSERT(outputWS->getDetector(0)->isMasked());
-    TS_ASSERT(!outputWS->getDetector(1)->isMasked());
-    TS_ASSERT(outputWS->getDetector(2)->isMasked());
-    TS_ASSERT(outputWS->getDetector(3)->isMasked());
-    TS_ASSERT(!outputWS->getDetector(4)->isMasked());
+    const auto &spectrumInfo = outputWS->spectrumInfo();
+    TS_ASSERT(spectrumInfo.isMasked(0));
+    TS_ASSERT(!spectrumInfo.isMasked(1));
+    TS_ASSERT(spectrumInfo.isMasked(2));
+    TS_ASSERT(spectrumInfo.isMasked(3));
+    TS_ASSERT(!spectrumInfo.isMasked(4));
   }
 
   //---------------------------------------------------------------------------------------------
@@ -251,15 +255,10 @@ public:
     masked_indices.insert(3);
     masked_indices.insert(4);
 
-    ParameterMap &pmap = existingMask->instrumentParameters();
-    for (int i = 0; i < static_cast<int>(existingMask->getNumberHistograms());
-         ++i) {
-      if (masked_indices.count(i) == 1) {
-        IDetector_const_sptr det;
-        TS_ASSERT_THROWS_NOTHING(det = existingMask->getDetector(i));
-        pmap.addBool(det.get(), "masked", true);
-      }
-    }
+    auto &detInfo = existingMask->mutableDetectorInfo();
+    for (int i = 0; i < static_cast<int>(detInfo.size()); ++i)
+      if (masked_indices.count(i) == 1)
+        detInfo.setMasked(i, true);
 
     MaskDetectors masker;
     TS_ASSERT_THROWS_NOTHING(masker.initialize());
@@ -279,15 +278,15 @@ public:
     TS_ASSERT(originalWS);
     if (!originalWS)
       return;
+    const auto &spectrumInfo = originalWS->spectrumInfo();
     for (int i = 0; i < static_cast<int>(originalWS->getNumberHistograms());
          ++i) {
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = originalWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (masked_indices.count(i) == 1) {
-        TS_ASSERT_EQUALS(det->isMasked(), true);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
         TS_ASSERT_EQUALS(originalWS->readY(i)[0], 0.0);
       } else {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
         TS_ASSERT_EQUALS(originalWS->readY(i)[0], 1.0);
       }
     }
@@ -343,15 +342,15 @@ public:
     if (!originalWS)
       return;
 
+    const auto &spectrumInfo = originalWS->spectrumInfo();
     for (int i = 0; i < static_cast<int>(originalWS->getNumberHistograms() - 1);
          ++i) {
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = originalWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (masked_indices.count(i) == 1) {
-        TS_ASSERT_EQUALS(det->isMasked(), true);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
         TS_ASSERT_EQUALS(originalWS->readY(i)[0], 0.0);
       } else {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
         TS_ASSERT_EQUALS(originalWS->readY(i)[0], 1.0);
       }
     }
@@ -394,13 +393,13 @@ public:
         inputWSName);
 
     // Check masking
+    const auto &spectrumInfo = inputWS->spectrumInfo();
     for (int i = 0; i < numInputSpec; ++i) {
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = inputWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (i == 3 || i == 4) {
-        TS_ASSERT_EQUALS(det->isMasked(), true);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
       } else {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
       }
     }
 
@@ -425,13 +424,13 @@ public:
         inputWSName);
 
     // Check masking
+    const auto &spectrumInfo = inputWS->spectrumInfo();
     for (int i = 0; i < numInputSpec; ++i) {
-      IDetector_const_sptr det;
-      TS_ASSERT_THROWS_NOTHING(det = inputWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (i == 3 || i == 4 || i == 5) {
-        TS_ASSERT_EQUALS(det->isMasked(), true);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), true);
       } else {
-        TS_ASSERT_EQUALS(det->isMasked(), false);
+        TS_ASSERT_EQUALS(spectrumInfo.isMasked(i), false);
       }
     }
 
@@ -489,21 +488,23 @@ public:
         inputWSName);
 
     // Check masking
+    const auto &spectrumInfo = inputWS->spectrumInfo();
     for (size_t i = 0; i < inputWS->getNumberHistograms(); ++i) {
       IDetector_const_sptr det;
       TS_ASSERT_THROWS_NOTHING(det = inputWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (i == 0 || i == 2 || i == 5) {
         TSM_ASSERT_EQUALS("Detector with id: " +
                               boost::lexical_cast<std::string>(det->getID()) +
                               "; Spectra N: " +
                               boost::lexical_cast<std::string>(i),
-                          det->isMasked(), true);
+                          spectrumInfo.isMasked(i), true);
       } else {
         TSM_ASSERT_EQUALS("Detector with id: " +
                               boost::lexical_cast<std::string>(det->getID()) +
                               "; Spectra N: " +
                               boost::lexical_cast<std::string>(i),
-                          det->isMasked(), false);
+                          spectrumInfo.isMasked(i), false);
       }
     }
 
@@ -554,21 +555,23 @@ public:
         inputWSName);
 
     // Check masking
+    const auto &spectrumInfo = inputWS->spectrumInfo();
     for (size_t i = 0; i < inputWS->getNumberHistograms(); ++i) {
       IDetector_const_sptr det;
       TS_ASSERT_THROWS_NOTHING(det = inputWS->getDetector(i));
+      TS_ASSERT(spectrumInfo.hasDetectors(i));
       if (i == 1 || i == 2 || i == 5) {
         TSM_ASSERT_EQUALS("Detector with id: " +
                               boost::lexical_cast<std::string>(det->getID()) +
                               "; Spectra N: " +
                               boost::lexical_cast<std::string>(i),
-                          det->isMasked(), true);
+                          spectrumInfo.isMasked(i), true);
       } else {
         TSM_ASSERT_EQUALS("Detector with id: " +
                               boost::lexical_cast<std::string>(det->getID()) +
                               "; Spectra N: " +
                               boost::lexical_cast<std::string>(i),
-                          det->isMasked(), false);
+                          spectrumInfo.isMasked(i), false);
       }
     }
 
diff --git a/Framework/DataHandling/test/MergeLogsTest.h b/Framework/DataHandling/test/MergeLogsTest.h
index 8ac64140c6f14de3f74643afc245c472e4bb5de2..2505be16c0275284792ce3e12eff9b46efbda343 100644
--- a/Framework/DataHandling/test/MergeLogsTest.h
+++ b/Framework/DataHandling/test/MergeLogsTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/NXcanSASTestHelper.cpp b/Framework/DataHandling/test/NXcanSASTestHelper.cpp
index 699907701a65cd4eba4de3e66f53c3be26c18988..7598619c6a8129561137fed8f60f368243701cfe 100644
--- a/Framework/DataHandling/test/NXcanSASTestHelper.cpp
+++ b/Framework/DataHandling/test/NXcanSASTestHelper.cpp
@@ -79,10 +79,10 @@ Mantid::API::MatrixWorkspace_sptr
 provide1DWorkspace(NXcanSASTestParameters &parameters) {
   Mantid::API::MatrixWorkspace_sptr ws;
   if (parameters.hasDx) {
-    ws = WorkspaceCreationHelper::Create1DWorkspaceConstantWithXerror(
+    ws = WorkspaceCreationHelper::create1DWorkspaceConstantWithXerror(
         parameters.size, parameters.value, parameters.error, parameters.xerror);
   } else {
-    ws = WorkspaceCreationHelper::Create1DWorkspaceConstant(
+    ws = WorkspaceCreationHelper::create1DWorkspaceConstant(
         parameters.size, parameters.value, parameters.error);
   }
 
@@ -114,7 +114,7 @@ provide1DWorkspace(NXcanSASTestParameters &parameters) {
 
 Mantid::API::MatrixWorkspace_sptr
 getTransmissionWorkspace(NXcanSASTestTransmissionParameters &parameters) {
-  auto ws = WorkspaceCreationHelper::Create1DWorkspaceConstant(
+  auto ws = WorkspaceCreationHelper::create1DWorkspaceConstant(
       parameters.size, parameters.value, parameters.error);
   ws->setTitle(parameters.name);
   ws->getAxis(0)->unit() =
diff --git a/Framework/DataHandling/test/PDLoadCharacterizationsTest.h b/Framework/DataHandling/test/PDLoadCharacterizationsTest.h
index 405365fb7333ead854e48518905ba0774afc29a3..d74a1ac87a3d5c254d70fa30393f7e2559fea8e9 100644
--- a/Framework/DataHandling/test/PDLoadCharacterizationsTest.h
+++ b/Framework/DataHandling/test/PDLoadCharacterizationsTest.h
@@ -4,6 +4,7 @@
 #include <boost/shared_ptr.hpp>
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 
 #include "MantidDataHandling/PDLoadCharacterizations.h"
diff --git a/Framework/DataHandling/test/RawFileInfoTest.h b/Framework/DataHandling/test/RawFileInfoTest.h
index 4e2fc9cc16e0b4f66d95dba9f82f9a5e1ac2186f..0afcdc16157ced33ed28bd38505532737f07617d 100644
--- a/Framework/DataHandling/test/RawFileInfoTest.h
+++ b/Framework/DataHandling/test/RawFileInfoTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/RawFileInfo.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 
 using namespace Mantid::DataHandling;
diff --git a/Framework/DataHandling/test/RemoveLogsTest.h b/Framework/DataHandling/test/RemoveLogsTest.h
index e179a08fbde45fd947818977efa09228d8188800..33f4f7762a2d59222932c71bdb52a08a5a44657d 100644
--- a/Framework/DataHandling/test/RemoveLogsTest.h
+++ b/Framework/DataHandling/test/RemoveLogsTest.h
@@ -118,7 +118,7 @@ private:
   void createSampleWorkspace() {
     // Create the workspace
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace(10, 100);
+        WorkspaceCreationHelper::create2DWorkspace(10, 100);
 
     // Add some log entries to it
     std::vector<DateAndTime> times;
diff --git a/Framework/DataHandling/test/RenameLogTest.h b/Framework/DataHandling/test/RenameLogTest.h
index dc218afb3634fd6d9da6ef7d54b8e5a9fd7e4ebc..56d1ead62dd403d5fd105ee80d2e7fd87e25a6fb 100644
--- a/Framework/DataHandling/test/RenameLogTest.h
+++ b/Framework/DataHandling/test/RenameLogTest.h
@@ -2,6 +2,7 @@
 #define MANTID_DATAHANDLING_RENAMELOGTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataHandling/test/RotateSourceTest.h b/Framework/DataHandling/test/RotateSourceTest.h
index f1a6c3f0e496be1e64cc38e5dad8477766b4f887..e87ac1f29b621e2e35b1b780ce05c84acadfc859 100644
--- a/Framework/DataHandling/test/RotateSourceTest.h
+++ b/Framework/DataHandling/test/RotateSourceTest.h
@@ -49,7 +49,7 @@ public:
     instr->markAsSamplePos(sample);
 
     // The workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 1);
     ws->setInstrument(instr);
     // The angle
     double theta = 90.;
@@ -88,7 +88,7 @@ public:
     instr->markAsSamplePos(sample);
 
     // The workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 1);
     ws->setInstrument(instr);
     // The angle
     double theta = -90.;
@@ -127,7 +127,7 @@ public:
     instr->markAsSamplePos(sample);
 
     // The workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 1);
     ws->setInstrument(instr);
     // The angle
     double theta = 90.;
@@ -166,7 +166,7 @@ public:
     instr->markAsSamplePos(sample);
 
     // The workspace
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 1);
     ws->setInstrument(instr);
     // The angle
     double theta = 90.;
@@ -186,4 +186,4 @@ public:
   }
 };
 
-#endif /* MANTID_DATAHANDLING_ROTATESOURCETEST_H_ */
\ No newline at end of file
+#endif /* MANTID_DATAHANDLING_ROTATESOURCETEST_H_ */
diff --git a/Framework/DataHandling/test/SaveANSTOAsciiTest.h b/Framework/DataHandling/test/SaveANSTOAsciiTest.h
index bdf6fd73cf974d226e2c0c958fbf1b0555a9538c..10da07d9748090a32ad2d6ce98dd345425d87a39 100644
--- a/Framework/DataHandling/test/SaveANSTOAsciiTest.h
+++ b/Framework/DataHandling/test/SaveANSTOAsciiTest.h
@@ -208,7 +208,7 @@ public:
 
 private:
   void createWS(bool zeroX = false, bool zeroY = false, bool zeroE = false) {
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     AnalysisDataService::Instance().addOrReplace(m_name, ws);
     // Check if any of X, Y or E should be zeroed to check for divide by zero or
     // similiar
diff --git a/Framework/DataHandling/test/SaveAsciiTest.h b/Framework/DataHandling/test/SaveAsciiTest.h
index ac20d16588e8eddc1d9bab9fd112fc424fb87129..ada5c579b7e42b493036347766456c56cd21df13 100644
--- a/Framework/DataHandling/test/SaveAsciiTest.h
+++ b/Framework/DataHandling/test/SaveAsciiTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidDataHandling/SaveAscii.h"
 #include "MantidDataObjects/Workspace2D.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include <fstream>
diff --git a/Framework/DataHandling/test/SaveCalFileTest.h b/Framework/DataHandling/test/SaveCalFileTest.h
index cdd7025bb62c4c66ac33de8ed84cc96ef0be0039..9d0d643b19622b7e75b4dfbe85bc58bbe55d1459 100644
--- a/Framework/DataHandling/test/SaveCalFileTest.h
+++ b/Framework/DataHandling/test/SaveCalFileTest.h
@@ -6,6 +6,7 @@
 #include "MantidDataObjects/GroupingWorkspace.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
 #include "MantidDataObjects/MaskWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
@@ -42,7 +43,8 @@ public:
     groupWS->setValue(3, 45);
     offsetsWS->setValue(1, 0.123);
     offsetsWS->setValue(2, 0.456);
-    maskWS->maskWorkspaceIndex(0);
+    maskWS->getSpectrum(0).clearData();
+    maskWS->mutableSpectrumInfo().setMasked(0, true);
 
     // Name of the output workspace.
     std::string outWSName("SaveCalFileTest_OutputWS");
diff --git a/Framework/DataHandling/test/SaveCanSAS1dTest.h b/Framework/DataHandling/test/SaveCanSAS1dTest.h
index 9a97b40ca9f6989e2fd2b94521b9379c3fe756d2..5a8fe2c988e978398e14f42807a744d60e2ace9b 100644
--- a/Framework/DataHandling/test/SaveCanSAS1dTest.h
+++ b/Framework/DataHandling/test/SaveCanSAS1dTest.h
@@ -4,6 +4,7 @@
 
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/Sample.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadRaw3.h"
 #include "MantidDataHandling/SaveCanSAS1D.h"
 #include "MantidDataHandling/LoadCanSAS1D.h"
diff --git a/Framework/DataHandling/test/SaveCanSAS1dTest2.h b/Framework/DataHandling/test/SaveCanSAS1dTest2.h
index 8cb991cee58ea205c4abe9c11c36055093884ebf..cb77fe952f53a6a5e0f8ca24daf1da3046d1d1d1 100644
--- a/Framework/DataHandling/test/SaveCanSAS1dTest2.h
+++ b/Framework/DataHandling/test/SaveCanSAS1dTest2.h
@@ -3,6 +3,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataHandling/LoadRaw3.h"
 #include "MantidDataHandling/SaveCanSAS1D2.h"
 #include "MantidDataHandling/LoadCanSAS1D.h"
diff --git a/Framework/DataHandling/test/SaveDaveGrpTest.h b/Framework/DataHandling/test/SaveDaveGrpTest.h
index 2a6270882a332b5b637cf1c9dec01a50c8008eaa..ef9616f8956ff2c26bb96b4936e38cc587ee8b7a 100644
--- a/Framework/DataHandling/test/SaveDaveGrpTest.h
+++ b/Framework/DataHandling/test/SaveDaveGrpTest.h
@@ -267,7 +267,7 @@ private:
     // all the Y values in this new workspace are set to DEFAU_Y, which
     // currently = 2
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(2, 3, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(2, 3, 1.0);
     inputWS->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("DeltaE");
     AnalysisDataService::Instance().add(input, inputWS);
diff --git a/Framework/DataHandling/test/SaveDetectorsGroupingTest.h b/Framework/DataHandling/test/SaveDetectorsGroupingTest.h
index 79ee211d051c482e58ea66dca02e3e4a1b49501d..7ab63236a7e661b38ce15fe028bcf5ce7ad3b560 100644
--- a/Framework/DataHandling/test/SaveDetectorsGroupingTest.h
+++ b/Framework/DataHandling/test/SaveDetectorsGroupingTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 
 #include "MantidDataHandling/SaveDetectorsGrouping.h"
diff --git a/Framework/DataHandling/test/SaveDiffCalTest.h b/Framework/DataHandling/test/SaveDiffCalTest.h
index 0b0d52e967b61f1d0afa676bac39246496cb08a1..3aa6f969260c2e1c28e332cfec1b8e99b92b217e 100644
--- a/Framework/DataHandling/test/SaveDiffCalTest.h
+++ b/Framework/DataHandling/test/SaveDiffCalTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include <Poco/File.h>
 
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataHandling/SaveDiffCal.h"
 #include "MantidDataObjects/MaskWorkspace.h"
@@ -50,7 +51,8 @@ public:
 
   MaskWorkspace_sptr createMasking(Instrument_sptr instr) {
     MaskWorkspace_sptr maskWS = boost::make_shared<MaskWorkspace>(instr);
-    maskWS->maskWorkspaceIndex(0);
+    maskWS->getSpectrum(0).clearData();
+    maskWS->mutableSpectrumInfo().setMasked(0, true);
     return maskWS;
   }
 
diff --git a/Framework/DataHandling/test/SaveDspacemapTest.h b/Framework/DataHandling/test/SaveDspacemapTest.h
index 4b2bbffb535bd59aceb4cc4f44c27163f5ff21d5..1f7cdf6d5c888bbab84caed8e17f3b5a5dbc7e88 100644
--- a/Framework/DataHandling/test/SaveDspacemapTest.h
+++ b/Framework/DataHandling/test/SaveDspacemapTest.h
@@ -4,6 +4,7 @@
 #include "MantidDataHandling/SaveDspacemap.h"
 #include "MantidDataHandling/LoadDspacemap.h"
 #include "MantidDataObjects/OffsetsWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
diff --git a/Framework/DataHandling/test/SaveFITSTest.h b/Framework/DataHandling/test/SaveFITSTest.h
index e0e6c0d9fd4f6a4ce2cff600bdd1f203af87097e..479da0f6104ee55be857d6d41975e1cca477e5fa 100644
--- a/Framework/DataHandling/test/SaveFITSTest.h
+++ b/Framework/DataHandling/test/SaveFITSTest.h
@@ -8,6 +8,7 @@
 #include "MantidAPI/NumericAxis.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -70,7 +71,7 @@ public:
   void test_exec_fails_units() {
     const std::string filename = "./savefits_wont_work.fits";
 
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(2, 2);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(2, 2);
 
     SaveFITS alg;
     TS_ASSERT_THROWS_NOTHING(alg.initialize())
@@ -102,7 +103,7 @@ public:
     const std::string filename = "./savefits_simple_test.fits";
 
     // create with appropriate units
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(2, 2);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(2, 2);
     auto lbl = boost::dynamic_pointer_cast<Mantid::Kernel::Units::Label>(
         Mantid::Kernel::UnitFactory::Instance().create("Label"));
     lbl->setLabel("width", "cm");
diff --git a/Framework/DataHandling/test/SaveFocussedXYETest.h b/Framework/DataHandling/test/SaveFocussedXYETest.h
index 644263939ca1065d4df721de205f76f6da188ef5..7f3717eea1176a55517453b6df9bc3fd13351f73 100644
--- a/Framework/DataHandling/test/SaveFocussedXYETest.h
+++ b/Framework/DataHandling/test/SaveFocussedXYETest.h
@@ -7,6 +7,7 @@
 
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidAPI/Axis.h"
@@ -33,7 +34,7 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
     Workspace2D_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     workspace->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
@@ -94,27 +95,27 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
     Workspace2D_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     workspace->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     work_in1->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     work_in2->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     work_in3->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in4 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 1.0);
     work_in4->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
@@ -190,27 +191,27 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
     Workspace2D_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     workspace->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     work_in1->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in2 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     work_in2->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in3 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     work_in3->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in4 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     work_in4->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
@@ -293,12 +294,12 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
     Workspace2D_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     workspace->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
     Workspace2D_sptr work_in1 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 3, 1.0, 2.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 3, 1.0, 2.0);
     work_in1->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
@@ -370,7 +371,7 @@ public:
     using namespace Mantid::API;
     using namespace Mantid::DataObjects;
     Workspace2D_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspace154(1, 3, false);
+        WorkspaceCreationHelper::create2DWorkspace154(1, 3, false);
     workspace->getAxis(0)->unit() =
         Mantid::Kernel::UnitFactory::Instance().create("TOF");
 
diff --git a/Framework/DataHandling/test/SaveFullprofResolutionTest.h b/Framework/DataHandling/test/SaveFullprofResolutionTest.h
index 20a011731a5a1d2c3d35f9fbe2359347c4356141..a669312e586b0f4e87687750b19875cdc85e22a4 100644
--- a/Framework/DataHandling/test/SaveFullprofResolutionTest.h
+++ b/Framework/DataHandling/test/SaveFullprofResolutionTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/SaveFullprofResolution.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 
 #include <Poco/File.h>
diff --git a/Framework/DataHandling/test/SaveGSASInstrumentFileTest.h b/Framework/DataHandling/test/SaveGSASInstrumentFileTest.h
index 26afed98e80782a8b1e2d03dd7de71be2ef794fb..7ef028aeaf2c9aac6d6f13fa3e7a55d35404b12a 100644
--- a/Framework/DataHandling/test/SaveGSASInstrumentFileTest.h
+++ b/Framework/DataHandling/test/SaveGSASInstrumentFileTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/SaveGSASInstrumentFile.h"
 #include "MantidDataObjects/TableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/FrameworkManager.h"
 
diff --git a/Framework/DataHandling/test/SaveGSSTest.h b/Framework/DataHandling/test/SaveGSSTest.h
index c5bfd1be54cfd1c880136e90cec58bd676416d21..8938025b6a334ba1bf9837e3c55b0876ef0ba41b 100644
--- a/Framework/DataHandling/test/SaveGSSTest.h
+++ b/Framework/DataHandling/test/SaveGSSTest.h
@@ -274,7 +274,7 @@ private:
     */
   API::MatrixWorkspace_sptr generateNoInstrumentWorkspace() {
     MatrixWorkspace_sptr dataws =
-        WorkspaceCreationHelper::Create2DWorkspace(2, 100);
+        WorkspaceCreationHelper::create2DWorkspace(2, 100);
     dataws->getAxis(0)->setUnit("TOF");
 
     // Set data with logarithm bin
diff --git a/Framework/DataHandling/test/SaveILLCosmosAsciiTest.h b/Framework/DataHandling/test/SaveILLCosmosAsciiTest.h
index 76050d288a48e3334b3ab572e32c6c6e9f2e23d8..120411c23c2e9f64bb9e450e61584add154914a4 100644
--- a/Framework/DataHandling/test/SaveILLCosmosAsciiTest.h
+++ b/Framework/DataHandling/test/SaveILLCosmosAsciiTest.h
@@ -268,7 +268,7 @@ private:
   }
   void createWS(bool zeroX = false, bool zeroY = false, bool zeroE = false,
                 bool createLogs = false) {
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
 
     if (createLogs) {
       ws->mutableRun().addProperty("run_title",
diff --git a/Framework/DataHandling/test/SaveMaskTest.h b/Framework/DataHandling/test/SaveMaskTest.h
index 5f10a4447ccef6b98b2b9c928784e0fe429e8742..6f60f7ab994380d05f79706c307048a862d01325 100644
--- a/Framework/DataHandling/test/SaveMaskTest.h
+++ b/Framework/DataHandling/test/SaveMaskTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 #include "MantidDataHandling/SaveMask.h"
 #include "MantidDataHandling/LoadMask.h"
diff --git a/Framework/DataHandling/test/SaveNXSPETest.h b/Framework/DataHandling/test/SaveNXSPETest.h
index c947bc4aa6de357be0d8a16908fec1dd01f1fb07..dd9667c75969ac19ef0a6ec119ccf893395d8185 100644
--- a/Framework/DataHandling/test/SaveNXSPETest.h
+++ b/Framework/DataHandling/test/SaveNXSPETest.h
@@ -6,6 +6,7 @@
 #include "MantidDataHandling/SaveNXSPE.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidDataHandling/LoadInstrument.h"
@@ -28,7 +29,7 @@ using Mantid::Geometry::ParameterMap;
 using Mantid::Geometry::Instrument;
 using Mantid::Geometry::IDetector_const_sptr;
 
-static const int THEMASKED = 2;
+static const int THEMASKED = 1;
 
 class SaveNXSPETest : public CxxTest::TestSuite {
 public:
@@ -129,7 +130,7 @@ public:
 private:
   MatrixWorkspace_sptr makeWorkspace(int nhist = 3, int nx = 10) {
     auto testWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, nx, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, nx, 1.0);
     // Fill workspace with increasing counter to properly check saving
     for (int i = 0; i < nhist; ++i) {
       auto &outY = testWS->dataY(i);
@@ -153,11 +154,7 @@ private:
     inputWS->setInstrument(testInst);
 
     // mask the detector
-    ParameterMap *m_Pmap = &(inputWS->instrumentParameters());
-    boost::shared_ptr<const Instrument> instru = inputWS->getInstrument();
-    IDetector_const_sptr toMask = instru->getDetector(THEMASKED);
-    TS_ASSERT(toMask);
-    m_Pmap->addBool(toMask.get(), "masked", true);
+    inputWS->mutableDetectorInfo().setMasked(THEMASKED, true);
 
     // required to get it passed the algorthms validator
     inputWS->setDistribution(true);
diff --git a/Framework/DataHandling/test/SaveNXTomoTest.h b/Framework/DataHandling/test/SaveNXTomoTest.h
index 94af06a174b99dfd9ce4f22eafcdaebfb003c1ce..0dc750e2dcf7b25849288e3d0c44ee0dccb043f9 100644
--- a/Framework/DataHandling/test/SaveNXTomoTest.h
+++ b/Framework/DataHandling/test/SaveNXTomoTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/SaveNXTomo.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include <Poco/File.h>
 
@@ -186,7 +187,7 @@ public:
 private:
   Workspace_sptr makeWorkspaceSingle(const std::string &input) {
     // Create a single workspace
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspaceBinned(
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspaceBinned(
         m_axisSize * m_axisSize, 1, 1.0);
     ws->setTitle(input);
 
@@ -227,11 +228,11 @@ private:
 
     for (uint32_t i = 0; i < static_cast<uint32_t>(wspaces.size()); ++i) {
       if (specPerRow) {
-        wspaces[i] = WorkspaceCreationHelper::Create2DWorkspaceBinned(
+        wspaces[i] = WorkspaceCreationHelper::create2DWorkspaceBinned(
             m_axisSize, m_axisSize + 1, 1.0);
 
       } else {
-        wspaces[i] = WorkspaceCreationHelper::Create2DWorkspaceBinned(
+        wspaces[i] = WorkspaceCreationHelper::create2DWorkspaceBinned(
             m_axisSize * m_axisSize, 1, 1.0);
       }
       wspaces[i]->setTitle(
diff --git a/Framework/DataHandling/test/SaveNXcanSASTest.h b/Framework/DataHandling/test/SaveNXcanSASTest.h
index b1b8efb46f91e27f83b5cc460d7926727b621357..9e9246d6a5761cbb33a9c6fb20ffbfeb74dff750 100644
--- a/Framework/DataHandling/test/SaveNXcanSASTest.h
+++ b/Framework/DataHandling/test/SaveNXcanSASTest.h
@@ -39,7 +39,7 @@ public:
 
   void test_that_workspace_without_momentum_transfer_units_is_invalid() {
     // Arrange
-    auto ws = WorkspaceCreationHelper::Create1DWorkspaceConstantWithXerror(
+    auto ws = WorkspaceCreationHelper::create1DWorkspaceConstantWithXerror(
         10 /*size*/, 1.23 /*value&*/, 2.3 /*error*/, 23.4 /*xerror*/);
     const std::string filename = "SaveNXcanSASTestFile.h5";
 
diff --git a/Framework/DataHandling/test/SaveNexusProcessedTest.h b/Framework/DataHandling/test/SaveNexusProcessedTest.h
index 7d41de5f3495554c4cb3e4e48c4769e26e009d77..d30fd9786becd426564ce6a953a54b33d45dccf1 100644
--- a/Framework/DataHandling/test/SaveNexusProcessedTest.h
+++ b/Framework/DataHandling/test/SaveNexusProcessedTest.h
@@ -11,6 +11,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/ScopedWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataHandling/LoadEventPreNexus.h"
@@ -18,6 +19,8 @@
 #include "MantidDataHandling/SaveNexusProcessed.h"
 #include "MantidDataHandling/LoadMuonNexus.h"
 #include "MantidDataHandling/LoadNexus.h"
+#include "MantidKernel/Strings.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidDataHandling/LoadRaw3.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -246,7 +249,7 @@ public:
     groups[4].push_back(50);
 
     EventWorkspace_sptr WS =
-        WorkspaceCreationHelper::CreateGroupedEventWorkspace(groups, 100, 1.0,
+        WorkspaceCreationHelper::createGroupedEventWorkspace(groups, 100, 1.0,
                                                              1.0);
     WS->getSpectrum(3).clear(false);
     // Switch the event type
@@ -399,7 +402,7 @@ public:
     const int nBins = 1;
     const std::string stem = "test_group_ws";
     Mantid::API::WorkspaceGroup_sptr group_ws =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(nEntries, nHist, nBins,
+        WorkspaceCreationHelper::createWorkspaceGroup(nEntries, nHist, nBins,
                                                       stem);
 
     SaveNexusProcessed alg;
diff --git a/Framework/DataHandling/test/SaveNexusTest.h b/Framework/DataHandling/test/SaveNexusTest.h
index 9ad2e790b21a055d9682bfb5c32b510b49418565..fd6b682e6ecc95c5556b335f4448e4963a86a8fa 100644
--- a/Framework/DataHandling/test/SaveNexusTest.h
+++ b/Framework/DataHandling/test/SaveNexusTest.h
@@ -90,7 +90,7 @@ public:
   }
 
   void test_pass_inputworkspace_as_pointer() {
-    Workspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace123(2, 5);
+    Workspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace123(2, 5);
 
     SaveNexus alg;
     alg.initialize();
diff --git a/Framework/DataHandling/test/SavePARTest.h b/Framework/DataHandling/test/SavePARTest.h
index 161145e1cfbea10893ec3a4668b3ed9b614143cb..174c1f0adbb02cade72921d29289cc33896dde62 100644
--- a/Framework/DataHandling/test/SavePARTest.h
+++ b/Framework/DataHandling/test/SavePARTest.h
@@ -140,7 +140,7 @@ private:
     // all the Y values in this new workspace are set to DEFAU_Y, which
     // currently = 2
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(NHIST, 10, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(NHIST, 10, 1.0);
     return setUpWorkspace(input, inputWS);
   }
 
@@ -163,13 +163,6 @@ private:
     loader.setPropertyValue("Workspace", input);
     loader.execute();
 
-    // mask the detector
-    Geometry::ParameterMap *m_Pmap = &(inputWS->instrumentParameters());
-    boost::shared_ptr<const Instrument> instru = inputWS->getInstrument();
-    Geometry::IDetector_const_sptr toMask = instru->getDetector(THEMASKED);
-    TS_ASSERT(toMask);
-    m_Pmap->addBool(toMask.get(), "masked", true);
-
     // required to get it passed the algorthms validator
     inputWS->setDistribution(true);
 
diff --git a/Framework/DataHandling/test/SavePDFGuiTest.h b/Framework/DataHandling/test/SavePDFGuiTest.h
index 5df40229c4d6f376811fd68b9900c8d0d7189283..ac70b524ca84af8acbe3b43dd67021b74798f274 100644
--- a/Framework/DataHandling/test/SavePDFGuiTest.h
+++ b/Framework/DataHandling/test/SavePDFGuiTest.h
@@ -6,6 +6,7 @@
 #include <fstream>
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidDataHandling/SavePDFGui.h"
 #include "MantidDataHandling/LoadNexusProcessed.h"
 
diff --git a/Framework/DataHandling/test/SavePHXTest.h b/Framework/DataHandling/test/SavePHXTest.h
index 7192560c4d9f2a002174350d3faf0bd1b7b4b5e2..22975866981084d1a550e27a12f2d9c295839d4b 100644
--- a/Framework/DataHandling/test/SavePHXTest.h
+++ b/Framework/DataHandling/test/SavePHXTest.h
@@ -170,7 +170,7 @@ private:
     // all the Y values in this new workspace are set to DEFAU_Y, which
     // currently = 2
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(NHIST, 10, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(NHIST, 10, 1.0);
     return setUpWorkspace(input, inputWS);
   }
 
@@ -193,13 +193,6 @@ private:
     loader.setProperty("RewriteSpectraMap", Mantid::Kernel::OptionalBool(true));
     loader.execute();
 
-    // mask the detector
-    Geometry::ParameterMap *m_Pmap = &(inputWS->instrumentParameters());
-    boost::shared_ptr<const Instrument> instru = inputWS->getInstrument();
-    Geometry::IDetector_const_sptr toMask = instru->getDetector(THEMASKED);
-    TS_ASSERT(toMask)
-    m_Pmap->addBool(toMask.get(), "masked", true);
-
     // required to get it passed the algorthms validator
     inputWS->setDistribution(true);
 
diff --git a/Framework/DataHandling/test/SaveParameterFileTest.h b/Framework/DataHandling/test/SaveParameterFileTest.h
index 6ce13bf6c081ad934ac9aed300182df64b8719b7..8f201b814036b5cc29862adbf70d9bacef29d4ea 100644
--- a/Framework/DataHandling/test/SaveParameterFileTest.h
+++ b/Framework/DataHandling/test/SaveParameterFileTest.h
@@ -15,7 +15,9 @@
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidGeometry/Instrument/Component.h"
+#include "MantidGeometry/Instrument/ParameterFactory.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/StringTokenizer.h"
 #include "MantidTestHelpers/ScopedFileHelper.h"
 
 using namespace Mantid::API;
diff --git a/Framework/DataHandling/test/SaveRKHTest.h b/Framework/DataHandling/test/SaveRKHTest.h
index 75f1e0a56efc76ff1cd31d5eab15fafb4221c2b6..6f4997268a0f54758ba8ba96197b8e264d1242bc 100644
--- a/Framework/DataHandling/test/SaveRKHTest.h
+++ b/Framework/DataHandling/test/SaveRKHTest.h
@@ -45,7 +45,7 @@ public:
     TS_ASSERT_THROWS(testAlgorithm1.execute(), std::runtime_error);
     // Need a test workspace to use as input
     MatrixWorkspace_sptr inputWS1 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 10, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 10, 1.0);
     inputWS1->setDistribution(true);
 
     // Register workspace
@@ -114,7 +114,7 @@ public:
 
     using namespace Mantid::API;
     MatrixWorkspace_sptr inputWS2 =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 1, 0.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 1, 0.0);
     inputWS2->setDistribution(true);
     // Register workspace
     AnalysisDataService::Instance().add("testInputTwo", inputWS2);
diff --git a/Framework/DataHandling/test/SaveReflCustomAsciiTest.h b/Framework/DataHandling/test/SaveReflCustomAsciiTest.h
index e7befc92f7e13cdd38acd8a36d3a631d91fac7e0..5a8f7f49642c935c75ebba87b1388b0b9e44a165 100644
--- a/Framework/DataHandling/test/SaveReflCustomAsciiTest.h
+++ b/Framework/DataHandling/test/SaveReflCustomAsciiTest.h
@@ -233,7 +233,7 @@ private:
   void createWS(bool zeroX = false, bool zeroY = false, bool zeroE = false,
                 bool createLogs = false) {
     createLogs = false;
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     AnalysisDataService::Instance().addOrReplace(m_name, ws);
     // Check if any of X, Y or E should be zeroed to check for divide by zero or
     // similiar
diff --git a/Framework/DataHandling/test/SaveReflThreeColumnAsciiTest.h b/Framework/DataHandling/test/SaveReflThreeColumnAsciiTest.h
index 73a89d0228ae30bfd400e2378b8996cf5fc3c486..b9c1e96e8b61d6c584f36da396e642c58620cc5b 100644
--- a/Framework/DataHandling/test/SaveReflThreeColumnAsciiTest.h
+++ b/Framework/DataHandling/test/SaveReflThreeColumnAsciiTest.h
@@ -213,7 +213,7 @@ public:
 
 private:
   void createWS(bool zeroX = false, bool zeroY = false, bool zeroE = false) {
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     AnalysisDataService::Instance().addOrReplace(m_name, ws);
     // Check if any of X, Y or E should be zeroed to check for divide by zero or
     // similiar
diff --git a/Framework/DataHandling/test/SaveSPETest.h b/Framework/DataHandling/test/SaveSPETest.h
index f42344b45a67297e002f0c4acb73c7de6b0628d1..a59e61ae980ee52a050552ce2f7daacf9454c663 100644
--- a/Framework/DataHandling/test/SaveSPETest.h
+++ b/Framework/DataHandling/test/SaveSPETest.h
@@ -5,6 +5,7 @@
 
 #include "MantidDataHandling/SaveSPE.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidDataHandling/LoadInstrument.h"
@@ -27,7 +28,7 @@ static const double MASK_FLAG =
 static const double MASK_ERROR = 0.0;
 
 static const int NHIST = 3;
-static const int THEMASKED = 2;
+static const int THEMASKED = 1;
 static const int DEFAU_Y = 2;
 
 class SaveSPETest : public CxxTest::TestSuite {
@@ -91,7 +92,7 @@ public:
          ++i) { // if the spectrum number (1+index number) is that of the masked
                 // spectrum look for the mask flag, otherwise value in the
                 // workspace
-      double value = i + 1 != THEMASKED ? DEFAU_Y : MASK_FLAG;
+      double value = i != THEMASKED ? DEFAU_Y : MASK_FLAG;
 
       getline(file, tmp);
       TS_ASSERT_EQUALS(tmp, "### S(Phi,w)")
@@ -102,7 +103,7 @@ public:
       TS_ASSERT_EQUALS(tmp2, value)
       getline(file, tmp);
 
-      double error = i + 1 != THEMASKED ? M_SQRT2 : MASK_ERROR;
+      double error = i != THEMASKED ? M_SQRT2 : MASK_ERROR;
       getline(file, tmp);
       TS_ASSERT_EQUALS(tmp, "### Errors")
       file >> tmp2;
@@ -148,7 +149,7 @@ private:
     // all the Y values in this new workspace are set to DEFAU_Y, which
     // currently = 2
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(NHIST, 10, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(NHIST, 10, 1.0);
     return setUpWorkspace(input, inputWS);
   }
 
@@ -156,7 +157,7 @@ private:
     // all the Y values in this new workspace are set to DEFAU_Y, which
     // currently = 2
     MatrixWorkspace_sptr inputWS =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(NHIST, 10, 1.0);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(NHIST, 10, 1.0);
     inputWS = setUpWorkspace(input, inputWS);
     API::Axis *axisOne = inputWS->getAxis(1);
     API::NumericAxis *newAxisOne = new NumericAxis(axisOne->length());
@@ -187,11 +188,7 @@ private:
     loader.execute();
 
     // mask the detector
-    Geometry::ParameterMap *m_Pmap = &(inputWS->instrumentParameters());
-    boost::shared_ptr<const Instrument> instru = inputWS->getInstrument();
-    Geometry::IDetector_const_sptr toMask = instru->getDetector(THEMASKED);
-    TS_ASSERT(toMask);
-    m_Pmap->addBool(toMask.get(), "masked", true);
+    inputWS->mutableDetectorInfo().setMasked(THEMASKED, true);
 
     // required to get it passed the algorthms validator
     inputWS->setDistribution(true);
diff --git a/Framework/DataHandling/test/SaveTBLTest.h b/Framework/DataHandling/test/SaveTBLTest.h
index 7ad8c2c2bb693939159e9a8d2825b33631d647da..16b68d03ced4e7f155fd61e854c46b6fbf57d70f 100644
--- a/Framework/DataHandling/test/SaveTBLTest.h
+++ b/Framework/DataHandling/test/SaveTBLTest.h
@@ -2,6 +2,7 @@
 #define SAVETBLTEST_H_
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/TableRow.h"
diff --git a/Framework/DataHandling/test/SetBeamTest.h b/Framework/DataHandling/test/SetBeamTest.h
index a0261731dcf253ba80028c0863522260a16a2b78..f52cba707891a0c3f685c40669cbf5750ae4c14e 100644
--- a/Framework/DataHandling/test/SetBeamTest.h
+++ b/Framework/DataHandling/test/SetBeamTest.h
@@ -27,7 +27,7 @@ public:
   }
 
   void test_Beam_Size_Parameters_Stored_On_Instrument_Source() {
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto testInst = ComponentCreationHelper::createTestInstrumentCylindrical(1);
     inputWS->setInstrument(testInst);
 
@@ -52,7 +52,7 @@ public:
   // Failure tests
   //----------------------------------------------------------------------------
   void test_Workspace_Without_Instrument_Not_Accepted() {
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     TS_ASSERT_THROWS(alg->setProperty("InputWorkspace", inputWS),
@@ -60,7 +60,7 @@ public:
   }
 
   void test_No_Geometry_Inputs_Not_Accepted() {
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto testInst = ComponentCreationHelper::createTestInstrumentCylindrical(1);
     inputWS->setInstrument(testInst);
 
@@ -71,7 +71,7 @@ public:
 
   void test_Missing_Geometry_Inputs_Not_Accepted() {
     using Mantid::Kernel::PropertyManager;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto testInst = ComponentCreationHelper::createTestInstrumentCylindrical(1);
     inputWS->setInstrument(testInst);
 
diff --git a/Framework/DataHandling/test/SetSampleTest.h b/Framework/DataHandling/test/SetSampleTest.h
index 30f03645579a3341be047486279eec0c1a1d0382..e90effc98c62d4b76210beb0e04c5ce144ba6161 100644
--- a/Framework/DataHandling/test/SetSampleTest.h
+++ b/Framework/DataHandling/test/SetSampleTest.h
@@ -86,7 +86,7 @@ public:
   }
 
   void test_Setting_Material_Alone_Only_Overwrites_Material() {
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto sampleShape = ComponentCreationHelper::createSphere(0.5);
     sampleShape->setID("mysample");
     inputWS->mutableSample().setShape(*sampleShape);
@@ -108,7 +108,7 @@ public:
     using Mantid::Kernel::Material;
     using Mantid::PhysicalConstants::getNeutronAtom;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto sampleShape = ComponentCreationHelper::createSphere(0.5);
     sampleShape->setID("mysample");
     Material alum("Al", getNeutronAtom(13), 2.6989);
@@ -133,7 +133,7 @@ public:
     using Mantid::Kernel::ConfigService;
     using Mantid::Geometry::SampleEnvironment;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto testInst = ComponentCreationHelper::createTestInstrumentCylindrical(1);
     testInst->setName(m_instName);
     inputWS->setInstrument(testInst);
@@ -165,7 +165,7 @@ public:
     using Mantid::Kernel::ConfigService;
     using Mantid::Geometry::SampleEnvironment;
 
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
     auto testInst = ComponentCreationHelper::createTestInstrumentCylindrical(1);
     testInst->setName(m_instName);
     inputWS->setInstrument(testInst);
@@ -200,7 +200,7 @@ public:
 
   void test_Setting_Geometry_As_FlatPlate() {
     using Mantid::Kernel::V3D;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -220,7 +220,7 @@ public:
 
   void test_Setting_Geometry_As_Cylinder() {
     using Mantid::Kernel::V3D;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -242,7 +242,7 @@ public:
 
   void test_Setting_Geometry_As_HollowCylinder() {
     using Mantid::Kernel::V3D;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -266,7 +266,7 @@ public:
   void test_Environment_Args_Without_Name_Invalid() {
     using Mantid::Kernel::PropertyManager;
     using StringProperty = Mantid::Kernel::PropertyWithValue<std::string>;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -281,7 +281,7 @@ public:
   void test_Environment_Args_Without_Container_Invalid() {
     using Mantid::Kernel::PropertyManager;
     using StringProperty = Mantid::Kernel::PropertyWithValue<std::string>;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -296,7 +296,7 @@ public:
   void test_Environment_Args_With_Empty_Strings_Invalid() {
     using Mantid::Kernel::PropertyManager;
     using StringProperty = Mantid::Kernel::PropertyWithValue<std::string>;
-    auto inputWS = WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 1);
+    auto inputWS = WorkspaceCreationHelper::create2DWorkspaceBinned(1, 1);
 
     auto alg = createAlgorithm();
     alg->setProperty("InputWorkspace", inputWS);
@@ -399,7 +399,7 @@ private:
     using namespace Mantid::Kernel;
     using DoubleArrayProperty = ArrayProperty<double>;
     using DoubleProperty = PropertyWithValue<double>;
-    using IntProperty = PropertyWithValue<long>;
+    using IntProperty = PropertyWithValue<int64_t>;
     using StringProperty = PropertyWithValue<std::string>;
 
     auto props = boost::make_shared<PropertyManager>();
@@ -422,7 +422,7 @@ private:
     using namespace Mantid::Kernel;
     using DoubleArrayProperty = ArrayProperty<double>;
     using DoubleProperty = PropertyWithValue<double>;
-    using IntProperty = PropertyWithValue<long>;
+    using IntProperty = PropertyWithValue<int64_t>;
     using StringProperty = PropertyWithValue<std::string>;
 
     auto props = boost::make_shared<PropertyManager>();
diff --git a/Framework/DataHandling/test/SortTableWorkspaceTest.h b/Framework/DataHandling/test/SortTableWorkspaceTest.h
index fcacba9e05005ed3663f986ec5925b959002e3ee..0db8cee09545ad13712010fffe18c9a3e058ae12 100644
--- a/Framework/DataHandling/test/SortTableWorkspaceTest.h
+++ b/Framework/DataHandling/test/SortTableWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidDataHandling/SortTableWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/TableRow.h"
diff --git a/Framework/DataHandling/test/UpdateInstrumentFromFileTest.h b/Framework/DataHandling/test/UpdateInstrumentFromFileTest.h
index 9dcfc5c1a7502741ccf4420bfa6954d394815109..3e2a90ea577d1e3692d062fa7958952d796b25ab 100644
--- a/Framework/DataHandling/test/UpdateInstrumentFromFileTest.h
+++ b/Framework/DataHandling/test/UpdateInstrumentFromFileTest.h
@@ -8,6 +8,7 @@
 #include "MantidDataHandling/LoadInstrumentFromNexus.h"
 #include "MantidDataHandling/LoadInstrument.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/InstrumentDataService.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/DataObjects/CMakeLists.txt b/Framework/DataObjects/CMakeLists.txt
index 9dca3c23c31a1beabb0a11f7c8ab9d3fa0b963b8..7184dae6b3753aee838959cd73ea34aa13015bab 100644
--- a/Framework/DataObjects/CMakeLists.txt
+++ b/Framework/DataObjects/CMakeLists.txt
@@ -36,6 +36,7 @@ set ( SRC_FILES
 	src/PeakShapeSpherical.cpp
 	src/PeakShapeSphericalFactory.cpp
 	src/PeaksWorkspace.cpp
+	src/PropertyWithValue.cpp
 	src/RebinnedOutput.cpp
 	src/ReflectometryTransform.cpp
 	src/SpecialWorkspace2D.cpp
@@ -45,6 +46,7 @@ set ( SRC_FILES
 	src/VectorColumn.cpp
 	src/Workspace2D.cpp
 	src/WorkspaceCreation.cpp
+	src/WorkspaceProperty.cpp
 	src/WorkspaceSingleValue.cpp
 )
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/EventList.h b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
index c2557fe1b0afbdbe5a26bc48f014f8784bc40812..b78a1098da6efb3672dbcdaf387638f511195eb7 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/EventList.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/EventList.h
@@ -6,18 +6,19 @@
 #endif
 #include "MantidAPI/IEventList.h"
 #include "MantidDataObjects/Events.h"
-#include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/MultiThreaded.h"
 #include "MantidKernel/System.h"
-#include "MantidKernel/TimeSplitter.h"
-#include "MantidKernel/Unit.h"
 #include "MantidKernel/cow_ptr.h"
-#include <cstddef>
 #include <iosfwd>
-#include <set>
 #include <vector>
 
 namespace Mantid {
+namespace Kernel {
+class DateAndTime;
+class SplittingInterval;
+typedef std::vector<SplittingInterval> TimeSplitterType;
+class Unit;
+}
 namespace DataObjects {
 class EventWorkspaceMRU;
 
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
index 2f7c3d4611880cbc978f31b934aecb7403300be7..4db8da03a56159193e041a491bd12370ffa2724b 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
@@ -19,6 +19,7 @@
 #include "MantidKernel/ConfigService.h"
 
 #include <iomanip>
+#include <iostream>
 #include <functional>
 #include <algorithm>
 #include "MantidDataObjects/MDBoxIterator.h"
@@ -920,7 +921,7 @@ TMDE(API::IMDWorkspace::LinePlot MDEventWorkspace)
   }
 
   // If everything was masked
-  if (line.x.size() == 0) {
+  if (line.x.empty()) {
     makeSinglePointWithNaN(line.x, line.y, line.e);
   }
   return line;
diff --git a/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h b/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h
index 2833c272232b313e357f7854965e2c0b71b9b3fd..26c868a2bc38d50ad5139c8a95ca6214ba2afc53 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/VectorColumn.h
@@ -80,8 +80,7 @@ public:
     Mantid::Kernel::StringTokenizer elements(
         text, ",", Mantid::Kernel::StringTokenizer::TOK_TRIM);
 
-    for (const auto &it : elements) {
-      std::string element(it);
+    for (const auto &element : elements) {
       try {
         newValues.push_back(boost::lexical_cast<Type>(element));
       } catch (boost::bad_lexical_cast &) {
diff --git a/Framework/DataObjects/src/BoxControllerNeXusIO.cpp b/Framework/DataObjects/src/BoxControllerNeXusIO.cpp
index 89fffca154c889810544ff5e475f8ca27fb763a8..7f26a67ee27d49b1cb415cb0c772db0452639174 100644
--- a/Framework/DataObjects/src/BoxControllerNeXusIO.cpp
+++ b/Framework/DataObjects/src/BoxControllerNeXusIO.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidDataObjects/MDBoxFlatTree.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Exception.h"
 #include "MantidAPI/FileFinder.h"
 #include "MantidDataObjects/MDEvent.h"
diff --git a/Framework/DataObjects/src/EventList.cpp b/Framework/DataObjects/src/EventList.cpp
index c72612926d7b3c127f8e919829f2838726dc552f..5e35cd776a05fac1bd0c61de5ba55b6e722721bd 100644
--- a/Framework/DataObjects/src/EventList.cpp
+++ b/Framework/DataObjects/src/EventList.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Logger.h"
+#include "MantidKernel/Unit.h"
 #include <cfloat>
 
 #include <cmath>
diff --git a/Framework/DataObjects/src/EventWorkspace.cpp b/Framework/DataObjects/src/EventWorkspace.cpp
index d7404dbd4dfa9fda20e33be991d21a2de7c1bfe7..1b4b3b232ddb4377238cc0e48e59707b5eb76235 100644
--- a/Framework/DataObjects/src/EventWorkspace.cpp
+++ b/Framework/DataObjects/src/EventWorkspace.cpp
@@ -2,7 +2,6 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectraAxis.h"
 #include "MantidAPI/Progress.h"
-#include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/EventWorkspaceMRU.h"
@@ -727,10 +726,6 @@ void EventWorkspace::getIntegratedSpectra(std::vector<double> &out,
 } // namespace DataObjects
 } // namespace Mantid
 
-///\cond TEMPLATE
-template class DLLExport
-    Mantid::API::WorkspaceProperty<Mantid::DataObjects::EventWorkspace>;
-
 namespace Mantid {
 namespace Kernel {
 template <>
diff --git a/Framework/DataObjects/src/MDBoxFlatTree.cpp b/Framework/DataObjects/src/MDBoxFlatTree.cpp
index 6142e6cc179ec848ab097152b1b8e25a0df6d5aa..7a9232e17ff28a54448c6285e29f13da33762e64 100644
--- a/Framework/DataObjects/src/MDBoxFlatTree.cpp
+++ b/Framework/DataObjects/src/MDBoxFlatTree.cpp
@@ -2,7 +2,9 @@
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidAPI/BoxController.h"
 #include "MantidAPI/FileBackedExperimentInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/Logger.h"
 #include "MantidKernel/Strings.h"
 #include <Poco/File.h>
 
diff --git a/Framework/DataObjects/src/MDHistoWorkspace.cpp b/Framework/DataObjects/src/MDHistoWorkspace.cpp
index f950aa27beffee21ec1550517f91bdc4093b2f29..0b2c563a92242ce5dc0818927df67bcfac233a72 100644
--- a/Framework/DataObjects/src/MDHistoWorkspace.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspace.cpp
@@ -632,7 +632,7 @@ IMDWorkspace::LinePlot MDHistoWorkspace::getLinePoints(
     } // for each unique boundary
 
     // If all bins were masked
-    if (line.x.size() == 0) {
+    if (line.x.empty()) {
       this->makeSinglePointWithNaN(line.x, line.y, line.e);
     }
   }
diff --git a/Framework/DataObjects/src/MaskWorkspace.cpp b/Framework/DataObjects/src/MaskWorkspace.cpp
index c7c02b228ba759a69df95448b98ac86915e93d5e..068ced80296a7d5b9d7cf4e802305308d6060cf8 100644
--- a/Framework/DataObjects/src/MaskWorkspace.cpp
+++ b/Framework/DataObjects/src/MaskWorkspace.cpp
@@ -1,6 +1,7 @@
 #include "MantidDataObjects/MaskWorkspace.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
 namespace Mantid {
@@ -71,8 +72,7 @@ void MaskWorkspace::clearMask() {
   }
 
   // Clear the mask flags
-  Geometry::ParameterMap &pmap = this->instrumentParameters();
-  pmap.clearParametersByName("masked");
+  mutableDetectorInfo().clearMaskFlags();
 }
 
 /**
@@ -170,7 +170,16 @@ bool MaskWorkspace::isMasked(const detid_t detectorID) const {
   }
 
   // the mask bit on the workspace can be set
-  return this->getInstrument()->isDetectorMasked(detectorID);
+  // Performance wise, it is not optimal to call detectorInfo() for every index,
+  // but this method seems to be used rarely enough to justify this until the
+  // Instrument-2.0 implementation has progressed far enough to make this cheap.
+  const auto &detectorInfo = this->detectorInfo();
+  try {
+    return detectorInfo.isMasked(detectorInfo.indexOf(detectorID));
+  } catch (std::out_of_range &) {
+    // The workspace can contain bad detector IDs. DetectorInfo::indexOf throws.
+    return false;
+  }
 }
 
 /**
diff --git a/Framework/DataObjects/src/PeakColumn.cpp b/Framework/DataObjects/src/PeakColumn.cpp
index 3f1aec2b8effeed15fc6e9bf8642aeea3f396402..9db8b6cc94a1d215ba22c1fbd79ed2523c1deaae 100644
--- a/Framework/DataObjects/src/PeakColumn.cpp
+++ b/Framework/DataObjects/src/PeakColumn.cpp
@@ -3,6 +3,7 @@
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/MultiThreaded.h"
 
 #include <boost/variant/get.hpp>
 
diff --git a/Framework/DataObjects/src/PeaksWorkspace.cpp b/Framework/DataObjects/src/PeaksWorkspace.cpp
index be71d11980e150a8896017473eaefabf27cbeac8..d6865c24d6fd63740ac956a0c2294b32a2e13035 100644
--- a/Framework/DataObjects/src/PeaksWorkspace.cpp
+++ b/Framework/DataObjects/src/PeaksWorkspace.cpp
@@ -6,7 +6,6 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/WorkspaceFactory.h"
-#include "MantidAPI/WorkspaceProperty.h"
 #include "MantidDataObjects/Peak.h"
 #include "MantidDataObjects/TableColumn.h"
 #include "MantidDataObjects/TableWorkspace.h"
diff --git a/Framework/DataObjects/src/PropertyWithValue.cpp b/Framework/DataObjects/src/PropertyWithValue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..36c5423db9cd69f0088d65ae571db00812cfbbee
--- /dev/null
+++ b/Framework/DataObjects/src/PropertyWithValue.cpp
@@ -0,0 +1,93 @@
+#include "MantidKernel/PropertyWithValue.h"
+#include "MantidDataObjects/DllConfig.h"
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/GroupingWorkspace.h"
+#include "MantidDataObjects/MaskWorkspace.h"
+#include "MantidDataObjects/MDEvent.h"
+#include "MantidDataObjects/MDEventWorkspace.h"
+#include "MantidDataObjects/MDHistoWorkspace.h"
+#include "MantidDataObjects/OffsetsWorkspace.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidDataObjects/RebinnedOutput.h"
+#include "MantidDataObjects/SpecialWorkspace2D.h"
+#include "MantidDataObjects/SplittersWorkspace.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/WorkspaceSingleValue.h"
+
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
+namespace Mantid {
+namespace DataObjects {
+template <size_t nd> using MDEventWS = MDEventWorkspace<MDEvent<nd>, nd>;
+template <size_t nd>
+using MDLeanEventWS = MDEventWorkspace<MDLeanEvent<nd>, nd>;
+}
+namespace Kernel {
+
+/// @cond
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::EventWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::GroupingWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MaskWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<1>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<2>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<3>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<4>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<5>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<6>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<7>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<8>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDEventWS<9>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<1>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<2>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<3>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<4>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<5>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<6>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<7>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<8>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDLeanEventWS<9>>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::MDHistoWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::OffsetsWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::PeaksWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::RebinnedOutput>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::SpecialWorkspace2D>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::SplittersWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::TableWorkspace>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::Workspace2D>>;
+template class MANTID_DATAOBJECTS_DLL
+    PropertyWithValue<boost::shared_ptr<DataObjects::WorkspaceSingleValue>>;
+/// @endcond
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Framework/DataObjects/src/RebinnedOutput.cpp b/Framework/DataObjects/src/RebinnedOutput.cpp
index 04e3e8db4178d269feb5c8a379aa901ad0d835d4..90fbbc7f869865847e584931a98586dd077ab55a 100644
--- a/Framework/DataObjects/src/RebinnedOutput.cpp
+++ b/Framework/DataObjects/src/RebinnedOutput.cpp
@@ -1,8 +1,11 @@
 #include "MantidDataObjects/RebinnedOutput.h"
 
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidKernel/Logger.h"
 
 #include <algorithm>
+#include <iterator>
+#include <sstream>
 
 namespace Mantid {
 namespace DataObjects {
diff --git a/Framework/DataObjects/src/ReflectometryTransform.cpp b/Framework/DataObjects/src/ReflectometryTransform.cpp
index b328094282f0cc81d7d26c4adcf510d76f4e6333..f32707eb71307ce25aa0c26aae80a0584e20e8c8 100644
--- a/Framework/DataObjects/src/ReflectometryTransform.cpp
+++ b/Framework/DataObjects/src/ReflectometryTransform.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/BinEdgeAxis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/CalculateReflectometry.h"
@@ -15,6 +16,8 @@
 #include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/V2D.h"
@@ -464,11 +467,13 @@ MatrixWorkspace_sptr ReflectometryTransform::executeNormPoly(
   std::vector<detid_t> detIDMapping;
   // Create a table for the output if we want to debug vertex positioning
   addColumnHeadings(*vertexes, outputDimensions);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (size_t i = 0; i < nHistos; ++i) {
-    IDetector_const_sptr detector = inputWS->getDetector(i);
-    if (!detector || detector->isMasked() || detector->isMonitor()) {
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMasked(i) ||
+        spectrumInfo.isMonitor(i)) {
       continue;
     }
+    const auto &detector = spectrumInfo.detector(i);
 
     // Compute polygon points
     const double theta = m_theta[i];
@@ -498,7 +503,7 @@ MatrixWorkspace_sptr ReflectometryTransform::executeNormPoly(
         // Add this spectra-detector pair to the mapping
         specNumberMapping.push_back(
             outWS->getSpectrum(qIndex - 1).getSpectrumNo());
-        detIDMapping.push_back(detector->getID());
+        detIDMapping.push_back(detector.getID());
       }
       // Debugging
       if (dumpVertexes) {
diff --git a/Framework/DataObjects/src/TableWorkspace.cpp b/Framework/DataObjects/src/TableWorkspace.cpp
index 96da4a3cbb5269daedc8765cfbd180b2155bddb4..922824f35c203e4a6f662595bb91098fda995b81 100644
--- a/Framework/DataObjects/src/TableWorkspace.cpp
+++ b/Framework/DataObjects/src/TableWorkspace.cpp
@@ -1,7 +1,6 @@
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidKernel/Logger.h"
 #include "MantidAPI/ColumnFactory.h"
-#include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
 #include <queue>
diff --git a/Framework/DataObjects/src/Workspace2D.cpp b/Framework/DataObjects/src/Workspace2D.cpp
index a09ce4d1f44807d3bebb602401acef19eb62cc4b..3f4482c707edc106dabe9dd39422ce628ad927bb 100644
--- a/Framework/DataObjects/src/Workspace2D.cpp
+++ b/Framework/DataObjects/src/Workspace2D.cpp
@@ -3,7 +3,6 @@
 #include "MantidKernel/Exception.h"
 #include "MantidAPI/RefAxis.h"
 #include "MantidAPI/SpectraAxis.h"
-#include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/ISpectrum.h"
 #include "MantidKernel/VectorHelper.h"
@@ -351,10 +350,6 @@ void Workspace2D::generateHistogram(const std::size_t index, const MantidVec &X,
 } // namespace DataObjects
 } // NamespaceMantid
 
-///\cond TEMPLATE
-template class DLLExport
-    Mantid::API::WorkspaceProperty<Mantid::DataObjects::Workspace2D>;
-
 namespace Mantid {
 namespace Kernel {
 template <>
diff --git a/Framework/DataObjects/src/WorkspaceProperty.cpp b/Framework/DataObjects/src/WorkspaceProperty.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d41fc73723bfda83d6040ec06bea5e2ec88bdfe5
--- /dev/null
+++ b/Framework/DataObjects/src/WorkspaceProperty.cpp
@@ -0,0 +1,42 @@
+#include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/GroupingWorkspace.h"
+#include "MantidDataObjects/MaskWorkspace.h"
+#include "MantidDataObjects/OffsetsWorkspace.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidDataObjects/SpecialWorkspace2D.h"
+#include "MantidDataObjects/SplittersWorkspace.h"
+#include "MantidDataObjects/TableWorkspace.h"
+#include "MantidDataObjects/Workspace2D.h"
+#include "MantidDataObjects/WorkspaceSingleValue.h"
+
+// WorkspaceProperty implementation
+#include "MantidAPI/WorkspaceProperty.tcc"
+
+namespace Mantid {
+// Note that this file is part of DataObjects, but we are injecting explicit
+// instantiations into API. This does not extend or modify API.
+namespace API {
+///@cond TEMPLATE
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::EventWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::SpecialWorkspace2D>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::SplittersWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::TableWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::Workspace2D>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::WorkspaceSingleValue>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::GroupingWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::PeaksWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::MaskWorkspace>;
+template class MANTID_DATAOBJECTS_DLL
+    Mantid::API::WorkspaceProperty<Mantid::DataObjects::OffsetsWorkspace>;
+///@endcond TEMPLATE
+} // namespace API
+} // namespace Mantid
diff --git a/Framework/DataObjects/src/WorkspaceSingleValue.cpp b/Framework/DataObjects/src/WorkspaceSingleValue.cpp
index 81c24a8b73a3f7b4722fd91a039e0f0cf8f7ceb7..579545de25425d1d6bf32a54f199e73881568688 100644
--- a/Framework/DataObjects/src/WorkspaceSingleValue.cpp
+++ b/Framework/DataObjects/src/WorkspaceSingleValue.cpp
@@ -1,5 +1,4 @@
 #include "MantidDataObjects/WorkspaceSingleValue.h"
-#include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidKernel/IPropertyManager.h"
 
@@ -78,11 +77,6 @@ size_t WorkspaceSingleValue::getNumDims() const { return 0; }
 } // namespace DataObjects
 } // namespace Mantid
 
-///\cond TEMPLATE
-
-template class DLLExport
-    Mantid::API::WorkspaceProperty<Mantid::DataObjects::WorkspaceSingleValue>;
-
 namespace Mantid {
 namespace Kernel {
 template <>
diff --git a/Framework/DataObjects/test/CMakeLists.txt b/Framework/DataObjects/test/CMakeLists.txt
index ad7553f752ee31a9e1b945a1fce3d3b64007af99..3befa081181d6d7441297a41a954bd4c0bd94b4e 100644
--- a/Framework/DataObjects/test/CMakeLists.txt
+++ b/Framework/DataObjects/test/CMakeLists.txt
@@ -12,6 +12,7 @@ if ( CXXTEST_FOUND )
                         ../../TestHelpers/src/MDEventsTestHelper.cpp 
                         ../../TestHelpers/src/ScopedFileHelper.cpp
                         ../../TestHelpers/src/BoxControllerDummyIO.cpp
+                        ../../TestHelpers/src/FakeObjects.cpp
   )
 
   cxxtest_add_test ( DataObjectsTest ${TEST_FILES} )
diff --git a/Framework/DataObjects/test/EventListTest.h b/Framework/DataObjects/test/EventListTest.h
index 91b705a1afcac555dce10bb04c4997899904a3d7..84d8211b8bc56cb015fdb92144f18af9fe7af847 100644
--- a/Framework/DataObjects/test/EventListTest.h
+++ b/Framework/DataObjects/test/EventListTest.h
@@ -6,6 +6,7 @@
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/CPUTimer.h"
+#include "MantidKernel/Unit.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <cmath>
diff --git a/Framework/DataObjects/test/EventWorkspaceTest.h b/Framework/DataObjects/test/EventWorkspaceTest.h
index 9bb026d442bbbbf2be54425d6ef8082e6de21ac4..73024a94bcbd99ca2b6f2e1b84b199a5d9f778e9 100644
--- a/Framework/DataObjects/test/EventWorkspaceTest.h
+++ b/Framework/DataObjects/test/EventWorkspaceTest.h
@@ -17,6 +17,7 @@
 
 #include "MantidHistogramData/LinearGenerator.h"
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -169,7 +170,8 @@ public:
         WorkspaceCreationHelper::createEventWorkspaceWithFullInstrument(
             1, 10, false /*dont clear the events*/);
     TS_ASSERT_EQUALS(ws->getSpectrum(2).getNumberEvents(), 200);
-    ws->maskWorkspaceIndex(2);
+    ws->getSpectrum(2).clearData();
+    ws->mutableSpectrumInfo().setMasked(2, true);
     TS_ASSERT_EQUALS(ws->getSpectrum(2).getNumberEvents(), 0);
   }
 
@@ -533,7 +535,7 @@ public:
 
   void test_sortAll_TOF() {
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::createRandomEventWorkspace(NUMBINS, NUMPIXELS);
     Progress *prog = NULL;
 
     test_in->sortAll(TOF_SORT, prog);
@@ -553,7 +555,7 @@ public:
   void test_sortAll_SingleEventList() {
     int numEvents = 30;
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents, 1);
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents, 1);
     Progress *prog = NULL;
 
     test_in->sortAll(TOF_SORT, prog);
@@ -571,7 +573,7 @@ public:
   void test_sortAll_byTime_SingleEventList() {
     int numEvents = 30;
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents, 1);
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents, 1);
     Progress *prog = NULL;
 
     test_in->sortAll(PULSETIME_SORT, prog);
@@ -585,7 +587,7 @@ public:
 
   void test_sortAll_ByTime() {
     EventWorkspace_sptr test_in =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(NUMBINS, NUMPIXELS);
+        WorkspaceCreationHelper::createRandomEventWorkspace(NUMBINS, NUMPIXELS);
     Progress *prog = NULL;
 
     test_in->sortAll(PULSETIME_SORT, prog);
@@ -608,7 +610,7 @@ public:
   {
     int numpix = 100000;
     EventWorkspace_const_sptr ew1 =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(50, numpix);
+        WorkspaceCreationHelper::createRandomEventWorkspace(50, numpix);
 
     PARALLEL_FOR_NO_WSP_CHECK()
     for (int i = 0; i < numpix; i++) {
@@ -625,7 +627,7 @@ public:
     // 50 pixels, 100 bins, 2 events in each
     int numpixels = 900;
     EventWorkspace_sptr ew1 =
-        WorkspaceCreationHelper::CreateEventWorkspace2(numpixels, 100);
+        WorkspaceCreationHelper::createEventWorkspace2(numpixels, 100);
     PARALLEL_FOR_IF(do_parallel)
     for (int i = 0; i < numpixels; i += 3) {
       const MantidVec &Y = ew1->readY(i);
@@ -731,7 +733,7 @@ public:
     int numEvents = 2;
     int numHistograms = 2;
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents,
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents,
                                                             numHistograms);
     // Calling isCommonBins() sets the flag m_isCommonBinsFlagSet
     TS_ASSERT(ws->isCommonBins());
@@ -750,7 +752,7 @@ public:
     int numEvents = 2;
     int numHistograms = 2;
     EventWorkspace_const_sptr ws =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents,
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents,
                                                             numHistograms);
     TS_ASSERT_THROWS_NOTHING(ws->readY(0));
     TS_ASSERT_THROWS_NOTHING(ws->dataY(0));
@@ -762,7 +764,7 @@ public:
     int numEvents = 2;
     int numHistograms = 2;
     EventWorkspace_const_sptr ws =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents,
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents,
                                                             numHistograms);
     auto hist1 = ws->histogram(0);
     auto hist2 = ws->histogram(0);
@@ -773,7 +775,7 @@ public:
   }
 
   void test_clearing_EventList_clears_MRU() {
-    auto ws = WorkspaceCreationHelper::CreateRandomEventWorkspace(2, 1);
+    auto ws = WorkspaceCreationHelper::createRandomEventWorkspace(2, 1);
     auto y = ws->sharedY(0);
     TS_ASSERT_EQUALS(y.use_count(), 2);
     ws->getSpectrum(0).clear();
@@ -784,7 +786,7 @@ public:
     int numEvents = 2;
     int numHistograms = 2;
     EventWorkspace_sptr ws =
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(numEvents,
+        WorkspaceCreationHelper::createRandomEventWorkspace(numEvents,
                                                             numHistograms);
     // put two items into MRU
     auto &yOld0 = ws->y(0);
@@ -802,7 +804,7 @@ public:
   }
 
   void test_deleting_spectra_removes_them_from_MRU() {
-    auto ws = WorkspaceCreationHelper::CreateRandomEventWorkspace(2, 1);
+    auto ws = WorkspaceCreationHelper::createRandomEventWorkspace(2, 1);
     auto y = ws->sharedY(0);
     TS_ASSERT_EQUALS(y.use_count(), 2);
 
diff --git a/Framework/DataObjects/test/RebinnedOutputTest.h b/Framework/DataObjects/test/RebinnedOutputTest.h
index 36400658edab22b71a7d1c5df1c630a653300ff9..9d17d3ea6b63e4a2b0ce919ecb657892b9952903 100644
--- a/Framework/DataObjects/test/RebinnedOutputTest.h
+++ b/Framework/DataObjects/test/RebinnedOutputTest.h
@@ -25,7 +25,7 @@ public:
 
   RebinnedOutputTest() {
     nHist = 6;
-    ws = WorkspaceCreationHelper::CreateRebinnedOutputWorkspace();
+    ws = WorkspaceCreationHelper::createRebinnedOutputWorkspace();
   }
 
   void testClone() {
diff --git a/Framework/DataObjects/test/TableWorkspacePropertyTest.h b/Framework/DataObjects/test/TableWorkspacePropertyTest.h
index 7cf08046d341574431b0466fb6d74438eef7f433..252b69205a936288b750792cb5e717b6b6f71868 100644
--- a/Framework/DataObjects/test/TableWorkspacePropertyTest.h
+++ b/Framework/DataObjects/test/TableWorkspacePropertyTest.h
@@ -8,6 +8,7 @@
 
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/Property.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/ColumnFactory.h"
diff --git a/Framework/DataObjects/test/Workspace2DTest.h b/Framework/DataObjects/test/Workspace2DTest.h
index 70b7b0fa0c6e817bd3fe0c938b99541fefb78863..e9fe344d5002d159b569df240160308514c94d70 100644
--- a/Framework/DataObjects/test/Workspace2DTest.h
+++ b/Framework/DataObjects/test/Workspace2DTest.h
@@ -21,7 +21,7 @@ using namespace Mantid::API;
 using HistogramData::Counts;
 using HistogramData::CountStandardDeviations;
 using HistogramData::LinearGenerator;
-using WorkspaceCreationHelper::Create2DWorkspaceBinned;
+using WorkspaceCreationHelper::create2DWorkspaceBinned;
 
 class Workspace2DTest : public CxxTest::TestSuite {
 public:
@@ -36,7 +36,7 @@ public:
   Workspace2DTest() {
     nbins = 5;
     nhist = 10;
-    ws = Create2DWorkspaceBinned(nhist, nbins);
+    ws = create2DWorkspaceBinned(nhist, nbins);
   }
 
   void testClone() {
@@ -128,7 +128,7 @@ public:
   }
 
   void testIntegrateSpectra_entire_range() {
-    ws = Create2DWorkspaceBinned(nhist, nbins);
+    ws = create2DWorkspaceBinned(nhist, nbins);
     MantidVec sums;
     ws->getIntegratedSpectra(sums, 10, 5, true);
     for (int i = 0; i < nhist; ++i) {
@@ -137,7 +137,7 @@ public:
     }
   }
   void testIntegrateSpectra_empty_range() {
-    ws = Create2DWorkspaceBinned(nhist, nbins);
+    ws = create2DWorkspaceBinned(nhist, nbins);
     MantidVec sums;
     ws->getIntegratedSpectra(sums, 10, 5, false);
     for (int i = 0; i < nhist; ++i) {
@@ -147,7 +147,7 @@ public:
   }
 
   void testIntegrateSpectra_partial_range() {
-    ws = Create2DWorkspaceBinned(nhist, nbins);
+    ws = create2DWorkspaceBinned(nhist, nbins);
     MantidVec sums;
     ws->getIntegratedSpectra(sums, 1.9, 3.2, false);
     for (int i = 0; i < nhist; ++i) {
@@ -157,7 +157,7 @@ public:
   }
 
   void test_generateHistogram() {
-    Workspace2D_sptr ws = Create2DWorkspaceBinned(2, 5);
+    Workspace2D_sptr ws = create2DWorkspaceBinned(2, 5);
     MantidVec X, Y, E;
     X.push_back(0.0);
     X.push_back(0.5);
@@ -181,7 +181,7 @@ public:
   }
 
   void test_getMemorySizeForXAxes() {
-    ws = Create2DWorkspaceBinned(nhist, nbins);
+    ws = create2DWorkspaceBinned(nhist, nbins);
     // Here they are shared, so only 1 X axis
     TS_ASSERT_EQUALS(ws->getMemorySizeForXAxes(),
                      1 * (nbins + 1) * sizeof(double));
@@ -267,8 +267,8 @@ public:
 
   Workspace2DTestPerformance() {
     nhist = 1000000; // 1 million
-    ws1 = WorkspaceCreationHelper::Create2DWorkspaceBinned(nhist, 5);
-    ws2 = WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 5);
+    ws1 = WorkspaceCreationHelper::create2DWorkspaceBinned(nhist, 5);
+    ws2 = WorkspaceCreationHelper::create2DWorkspaceBinned(10, 5);
     for (size_t i = 0; i < 10; i++) {
       auto &spec = ws2->getSpectrum(i);
       for (detid_t j = detid_t(i) * 100000; j < detid_t(i + 1) * 100000; j++) {
diff --git a/Framework/Geometry/CMakeLists.txt b/Framework/Geometry/CMakeLists.txt
index de7a6ed907a007b4b7c07c69f68459acee95e078..0f7812e6ecc086980ef2ed03fce0d6390443be0f 100644
--- a/Framework/Geometry/CMakeLists.txt
+++ b/Framework/Geometry/CMakeLists.txt
@@ -53,7 +53,6 @@ set ( SRC_FILES
 	src/Instrument/Goniometer.cpp
 	src/Instrument/IDFObject.cpp
 	src/Instrument/InstrumentDefinitionParser.cpp
-	src/Instrument/NearestNeighbours.cpp
 	src/Instrument/ObjCompAssembly.cpp
 	src/Instrument/ObjComponent.cpp
 	src/Instrument/ParComponentFactory.cpp
@@ -206,7 +205,6 @@ set ( INC_FILES
 	inc/MantidGeometry/Instrument/Goniometer.h
 	inc/MantidGeometry/Instrument/IDFObject.h
 	inc/MantidGeometry/Instrument/InstrumentDefinitionParser.h
-	inc/MantidGeometry/Instrument/NearestNeighbours.h
 	inc/MantidGeometry/Instrument/ObjCompAssembly.h
 	inc/MantidGeometry/Instrument/ObjComponent.h
 	inc/MantidGeometry/Instrument/ParComponentFactory.h
@@ -350,7 +348,6 @@ set ( TEST_FILES
 	MathSupportTest.h
 	MatrixVectorPairParserTest.h
 	MatrixVectorPairTest.h
-	NearestNeighboursTest.h
 	NiggliCellTest.h
 	NullImplicitFunctionTest.h
 	ObjCompAssemblyTest.h
diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/ReducedCell.h b/Framework/Geometry/inc/MantidGeometry/Crystal/ReducedCell.h
index e547ed6c6d0136b195d9068b0131cb3e4dd4bd7a..d7f8fa7beaee5f3992826d14b6e083e00fdf6d0b 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/ReducedCell.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/ReducedCell.h
@@ -3,6 +3,7 @@
 
 #include "MantidGeometry/DllConfig.h"
 #include "MantidKernel/Matrix.h"
+#include <string>
 
 namespace Mantid {
 namespace Geometry {
diff --git a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
index e806cdcd9ea347e8efdf40d93ca1f61a920550e1..17b29750842746e243ff3f7b4cf96c066e3f3dab 100644
--- a/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
+++ b/Framework/Geometry/inc/MantidGeometry/IObjComponent.h
@@ -1,12 +1,8 @@
 #ifndef IMANTID_GEOMETRY_OBJCOMPONENT_H_
 #define IMANTID_GEOMETRY_OBJCOMPONENT_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/IComponent.h"
-#include "MantidGeometry/Objects/Track.h"
 
 namespace Mantid {
 
@@ -15,9 +11,7 @@ class Material;
 }
 
 namespace Geometry {
-//----------------------------------------------------------------------
-// Forward Declaration
-//----------------------------------------------------------------------
+class Track;
 class Object;
 class GeometryHandler;
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument.h b/Framework/Geometry/inc/MantidGeometry/Instrument.h
index 00639c0af60e1f4a4f5db2d29b039ff3a7569209..e9cc7b772151a48aa86906f40068f5f250e641c2 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument.h
@@ -1,9 +1,6 @@
 #ifndef MANTID_GEOMETRY_INSTRUMENT_H_
 #define MANTID_GEOMETRY_INSTRUMENT_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Instrument_fwd.h"
 #include "MantidGeometry/IDetector.h"
@@ -19,11 +16,11 @@ namespace Mantid {
 /// Typedef of a map from detector ID to detector shared pointer.
 typedef std::map<detid_t, Geometry::IDetector_const_sptr> detid2det_map;
 
+namespace Beamline {
+class DetectorInfo;
+}
 namespace Geometry {
 
-//------------------------------------------------------------------
-// Forward declarations
-//------------------------------------------------------------------
 class XMLInstrumentParameter;
 class ParameterMap;
 class ReferenceFrame;
@@ -86,11 +83,9 @@ public:
   const IDetector *getBaseDetector(const detid_t &detector_id) const;
   bool isMonitor(const detid_t &detector_id) const;
   bool isMonitor(const std::set<detid_t> &detector_ids) const;
-  bool isDetectorMasked(const detid_t &detector_id) const;
-  bool isDetectorMasked(const std::set<detid_t> &detector_ids) const;
 
   /// Returns a pointer to the geometrical object for the given set of IDs
-  IDetector_const_sptr getDetectorG(const std::vector<detid_t> &det_ids) const;
+  IDetector_const_sptr getDetectorG(const std::set<detid_t> &det_ids) const;
 
   /// Returns a list of Detectors for the given detectors ids
   std::vector<IDetector_const_sptr>
@@ -219,7 +214,7 @@ public:
   static double calcConversion(const double l1, const Kernel::V3D &beamline,
                                const double beamline_norm,
                                const Kernel::V3D &samplePos,
-                               const IDetector_const_sptr &det,
+                               const Kernel::V3D &detectorPos,
                                const double offset);
 
   static double
@@ -253,6 +248,11 @@ public:
   /// @return Full if all detectors are rect., Partial if some, None if none
   ContainsState containsRectDetectors() const;
 
+  bool hasDetectorInfo() const;
+  const Beamline::DetectorInfo &detectorInfo() const;
+  void
+  setDetectorInfo(boost::shared_ptr<const Beamline::DetectorInfo> detectorInfo);
+
 private:
   /// Save information about a set of detectors to Nexus
   void saveDetectorSetInfoToNexus(::NeXus::File *file,
@@ -329,6 +329,10 @@ private:
 
   /// Pointer to the reference frame object.
   boost::shared_ptr<ReferenceFrame> m_referenceFrame;
+
+  /// Pointer to the DetectorInfo object. NULL unless the instrument is
+  /// associated with an ExperimentInfo object.
+  boost::shared_ptr<const Beamline::DetectorInfo> m_detectorInfo{nullptr};
 };
 
 } // namespace Geometry
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Component.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Component.h
index 72b7f492039b97da4547a44ebcef55526ef95d44..df454c38b2205628ab98c575d1efd530f4758d65 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Component.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Component.h
@@ -1,16 +1,11 @@
 #ifndef MANTID_GEOMETRY_Component_H_
 #define MANTID_GEOMETRY_Component_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include <string>
-#include <sstream>
 #include <typeinfo>
 #include <vector>
-#include <Poco/SAX/Attributes.h>
 #ifdef _MSC_VER
 // Disable a flood of warnings from Poco about inheriting from
 // std::basic_istream
@@ -20,12 +15,17 @@
 #pragma warning(disable : 4250)
 #endif
 
-#include <Poco/XML/XMLWriter.h>
-
 #ifdef _MSC_VER
 #pragma warning(pop)
 #endif
 
+namespace Poco {
+namespace XML {
+class Attributes;
+class XMLWriter;
+}
+}
+
 namespace Mantid {
 namespace Kernel {
 class V3D;
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentHelper.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentHelper.h
index 1427d5643e523195dd459187e561a065bfe26204..106ee0ad75b857227b2f282b6b808160b7f8718d 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentHelper.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ComponentHelper.h
@@ -73,7 +73,7 @@ createVirtualInstrument(Kernel::V3D sourcePos, Kernel::V3D samplePos,
                         const std::vector<Kernel::V3D> &vecdetpos,
                         const std::vector<detid_t> &vecdetid);
 
-MANTID_GEOMETRY_DLL Object_sptr
+MANTID_GEOMETRY_DLL boost::shared_ptr<Object>
 createSphere(double radius, const Kernel::V3D &centre, const std::string &id);
 
 MANTID_GEOMETRY_DLL std::string
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
index d81fa527e2d186ad2b621ef26484401687bde138..5730838c2639798409b9aad009bd9b9becfd5bc3 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ObjComponent.h
@@ -1,14 +1,9 @@
 #ifndef MANTID_GEOMETRY_OBJCOMPONENT_H_
 #define MANTID_GEOMETRY_OBJCOMPONENT_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/DllConfig.h"
 #include "MantidGeometry/Instrument/Component.h"
 #include "MantidGeometry/IObjComponent.h"
-#include "MantidGeometry/Objects/Track.h"
-#include "MantidGeometry/Objects/Object.h"
 
 #ifdef _WIN32
 #pragma warning(disable : 4250)
@@ -16,6 +11,7 @@
 
 namespace Mantid {
 namespace Geometry {
+class Objects;
 //----------------------------------------------------------------------
 // Forward Declaration
 //----------------------------------------------------------------------
@@ -61,7 +57,8 @@ public:
   // Looking to get rid of the first of these constructors in due course (and
   // probably add others)
   explicit ObjComponent(const std::string &name, IComponent *parent = nullptr);
-  explicit ObjComponent(const std::string &name, Object_const_sptr shape,
+  explicit ObjComponent(const std::string &name,
+                        boost::shared_ptr<const Object> shape,
                         IComponent *parent = nullptr);
 
   /** Virtual Copy Constructor
@@ -92,9 +89,9 @@ public:
   void initDraw() const override;
 
   /// Return the shape of the component
-  const Object_const_sptr shape() const override;
+  const boost::shared_ptr<const Object> shape() const override;
   /// Set a new shape on the component
-  void setShape(Object_const_sptr newShape);
+  void setShape(boost::shared_ptr<const Object> newShape);
   /// Return the material this component is made from
   const Kernel::Material material() const override;
 
@@ -103,7 +100,7 @@ protected:
   // Made a pointer to a const object. Since this is a shared object we
   // shouldn't be
   // exposing non-const methods of Object through this class.
-  Object_const_sptr m_shape;
+  boost::shared_ptr<const Object> m_shape;
 
   const Kernel::V3D factorOutComponentPosition(const Kernel::V3D &point) const;
   const Kernel::V3D takeOutRotation(Kernel::V3D point) const;
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
index 47691bd996599d6d7fa30af9591a52b5c9e29099..61f11fef33fcda6616459cb677b4f0f68b7e1156 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/Parameter.h
@@ -22,6 +22,7 @@
 #ifndef Q_MOC_RUN
 #include <boost/shared_ptr.hpp>
 #endif
+#include <sstream>
 #include <string>
 #include <typeinfo>
 #include <vector>
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
index edbbf966840b7e2dc699fae047d1406cd7cc2a80..83bc80a18e32a811441c15afd172a0afe076257c 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h
@@ -6,21 +6,18 @@
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/IDTypes.h" //For specnum_t
 #include "MantidGeometry/Instrument/Parameter.h"
-#include "MantidGeometry/Instrument/ParameterFactory.h"
-#include "MantidGeometry/Objects/BoundingBox.h"
-#include "MantidKernel/Cache.h"
 
 #include "tbb/concurrent_unordered_map.h"
 
+#include <memory>
 #include <vector>
 #include <typeinfo>
 
 namespace Mantid {
+namespace Kernel {
+template <class KEYTYPE, class VALUETYPE> class Cache;
+}
 namespace Geometry {
-
-//---------------------------------------------------------------------------
-// Forward declarations
-//---------------------------------------------------------------------------
 class BoundingBox;
 
 /** @class ParameterMap ParameterMap.h
@@ -74,6 +71,9 @@ public:
       ComponentID, boost::shared_ptr<Parameter>>::const_iterator pmap_cit;
   /// Default constructor
   ParameterMap();
+  /// Const constructor
+  ParameterMap(const ParameterMap &other);
+  ~ParameterMap();
   /// Returns true if the map is empty, false otherwise
   inline bool empty() const { return m_map.empty(); }
   /// Return the size of the map
@@ -141,7 +141,7 @@ public:
   void add(const std::string &type, const IComponent *comp,
            const std::string &name, const T &value,
            const std::string *const pDescription = nullptr) {
-    auto param = ParameterFactory::create(type, name);
+    auto param = create(type, name);
     auto typedParam = boost::dynamic_pointer_cast<ParameterType<T>>(param);
     assert(typedParam); // If not true the factory has created the wrong type
     typedParam->setValue(value);
@@ -340,6 +340,9 @@ public:
   pmap_cit end() const { return m_map.end(); }
 
 private:
+  boost::shared_ptr<Parameter> create(const std::string &className,
+                                      const std::string &name) const;
+
   /// Assignment operator
   ParameterMap &operator=(ParameterMap *rhs);
   /// internal function to get position of the parameter in the parameter map
@@ -356,11 +359,12 @@ private:
   /// internal parameter map instance
   pmap m_map;
   /// internal cache map instance for cached position values
-  mutable Kernel::Cache<const ComponentID, Kernel::V3D> m_cacheLocMap;
+  std::unique_ptr<Kernel::Cache<const ComponentID, Kernel::V3D>> m_cacheLocMap;
   /// internal cache map instance for cached rotation values
-  mutable Kernel::Cache<const ComponentID, Kernel::Quat> m_cacheRotMap;
+  std::unique_ptr<Kernel::Cache<const ComponentID, Kernel::Quat>> m_cacheRotMap;
   /// internal cache map for cached bounding boxes
-  mutable Kernel::Cache<const ComponentID, BoundingBox> m_boundingBoxMap;
+  std::unique_ptr<Kernel::Cache<const ComponentID, BoundingBox>>
+      m_boundingBoxMap;
 };
 
 /// ParameterMap shared pointer typedef
diff --git a/Framework/Geometry/inc/MantidGeometry/Instrument/SampleEnvironment.h b/Framework/Geometry/inc/MantidGeometry/Instrument/SampleEnvironment.h
index 62cd6b4d1779a74f86da83729ae1635d18af8249..d61f3479ffe1c2b2187e2ea11b06de2e2b6243e6 100644
--- a/Framework/Geometry/inc/MantidGeometry/Instrument/SampleEnvironment.h
+++ b/Framework/Geometry/inc/MantidGeometry/Instrument/SampleEnvironment.h
@@ -8,6 +8,9 @@
 #include "MantidGeometry/Instrument/Container.h"
 
 namespace Mantid {
+namespace Kernel {
+class PseudoRandomNumberGenerator;
+}
 namespace Geometry {
 class Track;
 
@@ -52,6 +55,14 @@ public:
   inline size_t nelements() const { return m_components.size(); }
 
   Geometry::BoundingBox boundingBox() const;
+  /// Select a random point within a component
+  Kernel::V3D generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
+                            const size_t maxAttempts) const;
+  /// Select a random point within a component that is also bound by a
+  /// given region
+  Kernel::V3D generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
+                            const BoundingBox &activeRegion,
+                            const size_t maxAttempts) const;
   bool isValid(const Kernel::V3D &point) const;
   int interceptSurfaces(Track &track) const;
 
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
index 08736f79496362b1a7a099ed83902eb10108a158..f1b0a16b005f6ddd45e4e73340eec90fe0dcf553 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/BoundingBox.h
@@ -142,9 +142,10 @@ public:
   std::vector<Kernel::V3D> const &getCoordSystem() const {
     return coord_system;
   }
-
   //@}
 
+  /// Generate a random point within the box
+  Kernel::V3D generatePointInside(double r1, double r2, double r3) const;
   /** returns the expanded box consisting of all 8 box points,
     * shifted into the coordinate system with the observer centre; */
   void getFullBox(std::vector<Kernel::V3D> &box,
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
index 5951682bdd63986570e90a0aabfbe5df31055ea3..8e6d76947817185bd8a142721276378bd6a9b2a6 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/InstrumentRayTracer.h
@@ -1,11 +1,9 @@
 #ifndef MANTID_GEOMETRY_INSTRUMENTRAYTRACER_H_
 #define MANTID_GEOMETRY_INSTRUMENTRAYTRACER_H_
 
-//-------------------------------------------------------------
-// Includes
-//-------------------------------------------------------------
 #include "MantidGeometry/IDetector.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Objects/Track.h"
 #include <deque>
 #include <list>
 
@@ -14,9 +12,6 @@ namespace Kernel {
 class V3D;
 }
 namespace Geometry {
-//-------------------------------------------------------------
-// Forward declarations
-//-------------------------------------------------------------
 struct Link;
 class Track;
 /// Typedef for object intersections
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/Object.h b/Framework/Geometry/inc/MantidGeometry/Objects/Object.h
index b16b816b5a9f1d1e599e6430cc62ca9e9f3cad36..5a1be5728a3ebf910d4b99ffe51615db6d05b27b 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/Object.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/Object.h
@@ -15,17 +15,18 @@ namespace Mantid {
 // Forward declarations
 //----------------------------------------------------------------------
 namespace Kernel {
-class V3D;
+class PseudoRandomNumberGenerator;
 class Material;
+class V3D;
 }
 
 namespace Geometry {
-class Rule;
+class CacheGeometryHandler;
 class CompGrp;
+class GeometryHandler;
+class Rule;
 class Surface;
 class Track;
-class GeometryHandler;
-class CacheGeometryHandler;
 class vtkGeometryCacheReader;
 class vtkGeometryCacheWriter;
 
@@ -153,6 +154,13 @@ public:
   // find internal point to object
   int getPointInObject(Kernel::V3D &point) const;
 
+  /// Select a random point within the object
+  Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                    const size_t) const;
+  Kernel::V3D generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                    const BoundingBox &activeRegion,
+                                    const size_t) const;
+
   // Rendering member functions
   void draw() const;
   // Initialize Drawing
diff --git a/Framework/Geometry/inc/MantidGeometry/Objects/Track.h b/Framework/Geometry/inc/MantidGeometry/Objects/Track.h
index df06aacfcfb04f604e6e66b7606e4198271904ea..3a7863d289fb37228af9e32feb383085c462ec4a 100644
--- a/Framework/Geometry/inc/MantidGeometry/Objects/Track.h
+++ b/Framework/Geometry/inc/MantidGeometry/Objects/Track.h
@@ -143,8 +143,8 @@ struct IntersectionPoint {
 */
 class MANTID_GEOMETRY_DLL Track {
 public:
-  typedef std::list<Link> LType;              ///< Type for the Link storage
-  typedef std::list<IntersectionPoint> PType; ///< Type for the partial
+  using LType = std::list<Link>;
+  using PType = std::list<IntersectionPoint>;
 
 public:
   /// Default constructor
@@ -175,10 +175,24 @@ public:
   LType::iterator begin() { return m_links.begin(); }
   /// Returns an interator to one-past-the-end of the set of links
   LType::iterator end() { return m_links.end(); }
-  /// Returns an interator to the start of the set of links
+  /// Returns an interator to the start of the set of links (const version)
+  LType::const_iterator begin() const { return m_links.begin(); }
+  /// Returns an interator to one-past-the-end of the set of links (const
+  /// version)
+  LType::const_iterator end() const { return m_links.end(); }
+  /// Returns an interator to the start of the set of links (const version)
   LType::const_iterator cbegin() const { return m_links.cbegin(); }
-  /// Returns an interator to one-past-the-end of the set of links
+  /// Returns an interator to one-past-the-end of the set of links (const
+  /// version)
   LType::const_iterator cend() const { return m_links.cend(); }
+  /// Returns a reference to the first link
+  LType::reference front() { return m_links.front(); }
+  /// Returns a reference to the last link
+  LType::reference back() { return m_links.back(); }
+  /// Returns a reference to the first link (const version)
+  LType::const_reference front() const { return m_links.front(); }
+  /// Returns a reference to the last link (const version)
+  LType::const_reference back() const { return m_links.back(); }
   /// Returns the number of links
   int count() const { return static_cast<int>(m_links.size()); }
   /// Is the link complete?
diff --git a/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h b/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h
index d61990b010d5a1c4ab8cec05f9f421d04428110a..dd57786c6369ac5955e2cba182ca91b48f39c604 100644
--- a/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h
+++ b/Framework/Geometry/inc/MantidGeometry/Surfaces/Line.h
@@ -3,6 +3,7 @@
 
 #include "MantidGeometry/DllConfig.h"
 #include "MantidKernel/V3D.h"
+#include <complex>
 
 namespace Mantid {
 
diff --git a/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp b/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp
index c36f94ac2505dd30f4194f7d4ddfa8b55362bab8..3e49afd85880d8f856895931d019b794cbbfd355 100644
--- a/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp
+++ b/Framework/Geometry/src/Crystal/CompositeBraggScatterer.cpp
@@ -186,7 +186,7 @@ void CompositeBraggScatterer::redeclareProperties() {
     std::vector<Property *> properties =
         scatterer->getPropertiesInGroup(getPropagatingGroupName());
     for (auto &property : properties) {
-      std::string propertyName = property->name();
+      const std::string &propertyName = property->name();
       if (!existsProperty(propertyName)) {
         declareProperty(std::unique_ptr<Property>(property->clone()));
       }
diff --git a/Framework/Geometry/src/Crystal/HKLFilterWavelength.cpp b/Framework/Geometry/src/Crystal/HKLFilterWavelength.cpp
index c186dad1e842f99bb43bae74939b95209bbdc2fc..85d41346ff6c66e5483a80d0df12e3c59dfbc309 100644
--- a/Framework/Geometry/src/Crystal/HKLFilterWavelength.cpp
+++ b/Framework/Geometry/src/Crystal/HKLFilterWavelength.cpp
@@ -1,4 +1,5 @@
 #include "MantidGeometry/Crystal/HKLFilterWavelength.h"
+#include <sstream>
 #include <stdexcept>
 
 namespace Mantid {
diff --git a/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp b/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp
index aba6ceafb47dacbb3e2b738b03b7f7b71b01bf80..2a70dcc0792d92875125aa0f8e5de7f5fe04e598 100644
--- a/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp
+++ b/Framework/Geometry/src/Crystal/SymmetryOperationSymbolParser.cpp
@@ -98,7 +98,7 @@ std::string SymmetryOperationSymbolParser::getNormalizedIdentifier(
         if (matrix[r][c] < 0) {
           currentComponent << "-";
         } else {
-          if (currentComponent.str().size() > 0) {
+          if (!currentComponent.str().empty()) {
             currentComponent << "+";
           }
         }
diff --git a/Framework/Geometry/src/Instrument.cpp b/Framework/Geometry/src/Instrument.cpp
index ed3f35541097fb048e36d1e970bd513901c2077d..c3acfb73a151156cdd4b6f2e76edaccae336ce90 100644
--- a/Framework/Geometry/src/Instrument.cpp
+++ b/Framework/Geometry/src/Instrument.cpp
@@ -4,6 +4,7 @@
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/Logger.h"
 #include "MantidKernel/PhysicalConstants.h"
 
 #include <boost/make_shared.hpp>
@@ -45,7 +46,8 @@ Instrument::Instrument(const boost::shared_ptr<const Instrument> instr,
       m_sampleCache(instr->m_sampleCache), m_defaultView(instr->m_defaultView),
       m_defaultViewAxis(instr->m_defaultViewAxis), m_instr(instr),
       m_map_nonconst(map), m_ValidFrom(instr->m_ValidFrom),
-      m_ValidTo(instr->m_ValidTo), m_referenceFrame(new ReferenceFrame) {}
+      m_ValidTo(instr->m_ValidTo), m_referenceFrame(new ReferenceFrame),
+      m_detectorInfo(instr->m_detectorInfo) {}
 
 /** Copy constructor
  *  This method was added to deal with having distinct neutronic and physical
@@ -61,7 +63,8 @@ Instrument::Instrument(const Instrument &instr)
       m_defaultViewAxis(instr.m_defaultViewAxis), m_instr(),
       m_map_nonconst(), /* Should not be parameterized */
       m_ValidFrom(instr.m_ValidFrom), m_ValidTo(instr.m_ValidTo),
-      m_referenceFrame(instr.m_referenceFrame) {
+      m_referenceFrame(instr.m_referenceFrame),
+      m_detectorInfo(instr.m_detectorInfo) {
   // Now we need to fill the detector, source and sample caches with pointers
   // into the new instrument
   std::vector<IComponent_const_sptr> children;
@@ -513,53 +516,6 @@ bool Instrument::isMonitor(const std::set<detid_t> &detector_ids) const {
   return false;
 }
 
-//--------------------------------------------------------------------------
-/** Is the detector with the given ID masked?
- *
- * @param detector_id :: detector ID to look for.
- * @return true if masked; false if not masked or if the detector was not found.
- */
-bool Instrument::isDetectorMasked(const detid_t &detector_id) const {
-  // With no parameter map, then no detector is EVER masked
-  if (!isParametrized())
-    return false;
-  // Find the (base) detector object in the map.
-  auto it = m_instr->m_detectorCache.find(detector_id);
-  if (it == m_instr->m_detectorCache.end())
-    return false;
-  // This is the detector
-  const Detector *det = dynamic_cast<const Detector *>(it->second.get());
-  if (det == nullptr)
-    return false;
-  // Access the parameter map directly.
-  Parameter_sptr maskedParam = m_map->get(det, "masked");
-  if (!maskedParam)
-    return false;
-  // If the parameter is defined, then yes, it is masked.
-  return maskedParam->value<bool>();
-}
-
-//--------------------------------------------------------------------------
-/** Is this group of detectors masked?
- *
- * This returns true (masked) if ALL of the detectors listed are masked.
- * It returns false (not masked) if there are no detectors in the list
- * It returns false (not masked) if any of the detectors are NOT masked.
- *
- * @param detector_ids :: set of detector IDs
- * @return true if masked.
- */
-bool Instrument::isDetectorMasked(const std::set<detid_t> &detector_ids) const {
-  if (detector_ids.empty())
-    return false;
-
-  for (auto detector_id : detector_ids) {
-    if (!this->isDetectorMasked(detector_id))
-      return false;
-  }
-  return true;
-}
-
 /**
  * Returns a pointer to the geometrical object for the given set of IDs
  * @param det_ids :: A list of detector ids
@@ -567,16 +523,16 @@ bool Instrument::isDetectorMasked(const std::set<detid_t> &detector_ids) const {
  *  @throw   NotFoundError If no detector is found for the detector ID given
  */
 IDetector_const_sptr
-Instrument::getDetectorG(const std::vector<detid_t> &det_ids) const {
+Instrument::getDetectorG(const std::set<detid_t> &det_ids) const {
   const size_t ndets(det_ids.size());
   if (ndets == 1) {
-    return this->getDetector(det_ids[0]);
+    return this->getDetector(*det_ids.begin());
   } else {
     boost::shared_ptr<DetectorGroup> det_group =
         boost::make_shared<DetectorGroup>();
     bool warn(false);
-    for (size_t i = 0; i < ndets; ++i) {
-      det_group->addDetector(this->getDetector(det_ids[i]), warn);
+    for (const auto detID : det_ids) {
+      det_group->addDetector(this->getDetector(detID), warn);
     }
     return det_group;
   }
@@ -902,14 +858,14 @@ const double CONSTANT = (PhysicalConstants::h * 1e10) /
  *        the length of the distance between the two.
  * @param beamline_norm: (source to sample distance) * 2.0 (apparently)
  * @param samplePos: position of the sample
- * @param det: Geometry object representing the detector (position of the pixel)
+ * @param detPos: position of the detector
  * @param offset: value (close to zero) that changes the factor := factor *
  *(1+offset).
  */
 double Instrument::calcConversion(const double l1, const Kernel::V3D &beamline,
                                   const double beamline_norm,
                                   const Kernel::V3D &samplePos,
-                                  const IDetector_const_sptr &det,
+                                  const Kernel::V3D &detPos,
                                   const double offset) {
   if (offset <=
       -1.) // not physically possible, means result is negative d-spacing
@@ -920,17 +876,12 @@ double Instrument::calcConversion(const double l1, const Kernel::V3D &beamline,
     throw std::logic_error(msg.str());
   }
 
-  // Get the sample-detector distance for this detector (in metres)
-
-  // The scattering angle for this detector (in radians).
-  Kernel::V3D detPos;
-  detPos = det->getPos();
-
   // Now detPos will be set with respect to samplePos
-  detPos -= samplePos;
+  Kernel::V3D relDetPos = detPos - samplePos;
   // 0.5*cos(2theta)
-  double l2 = detPos.norm();
-  double halfcosTwoTheta = detPos.scalar_prod(beamline) / (l2 * beamline_norm);
+  double l2 = relDetPos.norm();
+  double halfcosTwoTheta =
+      relDetPos.scalar_prod(beamline) / (l2 * beamline_norm);
   // This is sin(theta)
   double sinTheta = sqrt(0.5 - halfcosTwoTheta);
   const double numerator = (1.0 + offset);
@@ -957,8 +908,9 @@ double Instrument::calcConversion(
     } else {
       offset = 0.;
     }
-    factor += calcConversion(l1, beamline, beamline_norm, samplePos,
-                             instrument->getDetector(detector), offset);
+    factor +=
+        calcConversion(l1, beamline, beamline_norm, samplePos,
+                       instrument->getDetector(detector)->getPos(), offset);
   }
   return factor / static_cast<double>(detectors.size());
 }
@@ -1281,5 +1233,23 @@ Instrument::ContainsState Instrument::containsRectDetectors() const {
 
 } // containsRectDetectors
 
+/// Only for use by ExperimentInfo. Returns returns true if this instrument
+/// contains a DetectorInfo.
+bool Instrument::hasDetectorInfo() const {
+  return static_cast<bool>(m_detectorInfo);
+}
+/// Only for use by ExperimentInfo. Returns a reference to the DetectorInfo.
+const Beamline::DetectorInfo &Instrument::detectorInfo() const {
+  if (!hasDetectorInfo())
+    throw std::runtime_error("Cannot return reference to NULL DetectorInfo");
+  return *m_detectorInfo;
+}
+
+/// Only for use by ExperimentInfo. Sets the pointer to the DetectorInfo.
+void Instrument::setDetectorInfo(
+    boost::shared_ptr<const Beamline::DetectorInfo> detectorInfo) {
+  m_detectorInfo = std::move(detectorInfo);
+}
+
 } // namespace Geometry
 } // Namespace Mantid
diff --git a/Framework/Geometry/src/Instrument/Component.cpp b/Framework/Geometry/src/Instrument/Component.cpp
index a707ea7e27872af535b52a947499f398e51a3e9b..98434ee78a2d438c6ab65d74b11fc29dc55f2ebc 100644
--- a/Framework/Geometry/src/Instrument/Component.cpp
+++ b/Framework/Geometry/src/Instrument/Component.cpp
@@ -1,6 +1,7 @@
 #include "MantidGeometry/IComponent.h"
 #include "MantidGeometry/Instrument/ParComponentFactory.h"
 #include "MantidGeometry/Instrument/Component.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/Exception.h"
 
 #include <Poco/XML/XMLWriter.h>
diff --git a/Framework/Geometry/src/Instrument/ComponentHelper.cpp b/Framework/Geometry/src/Instrument/ComponentHelper.cpp
index ffc46c880af12d8efae417f88eda2eb3656f3945..7c9b75afdddd03f5d6c738341beedaf4212d72d2 100644
--- a/Framework/Geometry/src/Instrument/ComponentHelper.cpp
+++ b/Framework/Geometry/src/Instrument/ComponentHelper.cpp
@@ -1,10 +1,8 @@
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
 #include "MantidGeometry/Instrument/ComponentHelper.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/IComponent.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
+#include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
 #include "MantidGeometry/Instrument/Detector.h"
 
diff --git a/Framework/Geometry/src/Instrument/Detector.cpp b/Framework/Geometry/src/Instrument/Detector.cpp
index ce6d6b477919482b56129096303b37be9cc25a4d..bb0fd7612c84f86bcc8cf657d268ad9e5da025b9 100644
--- a/Framework/Geometry/src/Instrument/Detector.cpp
+++ b/Framework/Geometry/src/Instrument/Detector.cpp
@@ -1,5 +1,6 @@
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
+#include "MantidKernel/Logger.h"
 
 namespace Mantid {
 namespace Geometry {
diff --git a/Framework/Geometry/src/Instrument/DetectorGroup.cpp b/Framework/Geometry/src/Instrument/DetectorGroup.cpp
index abc36ded770f0b95735c53ce7becf958eee74473..7cfc6b7dc5872ee4ae4aa5462b9749d72f40fb0a 100644
--- a/Framework/Geometry/src/Instrument/DetectorGroup.cpp
+++ b/Framework/Geometry/src/Instrument/DetectorGroup.cpp
@@ -1,9 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/Instrument/DetectorGroup.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/Logger.h"
 #include "MantidKernel/Material.h"
 
 namespace Mantid {
diff --git a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
index ad4df1589551b08db77111481a7d00deb1a8f1a2..c3a34c389ea6938a628daf9ff29bbca4771f3bbf 100644
--- a/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
+++ b/Framework/Geometry/src/Instrument/InstrumentDefinitionParser.cpp
@@ -28,6 +28,7 @@
 #include <Poco/Path.h>
 #include <Poco/SAX/AttributesImpl.h>
 #include <Poco/String.h>
+#include <Poco/XML/XMLWriter.h>
 
 #include <boost/make_shared.hpp>
 #include <boost/regex.hpp>
@@ -753,7 +754,7 @@ Poco::XML::Element *InstrumentDefinitionParser::getParentComponent(
     const Poco::XML::Element *pLocElem) {
   if ((pLocElem->tagName()).compare("location") &&
       (pLocElem->tagName()).compare("locations")) {
-    std::string tagname = pLocElem->tagName();
+    const std::string &tagname = pLocElem->tagName();
     g_log.error("Argument to function getParentComponent must be a pointer to "
                 "an XML element with tag name location or locations.");
     throw std::logic_error(
diff --git a/Framework/Geometry/src/Instrument/ObjComponent.cpp b/Framework/Geometry/src/Instrument/ObjComponent.cpp
index 98a4c86a987f90810111b2b1dcf1e031b60b538e..127e17a3a983dd139eba31a56058b8d8438daea4 100644
--- a/Framework/Geometry/src/Instrument/ObjComponent.cpp
+++ b/Framework/Geometry/src/Instrument/ObjComponent.cpp
@@ -1,9 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidGeometry/Instrument/ObjComponent.h"
 #include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
@@ -34,7 +32,8 @@ ObjComponent::ObjComponent(const std::string &name, IComponent *parent)
 * component
 *  @param parent :: The Parent geometry object of this component
 */
-ObjComponent::ObjComponent(const std::string &name, Object_const_sptr shape,
+ObjComponent::ObjComponent(const std::string &name,
+                           boost::shared_ptr<const Object> shape,
                            IComponent *parent)
     : IObjComponent(), Component(name, parent), m_shape(shape) {}
 
diff --git a/Framework/Geometry/src/Instrument/ParameterMap.cpp b/Framework/Geometry/src/Instrument/ParameterMap.cpp
index f7fa224ba088f67db961c7d6a454603f336c34f0..5928ba0a1f9ad868b3296d761c6ebeeab18ad18d 100644
--- a/Framework/Geometry/src/Instrument/ParameterMap.cpp
+++ b/Framework/Geometry/src/Instrument/ParameterMap.cpp
@@ -1,8 +1,10 @@
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/IDetector.h"
+#include "MantidKernel/Cache.h"
 #include "MantidKernel/MultiThreaded.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/ParameterFactory.h"
 #include <cstring>
 #include <boost/algorithm/string.hpp>
 
@@ -45,7 +47,28 @@ Kernel::Logger g_log("ParameterMap");
 /**
  * Default constructor
  */
-ParameterMap::ParameterMap() : m_parameterFileNames(), m_map() {}
+ParameterMap::ParameterMap()
+    : m_cacheLocMap(
+          Kernel::make_unique<Kernel::Cache<const ComponentID, Kernel::V3D>>()),
+      m_cacheRotMap(Kernel::make_unique<
+          Kernel::Cache<const ComponentID, Kernel::Quat>>()),
+      m_boundingBoxMap(Kernel::make_unique<
+          Kernel::Cache<const ComponentID, BoundingBox>>()) {}
+
+ParameterMap::ParameterMap(const ParameterMap &other)
+    : m_parameterFileNames(other.m_parameterFileNames), m_map(other.m_map),
+      m_cacheLocMap(
+          Kernel::make_unique<Kernel::Cache<const ComponentID, Kernel::V3D>>(
+              *other.m_cacheLocMap)),
+      m_cacheRotMap(
+          Kernel::make_unique<Kernel::Cache<const ComponentID, Kernel::Quat>>(
+              *other.m_cacheRotMap)),
+      m_boundingBoxMap(
+          Kernel::make_unique<Kernel::Cache<const ComponentID, BoundingBox>>(
+              *other.m_boundingBoxMap)) {}
+
+// Defined as default in source for forward declaration with std::unique_ptr.
+ParameterMap::~ParameterMap() = default;
 
 /**
 * Return string to be inserted into the parameter map
@@ -961,9 +984,9 @@ std::string ParameterMap::asString() const {
  * Clears the location, rotation & bounding box caches
  */
 void ParameterMap::clearPositionSensitiveCaches() {
-  m_cacheLocMap.clear();
-  m_cacheRotMap.clear();
-  m_boundingBoxMap.clear();
+  m_cacheLocMap->clear();
+  m_cacheRotMap->clear();
+  m_boundingBoxMap->clear();
 }
 
 /// Sets a cached location on the location cache
@@ -971,7 +994,7 @@ void ParameterMap::clearPositionSensitiveCaches() {
 /// @param location :: The location
 void ParameterMap::setCachedLocation(const IComponent *comp,
                                      const V3D &location) const {
-  m_cacheLocMap.setCache(comp->getComponentID(), location);
+  m_cacheLocMap->setCache(comp->getComponentID(), location);
 }
 
 /// Attempts to retrieve a location from the location cache
@@ -980,7 +1003,7 @@ void ParameterMap::setCachedLocation(const IComponent *comp,
 /// @returns true if the location is in the map, otherwise false
 bool ParameterMap::getCachedLocation(const IComponent *comp,
                                      V3D &location) const {
-  return m_cacheLocMap.getCache(comp->getComponentID(), location);
+  return m_cacheLocMap->getCache(comp->getComponentID(), location);
 }
 
 /// Sets a cached rotation on the rotation cache
@@ -988,7 +1011,7 @@ bool ParameterMap::getCachedLocation(const IComponent *comp,
 /// @param rotation :: The rotation as a quaternion
 void ParameterMap::setCachedRotation(const IComponent *comp,
                                      const Quat &rotation) const {
-  m_cacheRotMap.setCache(comp->getComponentID(), rotation);
+  m_cacheRotMap->setCache(comp->getComponentID(), rotation);
 }
 
 /// Attempts to retrieve a rotation from the rotation cache
@@ -997,7 +1020,7 @@ void ParameterMap::setCachedRotation(const IComponent *comp,
 /// @returns true if the rotation is in the map, otherwise false
 bool ParameterMap::getCachedRotation(const IComponent *comp,
                                      Quat &rotation) const {
-  return m_cacheRotMap.getCache(comp->getComponentID(), rotation);
+  return m_cacheRotMap->getCache(comp->getComponentID(), rotation);
 }
 
 /// Sets a cached bounding box
@@ -1005,7 +1028,7 @@ bool ParameterMap::getCachedRotation(const IComponent *comp,
 /// @param box :: A reference to the bounding box
 void ParameterMap::setCachedBoundingBox(const IComponent *comp,
                                         const BoundingBox &box) const {
-  m_boundingBoxMap.setCache(comp->getComponentID(), box);
+  m_boundingBoxMap->setCache(comp->getComponentID(), box);
 }
 
 /// Attempts to retrieve a bounding box from the cache
@@ -1014,7 +1037,7 @@ void ParameterMap::setCachedBoundingBox(const IComponent *comp,
 /// @returns true if the bounding is in the map, otherwise false
 bool ParameterMap::getCachedBoundingBox(const IComponent *comp,
                                         BoundingBox &box) const {
-  return m_boundingBoxMap.getCache(comp->getComponentID(), box);
+  return m_boundingBoxMap->getCache(comp->getComponentID(), box);
 }
 
 /**
@@ -1079,5 +1102,12 @@ void ParameterMap::addParameterFilename(const std::string &filename) {
   m_parameterFileNames.push_back(filename);
 }
 
+/// Wrapper for ParameterFactory::create to avoid include in header
+boost::shared_ptr<Parameter>
+ParameterMap::create(const std::string &className,
+                     const std::string &name) const {
+  return ParameterFactory::create(className, name);
+}
+
 } // Namespace Geometry
 } // Namespace Mantid
diff --git a/Framework/Geometry/src/Instrument/RectangularDetector.cpp b/Framework/Geometry/src/Instrument/RectangularDetector.cpp
index c9af1b9cd8f6c7533f933bf2abf36a2ba24bf76d..794a1369ae26ef426080b79a3e7502e823de8a60 100644
--- a/Framework/Geometry/src/Instrument/RectangularDetector.cpp
+++ b/Framework/Geometry/src/Instrument/RectangularDetector.cpp
@@ -4,6 +4,7 @@
 #include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidGeometry/Rendering/BitmapGeometryHandler.h"
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
diff --git a/Framework/Geometry/src/Instrument/SampleEnvironment.cpp b/Framework/Geometry/src/Instrument/SampleEnvironment.cpp
index 58f1ce9d1a6e3f866999759faaff5a341747870f..a714c507e807913c4dc62d64be7035618c532a6c 100644
--- a/Framework/Geometry/src/Instrument/SampleEnvironment.cpp
+++ b/Framework/Geometry/src/Instrument/SampleEnvironment.cpp
@@ -5,6 +5,7 @@
 #include "MantidGeometry/IObjComponent.h"
 #include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Objects/Track.h"
+#include "MantidKernel/PseudoRandomNumberGenerator.h"
 
 namespace Mantid {
 namespace Geometry {
@@ -38,6 +39,41 @@ Geometry::BoundingBox SampleEnvironment::boundingBox() const {
   return box;
 }
 
+/**
+ * Generate a random point within one of the environment's components. The
+ * method first selects a random component and then selects a random point
+ * within that component using Object::generatePointObject
+ * @param rng A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @param maxAttempts The maximum number of attempts at generating a point
+ * @return The generated point
+ */
+Kernel::V3D
+SampleEnvironment::generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
+                                 const size_t maxAttempts) const {
+  auto componentIndex = rng.nextInt(1, static_cast<int>(nelements())) - 1;
+  return m_components[componentIndex]->generatePointInObject(rng, maxAttempts);
+}
+
+/**
+ * Generate a random point within one of the environment's components. The
+ * method first selects a random component and then selects a random point
+ * within that component using Object::generatePointObject
+ * @param rng A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @param activeRegion Restrict the generated point to be defined by this box
+ * @param maxAttempts The maximum number of attempts at generating a point
+ * @return The generated point
+ */
+Kernel::V3D
+SampleEnvironment::generatePoint(Kernel::PseudoRandomNumberGenerator &rng,
+                                 const Geometry::BoundingBox &activeRegion,
+                                 const size_t maxAttempts) const {
+  auto componentIndex = rng.nextInt(1, static_cast<int>(nelements())) - 1;
+  return m_components[componentIndex]->generatePointInObject(rng, activeRegion,
+                                                             maxAttempts);
+}
+
 /**
  * Is the point given a valid point within the environment
  * @param point Is the point valid within the environment
diff --git a/Framework/Geometry/src/MDGeometry/MDHistoDimension.cpp b/Framework/Geometry/src/MDGeometry/MDHistoDimension.cpp
index dc4c70b8b485d2e9349f5063fbdce43c46180f22..d0590b84ce7f3b8163f296eccc52dc258b6ac7bb 100644
--- a/Framework/Geometry/src/MDGeometry/MDHistoDimension.cpp
+++ b/Framework/Geometry/src/MDGeometry/MDHistoDimension.cpp
@@ -1,4 +1,5 @@
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
+#include <sstream>
 
 #include <boost/algorithm/string.hpp>
 #include <boost/format.hpp>
diff --git a/Framework/Geometry/src/Math/Acomp.cpp b/Framework/Geometry/src/Math/Acomp.cpp
index aced68e7e39bf3bb7cb8ee1eeac980bd8564b3e5..1661ec2ac9644181684e299378d9e1e4de3116e1 100644
--- a/Framework/Geometry/src/Math/Acomp.cpp
+++ b/Framework/Geometry/src/Math/Acomp.cpp
@@ -459,7 +459,7 @@ Units are sorted after this function is returned.
         Express += iu;
     }
   }
-  if (Express.size() > 0) {
+  if (!Express.empty()) {
     Acomp AX;
     try {
       AX.setString(Express);
diff --git a/Framework/Geometry/src/Objects/BoundingBox.cpp b/Framework/Geometry/src/Objects/BoundingBox.cpp
index ad4572dc5fa3f023527da1610329f66c800cb49c..7dde97876bac777553e87d2b3456af48564d748f 100644
--- a/Framework/Geometry/src/Objects/BoundingBox.cpp
+++ b/Framework/Geometry/src/Objects/BoundingBox.cpp
@@ -147,7 +147,21 @@ double BoundingBox::angularWidth(const Kernel::V3D &observer) const {
   }
   return thetaMax;
 }
-//
+
+/**
+ * Generate a random point within this box assuming the 3 numbers given
+ * are random numbers in the range (0,1) & selected from a flat distribution.
+ * @param r1 Flat random number in range (0,1)
+ * @param r2 Flat random number in range (0,1)
+ * @param r3 Flat random number in range (0,1)
+ * @return A new point within the box such that isPointInside(pt) == true
+ */
+Kernel::V3D BoundingBox::generatePointInside(double r1, double r2,
+                                             double r3) const {
+  return V3D(xMin() + r1 * (xMax() - xMin()), yMin() + r2 * (yMax() - yMin()),
+             zMin() + r3 * (zMax() - zMin()));
+}
+
 void BoundingBox::getFullBox(std::vector<Kernel::V3D> &box,
                              const Kernel::V3D &observer) const {
   box.resize(8);
@@ -160,6 +174,7 @@ void BoundingBox::getFullBox(std::vector<Kernel::V3D> &box,
   box[6] = Kernel::V3D(xMax(), yMin(), zMax()) - observer;
   box[7] = Kernel::V3D(xMax(), yMax(), zMax()) - observer;
 }
+
 void BoundingBox::setBoxAlignment(const Kernel::V3D &R0,
                                   const std::vector<Kernel::V3D> &orts) {
   this->coord_system.resize(4);
@@ -169,6 +184,7 @@ void BoundingBox::setBoxAlignment(const Kernel::V3D &R0,
   coord_system[3] = orts[2];
   is_axis_aligned = false;
 }
+
 void BoundingBox::nullify() {
   this->m_null = true;
   for (int i = 0; i < 3; i++) {
@@ -176,7 +192,7 @@ void BoundingBox::nullify() {
     this->m_maxPoint[i] = -FLT_MAX;
   }
 }
-//
+
 void BoundingBox::realign(std::vector<Kernel::V3D> const *const pCS) {
   if (pCS) {
     this->coord_system.resize(pCS->size());
@@ -224,6 +240,7 @@ void BoundingBox::realign(std::vector<Kernel::V3D> const *const pCS) {
   this->zMin() = zMin;
   this->zMax() = zMax;
 }
+
 /**
  * Enlarges this bounding box so that it encompasses that given.
  * @param other :: The bounding box that should be encompassed
diff --git a/Framework/Geometry/src/Objects/Object.cpp b/Framework/Geometry/src/Objects/Object.cpp
index 644d7a337344b2b35c68220a35749110d330fe22..d3237b51f770e3a30fe0a2c4bc42b69df865edee 100644
--- a/Framework/Geometry/src/Objects/Object.cpp
+++ b/Framework/Geometry/src/Objects/Object.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Material.h"
 #include "MantidKernel/MultiThreaded.h"
+#include "MantidKernel/PseudoRandomNumberGenerator.h"
 #include "MantidKernel/Strings.h"
 
 #include "MantidGeometry/Surfaces/Cone.h"
@@ -1823,6 +1824,54 @@ int Object::getPointInObject(Kernel::V3D &point) const {
   return 0;
 }
 
+/**
+ * Generate a random point within the object. The method simply generates a
+ * point within the bounding box and tests if this is a valid point within
+ * the object: if so the point is return otherwise a new point is selected.
+ * @param rng  A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @param maxAttempts The maximum number of attempts at generating a point
+ * @return The generated point
+ */
+V3D Object::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                  const size_t maxAttempts) const {
+  const auto &bbox = getBoundingBox();
+  if (bbox.isNull()) {
+    throw std::runtime_error("Object::generatePointInObject() - Invalid "
+                             "bounding box. Cannot generate new point.");
+  }
+  return generatePointInObject(rng, bbox, maxAttempts);
+}
+
+/**
+ * Generate a random point within the object that is also bound by the
+ * activeRegion box.
+ * @param rng A reference to a PseudoRandomNumberGenerator where
+ * nextValue should return a flat random number between 0.0 & 1.0
+ * @param activeRegion Restrict point generation to this sub-region of the
+ * object
+ * @param maxAttempts The maximum number of attempts at generating a point
+ * @return The newly generated point
+ */
+V3D Object::generatePointInObject(Kernel::PseudoRandomNumberGenerator &rng,
+                                  const BoundingBox &activeRegion,
+                                  const size_t maxAttempts) const {
+  size_t attempts(0);
+  while (attempts < maxAttempts) {
+    const double r1 = rng.nextValue();
+    const double r2 = rng.nextValue();
+    const double r3 = rng.nextValue();
+    auto pt = activeRegion.generatePointInside(r1, r2, r3);
+    if (this->isValid(pt))
+      return pt;
+    else
+      ++attempts;
+  };
+  throw std::runtime_error("Object::generatePointInObject() - Unable to "
+                           "generate point in object after " +
+                           std::to_string(maxAttempts) + " attempts");
+}
+
 /**
 * Try to find a point that lies within (or on) the object, given a seed point
 * @param point :: on entry the seed point, on exit point in object, if found
diff --git a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp
index dcdb018e5e2c36487eac583452c7cfb959260016..54a9d8d3926f7d608a1d7bfd01388dc5243ca592 100644
--- a/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp
+++ b/Framework/Geometry/src/Rendering/CacheGeometryHandler.cpp
@@ -4,6 +4,7 @@
 #include "MantidGeometry/Rendering/CacheGeometryHandler.h"
 #include "MantidGeometry/Rendering/CacheGeometryRenderer.h"
 #include "MantidGeometry/Rendering/CacheGeometryGenerator.h"
+#include "MantidKernel/MultiThreaded.h"
 
 #include <boost/make_shared.hpp>
 
diff --git a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp
index 2014b93e034fabf3724496ec28de44b2f24eb7f3..3ecd3e61fc9033bc6315ed5630e7dde6852ece11 100644
--- a/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp
+++ b/Framework/Geometry/src/Rendering/GluGeometryHandler.cpp
@@ -3,6 +3,7 @@
 #include "MantidGeometry/Objects/Object.h"
 #include "MantidGeometry/Rendering/GeometryHandler.h"
 #include "MantidGeometry/Rendering/GluGeometryRenderer.h"
+#include "MantidKernel/make_unique.h"
 
 #include <boost/make_shared.hpp>
 
diff --git a/Framework/Geometry/test/BoundingBoxTest.h b/Framework/Geometry/test/BoundingBoxTest.h
index b5ceb38ceb9826da81456d774a134b4595e04c3f..1357e628347d5ab4cd5d0a47f388add02b9c4b98 100644
--- a/Framework/Geometry/test/BoundingBoxTest.h
+++ b/Framework/Geometry/test/BoundingBoxTest.h
@@ -209,6 +209,18 @@ public:
     TS_ASSERT_EQUALS(box.maxPoint() == V3D(-FLT_MAX, -FLT_MAX, -FLT_MAX), true);
     TS_ASSERT_EQUALS(box.minPoint() == V3D(FLT_MAX, FLT_MAX, FLT_MAX), true);
   }
+
+  void test_generatePointInside_Gives_Point_Inside() {
+    BoundingBox box(3.0, 4.0, 5.0, 1.0, 1.0, 2.5);
+
+    auto pt = box.generatePointInside(0.1, 0.2, 0.3);
+    TS_ASSERT(box.isPointInside(pt));
+    const double tolerance(1e-10);
+    TS_ASSERT_DELTA(1.2, pt.X(), tolerance);
+    TS_ASSERT_DELTA(1.6, pt.Y(), tolerance);
+    TS_ASSERT_DELTA(3.25, pt.Z(), tolerance);
+  }
+
   void testBB_expansion_works_fine() {
     BoundingBox box(3.0, 4.0, 5.5, 1.0, 1.0, 1.5);
     std::vector<V3D> points;
diff --git a/Framework/Geometry/test/InstrumentTest.h b/Framework/Geometry/test/InstrumentTest.h
index b75d9830d630b73ef893aa5aae42d53ff306ebfc..9aa7ca01bc8e340aaeccc68ffa0c592712652344 100644
--- a/Framework/Geometry/test/InstrumentTest.h
+++ b/Framework/Geometry/test/InstrumentTest.h
@@ -301,10 +301,8 @@ public:
 
   void test_GetDetector_With_A_List_Returns_A_Group() {
     const size_t ndets(3);
-    std::vector<detid_t> detIDs(ndets);
-    detIDs[0] = 1;
-    detIDs[1] = 10;
-    detIDs[2] = 11;
+    std::set<detid_t> detIDs{1, 10, 11};
+    std::vector<detid_t> detIDsVec(detIDs.begin(), detIDs.end());
 
     IDetector_const_sptr det;
     TS_ASSERT_THROWS_NOTHING(det = instrument.getDetectorG(detIDs));
@@ -315,14 +313,12 @@ public:
     TS_ASSERT_EQUALS(detGroup->nDets(), ndets);
     std::vector<detid_t> memberIDs = detGroup->getDetectorIDs();
     for (size_t i = 0; i < ndets; ++i) {
-      TS_ASSERT_EQUALS(memberIDs[i], detIDs[i]);
+      TS_ASSERT_EQUALS(memberIDs[i], detIDsVec[i]);
     }
   }
 
   void test_GetDetectors_Throws_With_Invalid_IDs() {
-    const size_t ndets(1);
-    std::vector<detid_t> detIDs(ndets);
-    detIDs[0] = 10000;
+    std::set<detid_t> detIDs{10000};
 
     std::vector<IDetector_const_sptr> dets;
     TS_ASSERT_THROWS(dets = instrument.getDetectors(detIDs),
diff --git a/Framework/Geometry/test/ObjComponentTest.h b/Framework/Geometry/test/ObjComponentTest.h
index a9f5bf5051babf65550d4b14954411fc47e7ef54..37f19be9f51d9fa5f5c8ba04090adae7a0a4167b 100644
--- a/Framework/Geometry/test/ObjComponentTest.h
+++ b/Framework/Geometry/test/ObjComponentTest.h
@@ -8,6 +8,7 @@
 #include "MantidGeometry/Surfaces/Cylinder.h"
 #include "MantidGeometry/Surfaces/Plane.h"
 #include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/Exception.h"
 
 #include "MantidKernel/Timer.h"
diff --git a/Framework/Geometry/test/ObjectTest.h b/Framework/Geometry/test/ObjectTest.h
index 17bbf3b128bfcc6cc2436ba2cd975ad0dae3ca42..85764166dac8008bc38886f08396fee54c9c22cb 100644
--- a/Framework/Geometry/test/ObjectTest.h
+++ b/Framework/Geometry/test/ObjectTest.h
@@ -21,15 +21,38 @@
 #include "MantidGeometry/Objects/Track.h"
 #include "MantidGeometry/Rendering/GluGeometryHandler.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
-
 #include "MantidKernel/Material.h"
-
+#include "MantidKernel/MersenneTwister.h"
+#include "MantidKernel/WarningSuppressions.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
+#include <gmock/gmock.h>
+
 using namespace Mantid;
 using namespace Geometry;
 using Mantid::Kernel::V3D;
 
+namespace {
+// -----------------------------------------------------------------------------
+// Mock Random Number Generator
+// -----------------------------------------------------------------------------
+class MockRNG final : public Mantid::Kernel::PseudoRandomNumberGenerator {
+public:
+  GCC_DIAG_OFF_SUGGEST_OVERRIDE
+  MOCK_METHOD0(nextValue, double());
+  MOCK_METHOD2(nextValue, double(double, double));
+  MOCK_METHOD2(nextInt, int(int, int));
+  MOCK_METHOD0(restart, void());
+  MOCK_METHOD0(save, void());
+  MOCK_METHOD0(restore, void());
+  MOCK_METHOD1(setSeed, void(size_t));
+  MOCK_METHOD2(setRange, void(const double, const double));
+  MOCK_CONST_METHOD0(min, double());
+  MOCK_CONST_METHOD0(max, double());
+  GCC_DIAG_ON_SUGGEST_OVERRIDE
+};
+}
+
 class ObjectTest : public CxxTest::TestSuite {
 
 public:
@@ -53,8 +76,7 @@ public:
   }
 
   void testCopyConstructorGivesObjectWithSameAttributes() {
-    Object_sptr original =
-        ComponentCreationHelper::createSphere(1.0, V3D(), "sphere");
+    Object_sptr original = ComponentCreationHelper::createSphere(1.0);
     original->setID("sp-1");
     int objType(-1);
     double radius(-1.0), height(-1.0);
@@ -80,8 +102,7 @@ public:
   }
 
   void testAssignmentOperatorGivesObjectWithSameAttributes() {
-    Object_sptr original =
-        ComponentCreationHelper::createSphere(1.0, V3D(), "sphere");
+    Object_sptr original = ComponentCreationHelper::createSphere(1.0);
     original->setID("sp-1");
     int objType(-1);
     double radius(-1.0), height(-1.0);
@@ -181,7 +202,7 @@ public:
   }
 
   void testIsOnSideSphere() {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     // inside
     TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0, 0, 0)), false); // origin
     TS_ASSERT_EQUALS(geom_obj->isOnSide(V3D(0, 4.0, 0)), false);
@@ -202,7 +223,7 @@ public:
   }
 
   void testIsValidSphere() {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     // inside
     TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0, 0, 0)), true); // origin
     TS_ASSERT_EQUALS(geom_obj->isValid(V3D(0, 4.0, 0)), true);
@@ -223,7 +244,7 @@ public:
   }
 
   void testCalcValidTypeSphere() {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     // entry on the normal
     TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1, 0, 0), V3D(1, 0, 0)), 1);
     TS_ASSERT_EQUALS(geom_obj->calcValidType(V3D(-4.1, 0, 0), V3D(-1, 0, 0)),
@@ -246,7 +267,7 @@ public:
   }
 
   void testGetBoundingBoxForSphere() {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     const double tolerance(1e-10);
 
     double xmax, ymax, zmax, xmin, ymin, zmin;
@@ -322,7 +343,7 @@ public:
 
   void testInterceptSurfaceSphereY() {
     std::vector<Link> expectedResults;
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     Track track(V3D(0, -10, 0), V3D(0, 1, 0));
 
     // format = startPoint, endPoint, total distance so far
@@ -334,7 +355,7 @@ public:
 
   void testInterceptSurfaceSphereX() {
     std::vector<Link> expectedResults;
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     Track track(V3D(-10, 0, 0), V3D(1, 0, 0));
 
     // format = startPoint, endPoint, total distance so far
@@ -555,7 +576,7 @@ public:
   }
 
   void testComplementWithTwoPrimitives() {
-    auto shell = createSphericalShell();
+    auto shell = ComponentCreationHelper::createHollowShell(0.5, 1.0);
 
     TS_ASSERT_EQUALS(2, shell->getSurfaceIndex().size());
 
@@ -566,7 +587,7 @@ public:
     TS_ASSERT_EQUALS("SurfPoint", leaf1->className());
     auto surfPt1 = dynamic_cast<const SurfPoint *>(leaf1);
     TS_ASSERT(surfPt1);
-    TS_ASSERT_EQUALS(1, surfPt1->getKeyN());
+    TS_ASSERT_EQUALS(2, surfPt1->getKeyN());
     auto outer = dynamic_cast<const Sphere *>(surfPt1->getKey());
     TS_ASSERT(outer);
     TS_ASSERT_DELTA(1.0, outer->getRadius(), 1e-10);
@@ -577,7 +598,7 @@ public:
     TS_ASSERT(compRule);
     TS_ASSERT_EQUALS("SurfPoint", compRule->leaf(0)->className());
     auto surfPt2 = dynamic_cast<const SurfPoint *>(compRule->leaf(0));
-    TS_ASSERT_EQUALS(2, surfPt2->getKeyN());
+    TS_ASSERT_EQUALS(1, surfPt2->getKeyN());
     auto inner = dynamic_cast<const Sphere *>(surfPt2->getKey());
     TS_ASSERT(inner);
     TS_ASSERT_DELTA(0.5, inner->getRadius(), 1e-10);
@@ -661,17 +682,83 @@ public:
                          -M_SQRT2 - 0.5 * M_SQRT1_2,
                          -M_SQRT2 - 0.5 * M_SQRT1_2);
     TS_ASSERT_EQUALS(F->getPointInObject(pt), 1);
-    Object_sptr S = createSphere();
+    Object_sptr S = ComponentCreationHelper::createSphere(4.1);
     TS_ASSERT_EQUALS(S->getPointInObject(pt), 1);
     TS_ASSERT_EQUALS(pt, V3D(0.0, 0.0, 0));
   }
 
+  void testGeneratePointInside() {
+    using namespace ::testing;
+
+    // Generate "random" sequence
+    MockRNG rng;
+    Sequence rand;
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.55));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.65));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.70));
+
+    // inner radius=0.5, outer=1. Random sequence set up so as to give point
+    // inside hole
+    auto shell = ComponentCreationHelper::createHollowShell(0.5, 1.0);
+    size_t maxAttempts(1);
+    V3D point;
+    TS_ASSERT_THROWS_NOTHING(
+        point = shell->generatePointInObject(rng, maxAttempts));
+
+    const double tolerance(1e-10);
+    TS_ASSERT_DELTA(-1. + 2. * 0.55, point.X(), tolerance);
+    TS_ASSERT_DELTA(-1. + 2. * 0.65, point.Y(), tolerance);
+    TS_ASSERT_DELTA(-1. + 2. * 0.70, point.Z(), tolerance);
+  }
+
+  void testGeneratePointInsideRespectsMaxAttempts() {
+    using namespace ::testing;
+
+    // Generate "random" sequence
+    MockRNG rng;
+    Sequence rand;
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.1));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.2));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.3));
+
+    // inner radius=0.5, outer=1. Random sequence set up so as to give point
+    // inside hole
+    auto shell = ComponentCreationHelper::createHollowShell(0.5, 1.0);
+    size_t maxAttempts(1);
+    TS_ASSERT_THROWS(shell->generatePointInObject(rng, maxAttempts),
+                     std::runtime_error);
+  }
+
+  void testGeneratePointInsideRespectsActiveRegion() {
+    using namespace ::testing;
+
+    // Generate "random" sequence.
+    MockRNG rng;
+    Sequence rand;
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.01));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.02));
+    EXPECT_CALL(rng, nextValue()).InSequence(rand).WillOnce(Return(0.03));
+
+    // Radius=0.5
+    auto ball = ComponentCreationHelper::createSphere(0.5);
+    // Create a thin infinite rectangular region to restrict point generation
+    BoundingBox activeRegion(0.1, 0.1, 0.1, -0.1, -0.1, -0.1);
+    size_t maxAttempts(1);
+    V3D point;
+    TS_ASSERT_THROWS_NOTHING(
+        point = ball->generatePointInObject(rng, activeRegion, maxAttempts));
+    const double tolerance(1e-10);
+    TS_ASSERT_DELTA(-0.1 + 0.01 * 0.2, point.X(), tolerance);
+    TS_ASSERT_DELTA(-0.1 + 0.02 * 0.2, point.Y(), tolerance);
+    TS_ASSERT_DELTA(-0.1 + 0.03 * 0.2, point.Z(), tolerance);
+  }
+
   void testSolidAngleSphere()
   /**
   Test solid angle calculation for a sphere
   */
   {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     double satol = 2e-2; // tolerance for solid angle
 
     // Solid angle at distance 8.1 from centre of sphere radius 4.1 x/y/z
@@ -936,7 +1023,7 @@ public:
   Test solid angle calculation for a sphere from triangulation
   */
   {
-    Object_sptr geom_obj = createSphere();
+    Object_sptr geom_obj = ComponentCreationHelper::createSphere(4.1);
     double satol = 1e-3; // tolerance for solid angle
 
     // Solid angle at distance 8.1 from centre of sphere radius 4.1 x/y/z
@@ -1026,45 +1113,6 @@ private:
     return retVal;
   }
 
-  Object_sptr createSphere() {
-    std::string S41 = "so 4.1"; // Sphere at origin radius 4.1
-
-    // First create some surfaces
-    std::map<int, boost::shared_ptr<Surface>> SphSurMap;
-    SphSurMap[41] = boost::make_shared<Sphere>();
-    SphSurMap[41]->setSurface(S41);
-    SphSurMap[41]->setName(41);
-
-    // A sphere
-    std::string ObjSphere = "-41";
-
-    Object_sptr retVal = Object_sptr(new Object);
-    retVal->setObject(41, ObjSphere);
-    retVal->populate(SphSurMap);
-
-    return retVal;
-  }
-
-  Object_sptr createSphericalShell() {
-    // First create some surfaces
-    auto outer = boost::make_shared<Sphere>();
-    outer->setName(1);
-    outer->setRadius(1.0);
-    auto inner = boost::make_shared<Sphere>();
-    inner->setName(2);
-    inner->setRadius(0.5);
-    std::map<int, boost::shared_ptr<Surface>> surfaces = {{1, outer},
-                                                          {2, inner}};
-
-    // algebra string is outer with intersection of complement of inner
-    const std::string algebra = "(-1) # (-2)";
-    auto shell = boost::make_shared<Object>();
-    shell->setObject(21, algebra);
-    shell->populate(surfaces);
-
-    return shell;
-  }
-
   void clearSurfMap()
   /**
   Clears the surface map for a new test
@@ -1294,4 +1342,43 @@ private:
   }
 };
 
+// -----------------------------------------------------------------------------
+// Performance tests
+// -----------------------------------------------------------------------------
+class ObjectTestPerformance : 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 ObjectTestPerformance *createSuite() {
+    return new ObjectTestPerformance();
+  }
+  static void destroySuite(ObjectTestPerformance *suite) { delete suite; }
+
+  ObjectTestPerformance()
+      : rng(200000), solid(ComponentCreationHelper::createSphere(0.1)),
+        shell(ComponentCreationHelper::createHollowShell(0.009, 0.01)) {}
+
+  void test_generatePointInside_Solid_Primitive() {
+    const size_t maxAttempts(500);
+    V3D dummy;
+    for (size_t i = 0; i < npoints; ++i) {
+      dummy = solid->generatePointInObject(rng, maxAttempts);
+    }
+  }
+
+  void test_Point_Inside_Solid_Composite_With_Hole() {
+    const size_t maxAttempts(500);
+    V3D dummy;
+    for (size_t i = 0; i < npoints; ++i) {
+      dummy = shell->generatePointInObject(rng, maxAttempts);
+    }
+  }
+
+private:
+  const size_t npoints = 20000;
+  Mantid::Kernel::MersenneTwister rng;
+  Object_sptr solid;
+  Object_sptr shell;
+};
+
 #endif // MANTID_TESTOBJECT__
diff --git a/Framework/Geometry/test/ParObjComponentTest.h b/Framework/Geometry/test/ParObjComponentTest.h
index b59bd6e9b8cf7e4bc3d1dfc123ab133cbfb43dd0..97a1d8c11de4e5abcf19fdd28299850ca5313248 100644
--- a/Framework/Geometry/test/ParObjComponentTest.h
+++ b/Framework/Geometry/test/ParObjComponentTest.h
@@ -9,6 +9,7 @@
 #include "MantidGeometry/Surfaces/Cylinder.h"
 #include "MantidGeometry/Surfaces/Plane.h"
 #include "MantidGeometry/Objects/Object.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/Exception.h"
 
 #include "boost/make_shared.hpp"
diff --git a/Framework/Geometry/test/ParameterMapTest.h b/Framework/Geometry/test/ParameterMapTest.h
index 96bc3e32a4ca05eb4aea0f3f4c1f91609ac0891f..4b3a053d158009296e6fe6e3ec95f8a642f8a5ab 100644
--- a/Framework/Geometry/test/ParameterMapTest.h
+++ b/Framework/Geometry/test/ParameterMapTest.h
@@ -2,6 +2,7 @@
 #define PARAMETERMAPTEST_H_
 
 #include "MantidGeometry/Instrument/Parameter.h"
+#include "MantidGeometry/Instrument/ParameterFactory.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/Instrument/Detector.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
diff --git a/Framework/Geometry/test/SampleEnvironmentFactoryTest.h b/Framework/Geometry/test/SampleEnvironmentFactoryTest.h
index 06290556258504d693be53760501fab00137dc23..65a6b4f07ce912d43225cf56a8b6b68a6ccec1eb 100644
--- a/Framework/Geometry/test/SampleEnvironmentFactoryTest.h
+++ b/Framework/Geometry/test/SampleEnvironmentFactoryTest.h
@@ -5,6 +5,7 @@
 #include "MantidGeometry/Instrument/SampleEnvironmentFactory.h"
 #include "MantidGeometry/Instrument/Container.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidKernel/make_unique.h"
 
 #include "MantidTestHelpers/ComponentCreationHelper.h"
 
diff --git a/Framework/Geometry/test/SampleEnvironmentTest.h b/Framework/Geometry/test/SampleEnvironmentTest.h
index 1326e5dc00306cb88110f9fb8f769b4dc165079f..4acf34dbca96941e8d1afb22fd76258b9d88d89a 100644
--- a/Framework/Geometry/test/SampleEnvironmentTest.h
+++ b/Framework/Geometry/test/SampleEnvironmentTest.h
@@ -3,14 +3,39 @@
 
 #include "MantidGeometry/Instrument/SampleEnvironment.h"
 #include "MantidGeometry/Objects/ShapeFactory.h"
+#include "MantidGeometry/Objects/Track.h"
 #include "MantidKernel/V3D.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
+#include "MantidKernel/PseudoRandomNumberGenerator.h"
+#include "MantidKernel/WarningSuppressions.h"
 
 #include <boost/make_shared.hpp>
 #include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
 
 using Mantid::Geometry::SampleEnvironment;
 
+namespace {
+// -----------------------------------------------------------------------------
+// Mock Random Number Generator
+// -----------------------------------------------------------------------------
+class MockRNG final : public Mantid::Kernel::PseudoRandomNumberGenerator {
+public:
+  GCC_DIAG_OFF_SUGGEST_OVERRIDE
+  MOCK_METHOD0(nextValue, double());
+  MOCK_METHOD2(nextValue, double(double, double));
+  MOCK_METHOD2(nextInt, int(int, int));
+  MOCK_METHOD0(restart, void());
+  MOCK_METHOD0(save, void());
+  MOCK_METHOD0(restore, void());
+  MOCK_METHOD1(setSeed, void(size_t));
+  MOCK_METHOD2(setRange, void(const double, const double));
+  MOCK_CONST_METHOD0(min, double());
+  MOCK_CONST_METHOD0(max, double());
+  GCC_DIAG_ON_SUGGEST_OVERRIDE
+};
+}
+
 class SampleEnvironmentTest : public CxxTest::TestSuite {
 public:
   // This pair of boilerplate methods prevent the suite being created statically
@@ -82,6 +107,78 @@ public:
     TS_ASSERT_DELTA(0.2, widths.Z(), 1e-12);
   }
 
+  void testGeneratePointConsidersAllComponents() {
+    using namespace ::testing;
+    using namespace Mantid::Kernel;
+
+    auto kit = createTestKit();
+    size_t maxAttempts(1);
+
+    // Generate "random" sequence
+    MockRNG rng;
+    // Selects first component
+    EXPECT_CALL(rng, nextInt(_, _)).Times(Exactly(1)).WillOnce(Return(1));
+    EXPECT_CALL(rng, nextValue())
+        .Times(3)
+        .WillOnce(Return(0.55))
+        .WillOnce(Return(0.65))
+        .WillOnce(Return(0.70));
+    V3D comp1Point;
+    TS_ASSERT_THROWS_NOTHING(comp1Point = kit->generatePoint(rng, maxAttempts));
+    TS_ASSERT(kit->isValid(comp1Point));
+    Mock::VerifyAndClearExpectations(&rng);
+
+    // Selects second component
+    EXPECT_CALL(rng, nextInt(_, _)).Times(Exactly(1)).WillOnce(Return(2));
+    EXPECT_CALL(rng, nextValue())
+        .Times(3)
+        .WillOnce(Return(0.55))
+        .WillOnce(Return(0.65))
+        .WillOnce(Return(0.70));
+    V3D comp2Point;
+    TS_ASSERT_THROWS_NOTHING(comp2Point = kit->generatePoint(rng, maxAttempts));
+    TS_ASSERT(comp2Point != comp1Point);
+    TS_ASSERT(kit->isValid(comp2Point));
+    Mock::VerifyAndClearExpectations(&rng);
+
+    // Selects third component
+    EXPECT_CALL(rng, nextInt(_, _)).Times(Exactly(1)).WillOnce(Return(3));
+    EXPECT_CALL(rng, nextValue())
+        .Times(3)
+        .WillOnce(Return(0.55))
+        .WillOnce(Return(0.65))
+        .WillOnce(Return(0.70));
+    V3D comp3Point;
+    TS_ASSERT_THROWS_NOTHING(comp3Point = kit->generatePoint(rng, maxAttempts));
+    TS_ASSERT(comp3Point != comp2Point);
+    TS_ASSERT(comp3Point != comp1Point);
+    TS_ASSERT(kit->isValid(comp3Point));
+    Mock::VerifyAndClearExpectations(&rng);
+  }
+
+  void testGeneratePointRespectsActiveRegion() {
+    using namespace ::testing;
+    using namespace Mantid::Kernel;
+
+    auto kit = createTestKit();
+    size_t maxAttempts(1);
+
+    // Generate "random" sequence
+    MockRNG rng;
+    // Sequence will try to select one of the non-container pieces
+    EXPECT_CALL(rng, nextInt(_, _)).Times(Exactly(1)).WillOnce(Return(2));
+    EXPECT_CALL(rng, nextValue())
+        .Times(3)
+        .WillOnce(Return(0.5))
+        .WillOnce(Return(0.5))
+        .WillOnce(Return(0.5));
+    // Restrict region to can
+    TS_ASSERT_THROWS(kit->generatePoint(rng, kit->container()->getBoundingBox(),
+                                        maxAttempts),
+                     std::runtime_error);
+    Mock::VerifyAndClearExpectations(&rng);
+  }
+
 private:
   boost::shared_ptr<SampleEnvironment> createTestKit() {
     using namespace Mantid::Geometry;
diff --git a/Framework/Geometry/test/TrackTest.h b/Framework/Geometry/test/TrackTest.h
index 2de7b8eb9b476e96f7f618340de61f1340bf3d8a..c9e82ea561bd831c99c1f4de47b6acf073472fc8 100644
--- a/Framework/Geometry/test/TrackTest.h
+++ b/Framework/Geometry/test/TrackTest.h
@@ -40,6 +40,9 @@ public:
     Track A(V3D(1, 1, 1), V3D(1.0, 0.0, 0.0));
     Object shape;
     A.addLink(V3D(2, 2, 2), V3D(3, 3, 3), 2.0, shape, NULL);
+    const auto &linkFront = A.front();
+    const auto &linkBack = A.back();
+    TS_ASSERT_EQUALS(&linkFront, &linkBack);
     Track::LType::const_iterator iterBegin = A.cbegin();
     Track::LType::const_iterator iterEnd = A.cend();
     iterBegin++;
diff --git a/Framework/ICat/src/CatalogKeepAlive.cpp b/Framework/ICat/src/CatalogKeepAlive.cpp
index 0bc549faa7aaf5effd3b28561fd38281cd4d5d08..fb55f97be3ede909c37f4a1f18c5bb95b6599d1d 100644
--- a/Framework/ICat/src/CatalogKeepAlive.cpp
+++ b/Framework/ICat/src/CatalogKeepAlive.cpp
@@ -1,5 +1,6 @@
 #include "MantidICat/CatalogKeepAlive.h"
 #include "MantidAPI/CatalogManager.h"
+#include "MantidKernel/DateAndTime.h"
 
 #include <Poco/Thread.h>
 
diff --git a/Framework/ICat/test/ICatTestHelper.cpp b/Framework/ICat/test/ICatTestHelper.cpp
index 199bb9d6eaf3eb5999cee4b0b8eba0e0e561ae58..5b3b18968181bb66e3940b8fb6b9e82d2f53178d 100644
--- a/Framework/ICat/test/ICatTestHelper.cpp
+++ b/Framework/ICat/test/ICatTestHelper.cpp
@@ -1,5 +1,7 @@
 #include "ICatTestHelper.h"
 
+#include <iostream>
+
 namespace ICatTestHelper {
 /// Skip all unit tests if ICat server is down
 bool skipTests() {
diff --git a/Framework/Kernel/CMakeLists.txt b/Framework/Kernel/CMakeLists.txt
index 13322c64d1ad0db42f0367413015cfe1e466df52..62d90c4ab0f31ed579f8e629e36249cc28762843 100644
--- a/Framework/Kernel/CMakeLists.txt
+++ b/Framework/Kernel/CMakeLists.txt
@@ -43,6 +43,7 @@ set ( SRC_FILES
 	src/Interpolation.cpp
 	src/LibraryManager.cpp
 	src/LibraryWrapper.cpp
+	src/LiveListenerInfo.cpp
 	src/LogFilter.cpp
 	src/LogParser.cpp
 	src/Logger.cpp
@@ -148,6 +149,7 @@ set ( INC_FILES
 	inc/MantidKernel/BoundedValidator.h
 	inc/MantidKernel/CPUTimer.h
 	inc/MantidKernel/Cache.h
+	inc/MantidKernel/CaseInsensitiveMap.h
 	inc/MantidKernel/CatalogInfo.h
 	inc/MantidKernel/Chainable.h
 	inc/MantidKernel/ChainableFactory.h
@@ -198,6 +200,7 @@ set ( INC_FILES
 	inc/MantidKernel/LibraryManager.h
 	inc/MantidKernel/LibraryWrapper.h
 	inc/MantidKernel/ListValidator.h
+	inc/MantidKernel/LiveListenerInfo.h
 	inc/MantidKernel/LogFilter.h
 	inc/MantidKernel/LogParser.h
 	inc/MantidKernel/Logger.h
@@ -239,13 +242,14 @@ set ( INC_FILES
 	inc/MantidKernel/ProgressBase.h
 	inc/MantidKernel/ProgressText.h
 	inc/MantidKernel/Property.h
+	inc/MantidKernel/PropertyHelper.h
 	inc/MantidKernel/PropertyHistory.h
 	inc/MantidKernel/PropertyManager.h
 	inc/MantidKernel/PropertyManagerDataService.h
 	inc/MantidKernel/PropertyManagerOwner.h
 	inc/MantidKernel/PropertyManagerProperty.h
 	inc/MantidKernel/PropertyManager_fwd.h
-    	inc/MantidKernel/PropertyNexus.h
+	inc/MantidKernel/PropertyNexus.h
 	inc/MantidKernel/PropertyWithValue.h
 	inc/MantidKernel/ProxyInfo.h
 	inc/MantidKernel/PseudoRandomNumberGenerator.h
@@ -295,8 +299,7 @@ set ( INC_FILES
 	inc/MantidKernel/WarningSuppressions.h
 	inc/MantidKernel/WriteLock.h
 	inc/MantidKernel/XMLInstantiator.h
-  inc/MantidKernel/CaseInsensitiveMap.h
-  inc/MantidKernel/cow_ptr.h
+	inc/MantidKernel/cow_ptr.h
 	inc/MantidKernel/make_cow.h
 	inc/MantidKernel/make_unique.h
 )
@@ -351,6 +354,7 @@ set ( TEST_FILES
 	InternetHelperTest.h
 	InterpolationTest.h
 	ListValidatorTest.h
+	LiveListenerInfoTest.h
 	LogFilterTest.h
 	LogParserTest.h
 	LoggerTest.h
diff --git a/Framework/Kernel/inc/MantidKernel/ArrayProperty.h b/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
index bccc9de20ad92e5e7f5d1c630b793d89bb1f9770..8783a389bcaf267d037ab9c73f2a4dbd30a02d7e 100644
--- a/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/ArrayProperty.h
@@ -1,9 +1,6 @@
 #ifndef MANTID_KERNEL_ARRAYPROPERTY_H_
 #define MANTID_KERNEL_ARRAYPROPERTY_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "PropertyWithValue.h"
 
 namespace Mantid {
@@ -39,94 +36,27 @@ namespace Kernel {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
 template <typename T>
-class DLLExport ArrayProperty : public PropertyWithValue<std::vector<T>> {
+class ArrayProperty : public PropertyWithValue<std::vector<T>> {
 public:
-  /** Constructor
-   *  @param name ::      The name to assign to the property
-   *  @param vec ::       The initial vector of values to assign to the
-   * property.
-   *  @param validator :: The validator to use for this property, if required.
-   *  @param direction :: The direction (Input/Output/InOut) of this property
-   */
   ArrayProperty(const std::string &name, const std::vector<T> &vec,
                 IValidator_sptr validator = IValidator_sptr(new NullValidator),
-                const unsigned int direction = Direction::Input)
-      : PropertyWithValue<std::vector<T>>(name, vec, validator, direction) {}
-
-  /** Constructor
-   *  Will lead to the property having a default-constructed (i.e. empty) vector
-   *  as its initial (default) value
-   *  @param name ::      The name to assign to the property
-   *  @param validator :: The validator to use for this property, if required
-   *  @param direction :: The direction (Input/Output/InOut) of this property
-   */
-
+                const unsigned int direction = Direction::Input);
   ArrayProperty(const std::string &name, IValidator_sptr validator,
-                const unsigned int direction = Direction::Input)
-      : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), validator,
-                                          direction) {}
-
-  /** Constructor that's useful for output properties or inputs with an empty
-   * default and no validator.
-   *  Will lead to the property having a default-constructed (i.e. empty) vector
-   *  as its initial (default) value and no validator
-   *  @param name ::      The name to assign to the property
-   *  @param direction :: The direction (Input/Output/InOut) of this property
-   */
+                const unsigned int direction = Direction::Input);
   ArrayProperty(const std::string &name,
-                const unsigned int direction = Direction::Input)
-      : PropertyWithValue<std::vector<T>>(name, std::vector<T>(),
-                                          IValidator_sptr(new NullValidator),
-                                          direction) {}
-
-  /** Constructor from which you can set the property's values through a string:
-   *
-   * Inherits from the constructor of PropertyWithValue specifically made to
-   * handle a list
-   * of numeric values in a string format so that initial value is set
-   * correctly.
-   *
-   *  @param name ::      The name to assign to the property
-   *  @param values ::    A comma-separated string containing the values to
-   * store in the property
-   *  @param validator :: The validator to use for this property, if required
-   *  @param direction :: The direction (Input/Output/InOut) of this property
-   *  @throw std::invalid_argument if the string passed is not compatible with
-   * the array type
-   */
+                const unsigned int direction = Direction::Input);
   ArrayProperty(const std::string &name, const std::string &values,
                 IValidator_sptr validator = IValidator_sptr(new NullValidator),
-                const unsigned int direction = Direction::Input)
-      : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), values,
-                                          validator, direction) {}
+                const unsigned int direction = Direction::Input);
 
-  /// 'Virtual copy constructor'
-  ArrayProperty<T> *clone() const override {
-    return new ArrayProperty<T>(*this);
-  }
+  ArrayProperty<T> *clone() const override;
 
   // Unhide the base class assignment operator
   using PropertyWithValue<std::vector<T>>::operator=;
 
-  /** Returns the values stored in the ArrayProperty
-   *  @return The stored values as a comma-separated list
-   */
-  std::string value() const override {
-    // Implemented this method for documentation reasons. Just calls base class
-    // method.
-    return PropertyWithValue<std::vector<T>>::value();
-  }
+  std::string value() const override;
 
-  /** Sets the values stored in the ArrayProperty from a string representation
-   *  @param value :: The values to assign to the property, given as a
-   * comma-separated list
-   *  @return True if the assignment was successful
-   */
-  std::string setValue(const std::string &value) override {
-    // Implemented this method for documentation reasons. Just calls base class
-    // method.
-    return PropertyWithValue<std::vector<T>>::setValue(value);
-  }
+  std::string setValue(const std::string &value) override;
   // May want to add specialisation the the class later, e.g. setting just one
   // element of the vector
 };
diff --git a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
index 7f203ce9057e4aa7c5617fdd50fa85f3214353e0..625381c994f7c054914643084697a22da39653a7 100644
--- a/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
+++ b/Framework/Kernel/inc/MantidKernel/DynamicFactory.h
@@ -18,10 +18,8 @@
 // Poco
 #include <Poco/Notification.h>
 #include <Poco/NotificationCenter.h>
-#include <Poco/AutoPtr.h>
 
 // std
-#include <cstring>
 #include <functional>
 #include <iterator>
 #include <vector>
diff --git a/Framework/Kernel/inc/MantidKernel/EmptyValues.h b/Framework/Kernel/inc/MantidKernel/EmptyValues.h
index 411e660305cd4ab1e3b206ce7b67a47b5a9e4d09..343abf06d4bead86bc774c0ab37d42ce074703ba 100644
--- a/Framework/Kernel/inc/MantidKernel/EmptyValues.h
+++ b/Framework/Kernel/inc/MantidKernel/EmptyValues.h
@@ -37,6 +37,9 @@ DLLExport int EMPTY_INT();
 /// Returns what we consider an "empty" long
 DLLExport long EMPTY_LONG();
 
+/// Returns what we consider an "empty" int64_t
+DLLExport int64_t EMPTY_INT64();
+
 /// Return what we consider to be an empty double
 DLLExport double EMPTY_DBL();
 }
diff --git a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
index d8c66b9bb9b3e45f272037c1ce8df28ec6aa64cb..c4484eab302d27443c14f4baa10ad9cac7a2f7b3 100644
--- a/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/FacilityInfo.h
@@ -71,8 +71,6 @@ public:
   const std::vector<std::string> &archiveSearch() const {
     return m_archiveSearch;
   }
-  /// Returns the name of the default live listener
-  const std::string &liveListener() const { return m_liveListener; }
   /// Returns a list of instruments of this facility
   const std::vector<InstrumentInfo> &instruments() const {
     return m_instruments;
@@ -104,7 +102,6 @@ private:
   void fillExtensions(const Poco::XML::Element *elem);
   void fillArchiveNames(const Poco::XML::Element *elem);
   void fillInstruments(const Poco::XML::Element *elem);
-  void fillLiveListener(const Poco::XML::Element *elem);
   void fillHTTPProxy(const Poco::XML::Element *elem);
   void fillComputeResources(const Poco::XML::Element *elem);
   void fillNoFilePrefix(const Poco::XML::Element *elem);
@@ -122,8 +119,7 @@ private:
   std::vector<std::string>
       m_archiveSearch; ///< names of the archive search interface
   std::vector<InstrumentInfo>
-      m_instruments;          ///< list of instruments of this facility
-  std::string m_liveListener; ///< name of the default live listener
+      m_instruments;   ///< list of instruments of this facility
   bool m_noFilePrefix; ///< flag indicating if prefix is required in file names
   std::vector<ComputeResourceInfo> m_computeResInfos; ///< (remote) compute
   /// resources available in
diff --git a/Framework/Kernel/inc/MantidKernel/IPropertyManager.h b/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
index 9faae704401eedc1f5f9fedf093553979c318520..c38d263cb912f508ce34fff631f0bba3dfd8c31e 100644
--- a/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
+++ b/Framework/Kernel/inc/MantidKernel/IPropertyManager.h
@@ -1,12 +1,15 @@
 #ifndef MANTID_KERNEL_IPROPERTYMANAGER_H_
 #define MANTID_KERNEL_IPROPERTYMANAGER_H_
 
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidKernel/PropertyWithValue.h"
 #include "MantidKernel/OptionalBool.h"
 #include "MantidKernel/make_unique.h"
+
+#ifndef Q_MOC_RUN
+#include <boost/make_shared.hpp>
+#include <boost/type_traits.hpp>
+#endif
+
 #include <vector>
 #include <unordered_set>
 
@@ -18,12 +21,10 @@ namespace Mantid {
 
 namespace Kernel {
 
-//----------------------------------------------------------------------
-// Forward Declaration
-//----------------------------------------------------------------------
 class Logger;
 class DataItem;
 class DateAndTime;
+class IPropertySettings;
 class PropertyManager;
 template <typename T> class TimeSeriesProperty;
 template <typename T> class Matrix;
@@ -139,10 +140,7 @@ public:
    */
   template <typename T>
   IPropertyManager *setProperty(const std::string &name, const T &value) {
-    setTypedProperty(name, value,
-                     boost::is_convertible<T, boost::shared_ptr<DataItem>>());
-    this->afterPropertySet(name);
-    return this;
+    return doSetProperty(name, value);
   }
 
   /** Templated method to set the value of a PropertyWithValue from a
@@ -197,17 +195,9 @@ public:
   /// Return the property manager serialized as a json object.
   virtual ::Json::Value asJson(bool withDefaultValues = false) const = 0;
 
-  /** Give settings to a property to determine when it gets enabled/hidden.
-   * Passes ownership of the given IPropertySettings object to the named
-   * property
-   * @param name :: property name
-   * @param settings :: IPropertySettings     */
   void setPropertySettings(const std::string &name,
-                           std::unique_ptr<IPropertySettings> settings) {
-    Property *prop = getPointerToProperty(name);
-    if (prop)
-      prop->setSettings(std::move(settings));
-  }
+                           std::unique_ptr<IPropertySettings> settings);
+
   /** Set the group for a given property
    * @param name :: property name
    * @param group :: Name of the group it belongs to     */
@@ -444,6 +434,45 @@ public:
   virtual Property *getPointerToProperty(const std::string &name) const = 0;
 
 private:
+  /** Helper method to set the value of a PropertyWithValue
+   *  @param name :: The name of the property (case insensitive)
+   *  @param value :: The value to assign to the property
+   *  @throw Exception::NotFoundError If the named property is unknown
+   *  @throw std::invalid_argument If an attempt is made to assign to a property
+   * of different type
+   */
+  template <typename T>
+  IPropertyManager *doSetProperty(const std::string &name, const T &value) {
+    setTypedProperty(name, value,
+                     boost::is_convertible<T, boost::shared_ptr<DataItem>>());
+    this->afterPropertySet(name);
+    return this;
+  }
+
+  /** Helper method to set the value of a PropertyWithValue, variant for
+   * shared_ptr types. This variant is required to enforce checks for complete
+   * types, do not remove it.
+   *  @param name :: The name of the property (case insensitive)
+   *  @param value :: The value to assign to the property
+   *  @throw Exception::NotFoundError If the named property is unknown
+   *  @throw std::invalid_argument If an attempt is made to assign to a property
+   * of different type
+   */
+  template <typename T>
+  IPropertyManager *doSetProperty(const std::string &name,
+                                  const boost::shared_ptr<T> &value) {
+    // CAREFUL: is_convertible has undefined behavior for incomplete types. If T
+    // is forward-declared in the calling code, e.g., an algorithm that calls
+    // setProperty, compilation and linking do work. However, the BEHAVIOR IS
+    // UNDEFINED and the compiler will not complain, but things crash or go
+    // wrong badly. To circumvent this we call `sizeof` here to force a compiler
+    // error if T is an incomplete type.
+    static_cast<void>(sizeof(T)); // DO NOT REMOVE, enforces complete type
+    setTypedProperty(name, value, boost::is_convertible<T *, DataItem *>());
+    this->afterPropertySet(name);
+    return this;
+  }
+
   /**
    * Set a property value that is not convertible to a DataItem_sptr
    *  @param name :: The name of the property (case insensitive)
diff --git a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
index d42957f6d9d05a258fe7345bdd50534a9ad33926..85dc0b5de58cf210a3559df30da1dddf9fb52cbe 100644
--- a/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
+++ b/Framework/Kernel/inc/MantidKernel/InstrumentInfo.h
@@ -5,9 +5,12 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidKernel/DllConfig.h"
+#include "MantidKernel/LiveListenerInfo.h"
+
 #include <set>
 #include <string>
 #include <map>
+#include <vector>
 
 //----------------------------------------------------------------------
 // Forward declarations
@@ -64,16 +67,22 @@ public:
   std::string filePrefix(unsigned int runNumber) const;
   /// Returns the default delimiter between instrument name and run number
   std::string delimiter() const;
-  /// Returns the name of the live listener
-  const std::string &liveListener() const;
-  /// Returns an object representing the host & port to connect to for a live
-  /// data stream
-  const std::string &liveDataAddress() const;
   /// Return list of techniques
   const std::set<std::string> &techniques() const;
   /// The facility to which this instrument belongs
   const FacilityInfo &facility() const;
 
+  /// Returns the name of the default live listener
+  std::string liveListener(const std::string &name = "") const;
+  /// Returns a string containing the "host:port" for default live listener
+  std::string liveDataAddress(const std::string &name = "") const;
+  /// Returns LiveListenerInfo for specified connection name (or default)
+  const LiveListenerInfo &liveListenerInfo(std::string name = "") const;
+  /// Returns true if this instrument has at least one live listener defined
+  bool hasLiveListenerInfo() const;
+  /// Returns all available LiveListenerInfos as a vector
+  const std::vector<LiveListenerInfo> &liveListenerInfoList() const;
+
 private:
   void fillTechniques(const Poco::XML::Element *elem);
   void fillLiveData(const Poco::XML::Element *elem);
@@ -96,10 +105,11 @@ private:
   std::string m_shortName;        ///< Instrument short name
   ZeroPaddingMap m_zeroPadding;   ///< Run number-dependent zero padding
   std::string m_delimiter; ///< Delimiter between instrument name and run number
-  std::string m_liveListener;    ///< Name of the live listener class
-  std::string m_liveDataAddress; ///< Host & port for live data connection
   std::set<std::string>
       m_technique; ///< List of techniques the instrument can do
+
+  std::vector<LiveListenerInfo> m_listeners; ///< LiveListener connections
+  std::string m_defaultListener; ///< Default LiveListener connection to use
 };
 
 /// Allow this object to be printed to a stream
diff --git a/Framework/Kernel/inc/MantidKernel/LiveListenerInfo.h b/Framework/Kernel/inc/MantidKernel/LiveListenerInfo.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d126e231b2f38207ef18925d4f8589dabccb717
--- /dev/null
+++ b/Framework/Kernel/inc/MantidKernel/LiveListenerInfo.h
@@ -0,0 +1,82 @@
+#ifndef MANTID_KERNEL_LIVELISTENERINFO_H_
+#define MANTID_KERNEL_LIVELISTENERINFO_H_
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include "MantidKernel/DllConfig.h"
+#include <string>
+
+//----------------------------------------------------------------------
+// Forward declarations
+//----------------------------------------------------------------------
+namespace Poco {
+namespace XML {
+class Element;
+}
+}
+
+namespace Mantid {
+namespace Kernel {
+
+//----------------------------------------------------------------------
+// Forward declarations
+//----------------------------------------------------------------------
+class InstrumentInfo;
+
+/**
+ * A class that holds information about a LiveListener connection.
+ *
+ * Copyright &copy; 2016 STFC Rutherford Appleton Laboratory
+ *
+ * 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 LiveListenerInfo {
+public:
+  LiveListenerInfo(InstrumentInfo *inst, const Poco::XML::Element *elem);
+  LiveListenerInfo(const std::string &listener = "",
+                   const std::string &address = "",
+                   const std::string &name = "");
+
+  /// Required for Python bindings
+  bool operator==(const LiveListenerInfo &rhs) const;
+
+  /// Return the name of this LiveListener connection
+  const std::string &name() const;
+
+  /// Returns the address string of this LiveListener connection
+  const std::string &address() const;
+
+  /// Returns the classname of the specific LiveListener to use
+  const std::string &listener() const;
+
+private:
+  std::string m_name;     ///< Listener name
+  std::string m_address;  ///< Listener address
+  std::string m_listener; ///< Listener classname
+};
+
+/// Allow this object to be printed to a stream
+MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &buffer,
+                                           const LiveListenerInfo &listener);
+
+} // namespace Kernel
+} // namespace Mantid
+
+#endif /* MANTID_KERNEL_LIVELISTENERINFO_H_ */
diff --git a/Framework/Kernel/inc/MantidKernel/MaskedProperty.h b/Framework/Kernel/inc/MantidKernel/MaskedProperty.h
index 79c15d52e0934dc70c7a252c01a85350a711c390..7c5a8db855dbc4b5b4105c574b3e826174cfed69 100644
--- a/Framework/Kernel/inc/MantidKernel/MaskedProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/MaskedProperty.h
@@ -41,8 +41,7 @@
 namespace Mantid {
 namespace Kernel {
 template <typename TYPE = std::string>
-class MANTID_KERNEL_DLL MaskedProperty
-    : public Kernel::PropertyWithValue<TYPE> {
+class MaskedProperty : public Kernel::PropertyWithValue<TYPE> {
 public:
   /// Constructor with a validator
   MaskedProperty(const std::string &name, TYPE defaultvalue,
diff --git a/Framework/Kernel/inc/MantidKernel/Matrix.h b/Framework/Kernel/inc/MantidKernel/Matrix.h
index 17d763e0c241ae321ce2065de994f809d21cd222..f5625946f5a5834614b94155c7913fb510f33ac2 100644
--- a/Framework/Kernel/inc/MantidKernel/Matrix.h
+++ b/Framework/Kernel/inc/MantidKernel/Matrix.h
@@ -4,7 +4,7 @@
 #include "MantidKernel/DllConfig.h"
 #include <vector>
 #include <cfloat>
-#include <ostream>
+#include <iosfwd>
 
 namespace Mantid {
 
diff --git a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
index 3dc44a7a1e27143edb21fad46f49fd177861a6ff..2d0a49f831f116645fadf73c29ecf832a4a6a6dc 100644
--- a/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/MatrixProperty.h
@@ -33,7 +33,7 @@ File change history is stored at: <https://github.com/mantidproject/mantid>.
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 template <class TYPE = double>
-class DLLExport MatrixProperty : public PropertyWithValue<Matrix<TYPE>> {
+class MatrixProperty : public PropertyWithValue<Matrix<TYPE>> {
   /// Typedef the held type
   typedef Kernel::Matrix<TYPE> HeldType;
 
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyHelper.h b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..397b88b1de7fa3ff9b12e7c8bfaa3079641ef058
--- /dev/null
+++ b/Framework/Kernel/inc/MantidKernel/PropertyHelper.h
@@ -0,0 +1,252 @@
+#ifndef MANTID_KERNEL_PROPERTYHELPER_H_
+#define MANTID_KERNEL_PROPERTYHELPER_H_
+
+#ifndef Q_MOC_RUN
+#include <boost/lexical_cast.hpp>
+#include <boost/make_shared.hpp>
+#endif
+
+#include "MantidKernel/OptionalBool.h"
+#include "MantidKernel/StringTokenizer.h"
+
+namespace Mantid {
+namespace Kernel {
+
+// --------------------- convert values to strings
+namespace {
+/// Convert values to strings.
+template <typename T> std::string toString(const T &value) {
+  return boost::lexical_cast<std::string>(value);
+}
+
+/// Throw an exception if a shared pointer is converted to a string.
+template <typename T> std::string toString(const boost::shared_ptr<T> &value) {
+  UNUSED_ARG(value);
+  throw boost::bad_lexical_cast();
+}
+
+/// Specialisation for a property of type std::vector.
+template <typename T>
+std::string toString(const std::vector<T> &value,
+                     const std::string &delimiter = ",") {
+  std::stringstream result;
+  std::size_t vsize = value.size();
+  for (std::size_t i = 0; i < vsize; ++i) {
+    result << value[i];
+    if (i + 1 != vsize)
+      result << delimiter;
+  }
+  return result.str();
+}
+
+/// Specialisation for a property of type std::vector<std::vector>.
+template <typename T>
+std::string toString(const std::vector<std::vector<T>> &value,
+                     const std::string &outerDelimiter = ",",
+                     const std::string &innerDelimiter = "+") {
+  std::stringstream result;
+  std::size_t vsize = value.size();
+  for (std::size_t i = 0; i < vsize; ++i) {
+    std::size_t innervsize = value[i].size();
+    for (std::size_t j = 0; j < innervsize; ++j) {
+      result << value[i][j];
+      if (j + 1 != innervsize)
+        result << innerDelimiter;
+    }
+
+    if (i + 1 != vsize)
+      result << outerDelimiter;
+  }
+  return result.str();
+}
+
+/// Specialisation for any type, should be appropriate for properties with a
+/// single value.
+template <typename T> int findSize(const T &) { return 1; }
+
+/// Specialisation for properties that are of type vector.
+template <typename T> int findSize(const std::vector<T> &value) {
+  return static_cast<int>(value.size());
+}
+
+// ------------- Convert strings to values
+template <typename T>
+inline void appendValue(const std::string &strvalue, std::vector<T> &value) {
+  // try to split the string
+  std::size_t pos = strvalue.find(':');
+  if (pos == std::string::npos) {
+    pos = strvalue.find('-', 1);
+  }
+
+  // just convert the whole thing into a value
+  if (pos == std::string::npos) {
+    value.push_back(boost::lexical_cast<T>(strvalue));
+    return;
+  }
+
+  // convert the input string into boundaries and run through a list
+  T start = boost::lexical_cast<T>(strvalue.substr(0, pos));
+  T stop = boost::lexical_cast<T>(strvalue.substr(pos + 1));
+  for (T i = start; i <= stop; i++)
+    value.push_back(i);
+}
+
+template <typename T> void toValue(const std::string &strvalue, T &value) {
+  value = boost::lexical_cast<T>(strvalue);
+}
+
+template <typename T>
+void toValue(const std::string &, boost::shared_ptr<T> &) {
+  throw boost::bad_lexical_cast();
+}
+
+namespace detail {
+// vector<int> specializations
+template <typename T>
+void toValue(const std::string &strvalue, std::vector<T> &value,
+             std::true_type) {
+  typedef Mantid::Kernel::StringTokenizer tokenizer;
+  tokenizer values(strvalue, ",",
+                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+  value.clear();
+  value.reserve(values.count());
+  for (const auto &token : values) {
+    appendValue(token, value);
+  }
+}
+
+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;
+  tokenizer values(strvalue, ",",
+                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+
+  value.clear();
+  value.reserve(values.count());
+  std::transform(
+      values.cbegin(), values.cend(), std::back_inserter(value),
+      [](const std::string &str) { return boost::lexical_cast<T>(str); });
+}
+
+// bool and char don't make sense as types to generate a range of values.
+// This is similar to std::is_integral<T>, but bool and char are std::false_type
+template <class T> struct is_range_type : public std::false_type {};
+template <class T> struct is_range_type<const T> : public is_range_type<T> {};
+template <class T>
+struct is_range_type<volatile const T> : public is_range_type<T> {};
+template <class T>
+struct is_range_type<volatile T> : public is_range_type<T> {};
+
+template <> struct is_range_type<unsigned short> : public std::true_type {};
+template <> struct is_range_type<unsigned int> : public std::true_type {};
+template <> struct is_range_type<unsigned long> : public std::true_type {};
+template <> struct is_range_type<unsigned long long> : public std::true_type {};
+
+template <> struct is_range_type<short> : public std::true_type {};
+template <> struct is_range_type<int> : public std::true_type {};
+template <> struct is_range_type<long> : public std::true_type {};
+template <> struct is_range_type<long long> : public std::true_type {};
+}
+template <typename T>
+void toValue(const std::string &strvalue, std::vector<T> &value) {
+  detail::toValue(strvalue, value, detail::is_range_type<T>());
+}
+
+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;
+  tokenizer tokens(strvalue, outerDelimiter,
+                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+
+  value.clear();
+  value.reserve(tokens.count());
+
+  for (const auto &token : tokens) {
+    tokenizer values(token, innerDelimiter,
+                     tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
+    std::vector<T> vect;
+    vect.reserve(values.count());
+    std::transform(
+        values.begin(), values.end(), std::back_inserter(vect),
+        [](const std::string &str) { return boost::lexical_cast<T>(str); });
+    value.push_back(std::move(vect));
+  }
+}
+
+/*Used specifically to retrieve a vector of type T populated with values
+ * given to it from strvalue parameter, Using toValue method.
+ (See constructor used specifically for vector assignments)
+ */
+template <typename T> T extractToValueVector(const std::string &strvalue) {
+  T valueVec;
+  toValue(strvalue, valueVec);
+  return valueVec;
+}
+
+//------------------------------------------------------------------------------------------------
+// Templated += operator functions for specific types
+template <typename T> inline void addingOperator(T &lhs, const T &rhs) {
+  // The cast here (and the expansion of the compound operator which that
+  // necessitates) is because if this function is created for a template
+  // type narrower than an int, the compiler will expande the operands to
+  // ints which leads to a compiler warning when it's assigned back to the
+  // narrower type.
+  lhs = static_cast<T>(lhs + rhs);
+}
+
+template <typename T>
+inline void addingOperator(std::vector<T> &lhs, const std::vector<T> &rhs) {
+  // This concatenates the two
+  if (&lhs != &rhs) {
+    lhs.insert(lhs.end(), rhs.begin(), rhs.end());
+  } else {
+    std::vector<T> rhs_copy(rhs);
+    lhs.insert(lhs.end(), rhs_copy.begin(), rhs_copy.end());
+  }
+}
+
+template <> inline void addingOperator(bool &, const bool &) {
+  throw Exception::NotImplementedError(
+      "PropertyWithValue.h: += operator not implemented for type bool");
+}
+
+template <> inline void addingOperator(OptionalBool &, const OptionalBool &) {
+  throw Exception::NotImplementedError(
+      "PropertyWithValue.h: += operator not implemented for type OptionalBool");
+}
+
+template <typename T>
+inline void addingOperator(boost::shared_ptr<T> &,
+                           const boost::shared_ptr<T> &) {
+  throw Exception::NotImplementedError(
+      "PropertyWithValue.h: += operator not implemented for boost::shared_ptr");
+}
+
+template <typename T>
+inline std::vector<std::string>
+determineAllowedValues(const T &, const IValidator &validator) {
+  return validator.allowedValues();
+}
+
+template <>
+inline std::vector<std::string> determineAllowedValues(const OptionalBool &,
+                                                       const IValidator &) {
+  auto enumMap = OptionalBool::enumToStrMap();
+  std::vector<std::string> values;
+  values.reserve(enumMap.size());
+  std::transform(enumMap.cbegin(), enumMap.cend(), std::back_inserter(values),
+                 [](const std::pair<OptionalBool::Value, std::string> &str) {
+                   return str.second;
+                 });
+  return values;
+}
+}
+
+} // namespace Kernel
+} // namespace Mantid
+
+#endif /* MANTID_KERNEL_PROPERTYHELPER_H_ */
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
index c04d643af4d5a456940e4c8a47f5c26964f80517..fab07ec92ba664e38a31bc222f3840224538ebe4 100644
--- a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h
@@ -5,21 +5,13 @@
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/NullValidator.h"
-#include "MantidKernel/OptionalBool.h"
 
-#ifndef Q_MOC_RUN
-#include <boost/lexical_cast.hpp>
-#include <boost/make_shared.hpp>
-#include <boost/algorithm/string/trim.hpp>
-#endif
-
-#include <nexus/NeXusFile.hpp>
-
-#include "MantidKernel/IPropertySettings.h"
-#include <MantidKernel/StringTokenizer.h>
-#include <type_traits>
 #include <vector>
 
+namespace NeXus {
+class File;
+}
+
 namespace Mantid {
 
 namespace Kernel {
@@ -58,507 +50,38 @@ namespace Kernel {
     File change history is stored at: <https://github.com/mantidproject/mantid>.
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-
-// --------------------- convert values to strings
-namespace {
-/// Convert values to strings.
-template <typename T> std::string toString(const T &value) {
-  return boost::lexical_cast<std::string>(value);
-}
-
-/// Throw an exception if a shared pointer is converted to a string.
-template <typename T> std::string toString(const boost::shared_ptr<T> &value) {
-  UNUSED_ARG(value);
-  throw boost::bad_lexical_cast();
-}
-
-/// Specialisation for a property of type std::vector.
-template <typename T>
-std::string toString(const std::vector<T> &value,
-                     const std::string &delimiter = ",") {
-  std::stringstream result;
-  std::size_t vsize = value.size();
-  for (std::size_t i = 0; i < vsize; ++i) {
-    result << value[i];
-    if (i + 1 != vsize)
-      result << delimiter;
-  }
-  return result.str();
-}
-
-/// Specialisation for a property of type std::vector<std::vector>.
-template <typename T>
-std::string toString(const std::vector<std::vector<T>> &value,
-                     const std::string &outerDelimiter = ",",
-                     const std::string &innerDelimiter = "+") {
-  std::stringstream result;
-  std::size_t vsize = value.size();
-  for (std::size_t i = 0; i < vsize; ++i) {
-    std::size_t innervsize = value[i].size();
-    for (std::size_t j = 0; j < innervsize; ++j) {
-      result << value[i][j];
-      if (j + 1 != innervsize)
-        result << innerDelimiter;
-    }
-
-    if (i + 1 != vsize)
-      result << outerDelimiter;
-  }
-  return result.str();
-}
-
-/// Specialisation for any type, should be appropriate for properties with a
-/// single value.
-template <typename T> int findSize(const T &) { return 1; }
-
-/// Specialisation for properties that are of type vector.
-template <typename T> int findSize(const std::vector<T> &value) {
-  return static_cast<int>(value.size());
-}
-
-// ------------- Convert strings to values
-template <typename T>
-inline void appendValue(const std::string &strvalue, std::vector<T> &value) {
-  // try to split the string
-  std::size_t pos = strvalue.find(':');
-  if (pos == std::string::npos) {
-    pos = strvalue.find('-', 1);
-  }
-
-  // just convert the whole thing into a value
-  if (pos == std::string::npos) {
-    value.push_back(boost::lexical_cast<T>(strvalue));
-    return;
-  }
-
-  // convert the input string into boundaries and run through a list
-  T start = boost::lexical_cast<T>(strvalue.substr(0, pos));
-  T stop = boost::lexical_cast<T>(strvalue.substr(pos + 1));
-  for (T i = start; i <= stop; i++)
-    value.push_back(i);
-}
-
-template <typename T> void toValue(const std::string &strvalue, T &value) {
-  value = boost::lexical_cast<T>(strvalue);
-}
-
-template <typename T>
-void toValue(const std::string &, boost::shared_ptr<T> &) {
-  throw boost::bad_lexical_cast();
-}
-
-namespace detail {
-// vector<int> specializations
-template <typename T>
-void toValue(const std::string &strvalue, std::vector<T> &value,
-             std::true_type) {
-  typedef Mantid::Kernel::StringTokenizer tokenizer;
-  tokenizer values(strvalue, ",",
-                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
-  value.clear();
-  value.reserve(values.count());
-  for (const auto &token : values) {
-    appendValue(token, value);
-  }
-}
-
-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;
-  tokenizer values(strvalue, ",",
-                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
-
-  value.clear();
-  value.reserve(values.count());
-  std::transform(
-      values.cbegin(), values.cend(), std::back_inserter(value),
-      [](const std::string &str) { return boost::lexical_cast<T>(str); });
-}
-
-// bool and char don't make sense as types to generate a range of values.
-// This is similar to std::is_integral<T>, but bool and char are std::false_type
-template <class T> struct is_range_type : public std::false_type {};
-template <class T> struct is_range_type<const T> : public is_range_type<T> {};
-template <class T>
-struct is_range_type<volatile const T> : public is_range_type<T> {};
-template <class T>
-struct is_range_type<volatile T> : public is_range_type<T> {};
-
-template <> struct is_range_type<unsigned short> : public std::true_type {};
-template <> struct is_range_type<unsigned int> : public std::true_type {};
-template <> struct is_range_type<unsigned long> : public std::true_type {};
-template <> struct is_range_type<unsigned long long> : public std::true_type {};
-
-template <> struct is_range_type<short> : public std::true_type {};
-template <> struct is_range_type<int> : public std::true_type {};
-template <> struct is_range_type<long> : public std::true_type {};
-template <> struct is_range_type<long long> : public std::true_type {};
-}
-template <typename T>
-void toValue(const std::string &strvalue, std::vector<T> &value) {
-  detail::toValue(strvalue, value, detail::is_range_type<T>());
-}
-
-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;
-  tokenizer tokens(strvalue, outerDelimiter,
-                   tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
-
-  value.clear();
-  value.reserve(tokens.count());
-
-  for (const auto &token : tokens) {
-    tokenizer values(token, innerDelimiter,
-                     tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM);
-    std::vector<T> vect;
-    vect.reserve(values.count());
-    std::transform(
-        values.begin(), values.end(), std::back_inserter(vect),
-        [](const std::string &str) { return boost::lexical_cast<T>(str); });
-    value.push_back(std::move(vect));
-  }
-}
-
-/*Used specifically to retrieve a vector of type T populated with values
- * given to it from strvalue parameter, Using toValue method.
- (See constructor used specifically for vector assignments)
- */
-template <typename T> T extractToValueVector(const std::string &strvalue) {
-  T valueVec;
-  toValue(strvalue, valueVec);
-  return valueVec;
-}
-
-//------------------------------------------------------------------------------------------------
-// Templated += operator functions for specific types
-template <typename T> inline void addingOperator(T &lhs, const T &rhs) {
-  // The cast here (and the expansion of the compound operator which that
-  // necessitates) is because if this function is created for a template
-  // type narrower than an int, the compiler will expande the operands to
-  // ints which leads to a compiler warning when it's assigned back to the
-  // narrower type.
-  lhs = static_cast<T>(lhs + rhs);
-}
-
-template <typename T>
-inline void addingOperator(std::vector<T> &lhs, const std::vector<T> &rhs) {
-  // This concatenates the two
-  if (&lhs != &rhs) {
-    lhs.insert(lhs.end(), rhs.begin(), rhs.end());
-  } else {
-    std::vector<T> rhs_copy(rhs);
-    lhs.insert(lhs.end(), rhs_copy.begin(), rhs_copy.end());
-  }
-}
-
-template <> inline void addingOperator(bool &, const bool &) {
-  throw Exception::NotImplementedError(
-      "PropertyWithValue.h: += operator not implemented for type bool");
-}
-
-template <> inline void addingOperator(OptionalBool &, const OptionalBool &) {
-  throw Exception::NotImplementedError(
-      "PropertyWithValue.h: += operator not implemented for type OptionalBool");
-}
-
-template <typename T>
-inline void addingOperator(boost::shared_ptr<T> &,
-                           const boost::shared_ptr<T> &) {
-  throw Exception::NotImplementedError(
-      "PropertyWithValue.h: += operator not implemented for boost::shared_ptr");
-}
-
-template <typename T>
-inline std::vector<std::string>
-determineAllowedValues(const T &, const IValidator &validator) {
-  return validator.allowedValues();
-}
-
-template <>
-inline std::vector<std::string> determineAllowedValues(const OptionalBool &,
-                                                       const IValidator &) {
-  auto enumMap = OptionalBool::enumToStrMap();
-  std::vector<std::string> values;
-  values.reserve(enumMap.size());
-  std::transform(enumMap.cbegin(), enumMap.cend(), std::back_inserter(values),
-                 [](const std::pair<OptionalBool::Value, std::string> &str) {
-                   return str.second;
-                 });
-  return values;
-}
-}
-//------------------------------------------------------------------------------------------------
-// Now the PropertyWithValue class itself
-//------------------------------------------------------------------------------------------------
-
 template <typename TYPE> class DLLExport PropertyWithValue : public Property {
 public:
-  /** Constructor
-   *  @param name :: The name to assign to the property
-   *  @param defaultValue :: Is stored initial default value of the property
-   *  @param validator :: The validator to use for this property
-   *  @param direction :: Whether this is a Direction::Input, Direction::Output
-   * or Direction::InOut (Input & Output) property
-   */
   PropertyWithValue(
       const std::string &name, const TYPE &defaultValue,
       IValidator_sptr validator = IValidator_sptr(new NullValidator),
-      const unsigned int direction = Direction::Input)
-      : Property(name, typeid(TYPE), direction), m_value(defaultValue),
-        m_initialValue(defaultValue), m_validator(validator) {}
-
-  /** Constructor
-   *  @param name :: The name to assign to the property
-   *  @param defaultValue :: Is stored initial default value of the property
-   *  @param direction :: Whether this is a Direction::Input, Direction::Output
-   * or Direction::InOut (Input & Output) property
-   */
+      const unsigned int direction = Direction::Input);
   PropertyWithValue(const std::string &name, const TYPE &defaultValue,
-                    const unsigned int direction)
-      : Property(name, typeid(TYPE), direction), m_value(defaultValue),
-        m_initialValue(defaultValue),
-        m_validator(boost::make_shared<NullValidator>()) {}
-
-  /*
-    Constructor to handle vector value assignments to m_initialValue
-    so they can be remembered when the algorithm dialog is reloaded.
-  */
-  /**Constructor
-    *  @param name :: The name to assign to the property.
-    *  @param defaultValue :: A vector of numerical type, empty to comply with
-   * other definitions.
-    *  @param defaultValueStr :: The numerical values you wish to assign to the
-   * property
-    *  @param validator :: The validator to use for this property
-    *  @param direction :: Whether this is a Direction::Input, Direction::Output
-    * or Direction::InOut (Input & Output) property
-    */
+                    const unsigned int direction);
   PropertyWithValue(const std::string &name, const TYPE &defaultValue,
                     const std::string defaultValueStr,
-                    IValidator_sptr validator, const unsigned int direction)
-      : Property(name, typeid(TYPE), direction),
-        m_value(extractToValueVector<TYPE>(defaultValueStr)),
-        m_initialValue(extractToValueVector<TYPE>(defaultValueStr)),
-        m_validator(validator) {
-    UNUSED_ARG(defaultValue);
-  }
-
-  /**Copy constructor
-  *  Note the default value of the copied object is the initial value of
-  * original
-  */
-  PropertyWithValue(const PropertyWithValue &right)
-      : Property(right), m_value(right.m_value),
-        m_initialValue(right.m_initialValue), // the default is the initial
-                                              // value of the original object
-        m_validator(right.m_validator->clone()) {}
-  /// 'Virtual copy constructor'
-  PropertyWithValue<TYPE> *clone() const override {
-    return new PropertyWithValue<TYPE>(*this);
-  }
+                    IValidator_sptr validator, const unsigned int direction);
+  PropertyWithValue(const PropertyWithValue &right);
+  PropertyWithValue<TYPE> *clone() const override;
 
   void saveProperty(::NeXus::File *file) override;
-
-  /** Get the value of the property as a string
-   *  @return The property's value
-   */
-  std::string value() const override { return toString(m_value); }
-
-  /**
-   * Deep comparison.
-   * @param rhs The other property to compare to.
-   * @return true if the are equal.
-   */
-  virtual bool operator==(const PropertyWithValue<TYPE> &rhs) const {
-    if (this->name() != rhs.name())
-      return false;
-    return (m_value == rhs.m_value);
-  }
-
-  /**
-   * Deep comparison (not equal).
-   * @param rhs The other property to compare to.
-   * @return true if the are not equal.
-   */
-  virtual bool operator!=(const PropertyWithValue<TYPE> &rhs) const {
-    return !(*this == rhs);
-  }
-
-  /** Get the size of the property.
-  */
-  int size() const override { return findSize(m_value); }
-
-  /** Get the value the property was initialised with -its default value
-   *  @return The default value
-   */
-  std::string getDefault() const override { return toString(m_initialValue); }
-
-  /** Set the value of the property from a string representation.
-   *  Note that "1" & "0" must be used for bool properties rather than
-   * true/false.
-   *  @param value :: The value to assign to the property
-   *  @return Returns "" if the assignment was successful or a user level
-   * description of the problem
-   */
-  std::string setValue(const std::string &value) override {
-    try {
-      TYPE result = m_value;
-      std::string valueCopy = value;
-      if (autoTrim()) {
-        boost::trim(valueCopy);
-      }
-      toValue(valueCopy, result);
-      // Uses the assignment operator defined below which runs isValid() and
-      // throws based on the result
-      *this = result;
-      return "";
-    } catch (boost::bad_lexical_cast &) {
-      std::string error = "Could not set property " + name() +
-                          ". Can not convert \"" + value + "\" to " + type();
-      g_logger.debug() << error;
-      return error;
-    } catch (std::invalid_argument &except) {
-      g_logger.debug() << "Could not set property " << name() << ": "
-                       << except.what();
-      return except.what();
-    }
-  }
-
-  /**
-   * Set a property value via a DataItem
-   * @param data :: A shared pointer to a data item
-   * @return "" if the assignment was successful or a user level description of
-   * the problem
-   */
-  std::string setDataItem(const boost::shared_ptr<DataItem> data) override {
-    // Pass of the helper function that is able to distinguish whether
-    // the TYPE of the PropertyWithValue can be converted to a
-    // shared_ptr<DataItem>
-    return setTypedValue(
-        data, boost::is_convertible<TYPE, boost::shared_ptr<DataItem>>());
-  }
-
-  /// Copy assignment operator assigns only the value and the validator not the
-  /// name, default (initial) value, etc.
-  PropertyWithValue &operator=(const PropertyWithValue &right) {
-    if (&right == this)
-      return *this;
-    m_value = right.m_value;
-    m_validator = right.m_validator->clone();
-    return *this;
-  }
-
-  //--------------------------------------------------------------------------------------
-  /** Add the value of another property
-  * @param right the property to add
-  * @return the sum
-  */
-  PropertyWithValue &operator+=(Property const *right) override {
-    PropertyWithValue const *rhs =
-        dynamic_cast<PropertyWithValue const *>(right);
-
-    if (rhs) {
-      // This function basically does:
-      //  m_value += rhs->m_value; for values
-      //  or concatenates vectors for vectors
-      addingOperator(m_value, rhs->m_value);
-    } else
-      g_logger.warning() << "PropertyWithValue " << this->name()
-                         << " could not be added to another property of the "
-                            "same name but incompatible type.\n";
-
-    return *this;
-  }
-
-  //--------------------------------------------------------------------------------------
-  /** Assignment operator.
-   *  Allows assignment of a new value to the property by writing,
-   *  e.g., myProperty = 3;
-   *  @param value :: The new value to assign to the property
-   *  @return the reference to itself
-   */
-  virtual TYPE &operator=(const TYPE &value) {
-    TYPE oldValue = m_value;
-    if (std::is_same<TYPE, std::string>::value) {
-      std::string valueCopy = toString(value);
-      if (autoTrim()) {
-        boost::trim(valueCopy);
-      }
-      toValue(valueCopy, m_value);
-    } else {
-      m_value = value;
-    }
-    std::string problem = this->isValid();
-    if (problem == "") {
-      return m_value;
-    } else if (problem == "_alias") {
-      m_value = getValueForAlias(value);
-      return m_value;
-    } else {
-      m_value = oldValue;
-      throw std::invalid_argument(problem);
-    }
-  }
-
-  /** Allows you to get the value of the property via an expression like
-   * myProperty()
-   *  @returns the value of the property
-   */
-  virtual const TYPE &operator()() const { return m_value; }
-
-  /** Allows you to get the value of the property simply by typing its name.
-   *  Means you can use an expression like: int i = myProperty;
-   * @return the value
-   */
-  virtual operator const TYPE &() const { return m_value; }
-
-  /** Check the value chosen for the property is OK, unless overidden it just
-   * calls the validator's isValid()
-   *  N.B. Problems found in validator are written to the log
-   *  if you override this function to do checking outside a validator may want
-   * to do more logging
-   *  @returns "" if the value is valid or a discription of the problem
-   */
-  std::string isValid() const override { return m_validator->isValid(m_value); }
-
-  /** Indicates if the property's value is the same as it was when it was set
-  *  N.B. Uses an unsafe comparison in the case of doubles, consider overriding
-  * if the value is a pointer or floating point type
-  *  @return true if the value is the same as the initial value or false
-  * otherwise
-  */
-  bool isDefault() const override { return m_initialValue == m_value; }
-
-  /** Returns the set of valid values for this property, if such a set exists.
-   *  If not, it returns an empty vector.
-   *  @return Returns the set of valid values for this property, or it returns
-   * an empty vector.
-   */
-  std::vector<std::string> allowedValues() const override {
-    return determineAllowedValues(m_value, *m_validator);
-  }
-
-  /** Returns the set of valid values for this property, if such a set exists.
-  *  If not, it returns an empty vector.
-  *  @return Returns the set of valid values for this property, or it returns
-  * an empty vector.
-  */
-  bool isMultipleSelectionAllowed() override {
-    return m_validator->isMultipleSelectionAllowed();
-  }
-
-  /**
-   * Replace the current validator with the given one
-   * @param newValidator :: A replacement validator
-   */
-  virtual void replaceValidator(IValidator_sptr newValidator) {
-    m_validator = newValidator;
-  }
+  std::string value() const override;
+  virtual bool operator==(const PropertyWithValue<TYPE> &rhs) const;
+  virtual bool operator!=(const PropertyWithValue<TYPE> &rhs) const;
+  int size() const override;
+  std::string getDefault() const override;
+  std::string setValue(const std::string &value) override;
+  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 const TYPE &operator()() const;
+  virtual operator const TYPE &() const;
+  std::string isValid() const override;
+  bool isDefault() const override;
+  std::vector<std::string> allowedValues() const override;
+  bool isMultipleSelectionAllowed() override;
+  virtual void replaceValidator(IValidator_sptr newValidator);
 
 protected:
   /// The value of the property
@@ -568,74 +91,15 @@ protected:
   TYPE m_initialValue;
 
 private:
-  /**
-   * Set the value of the property via a reference to another property.
-   * If the value is unacceptable the value is not changed but a string is
-   * returned.
-   * The value is only accepted if the other property has the same type as this
-   * @param right :: A reference to a property.
-   */
-  std::string setValueFromProperty(const Property &right) override {
-    auto prop = dynamic_cast<const PropertyWithValue<TYPE> *>(&right);
-    if (!prop) {
-      return "Could not set value: properties have different type.";
-    }
-    m_value = prop->m_value;
-    return "";
-  }
+  std::string setValueFromProperty(const Property &right) override;
 
-  /**
-   * Helper function for setValue(DataItem_sptr). Uses boost type traits to
-   * ensure
-   * it is only used if U is a type that is convertible to
-   * boost::shared_ptr<DataItem>
-   * @param value :: A object of type convertible to boost::shared_ptr<DataItem>
-   */
   template <typename U>
-  std::string setTypedValue(const U &value, const boost::true_type &) {
-    TYPE data = boost::dynamic_pointer_cast<typename TYPE::element_type>(value);
-    std::string msg;
-    if (data) {
-      try {
-        (*this) = data;
-      } catch (std::invalid_argument &exc) {
-        msg = exc.what();
-      }
-    } else {
-      msg = "Invalid DataItem. The object type (" +
-            std::string(typeid(value).name()) +
-            ") does not match the declared type of the property (" +
-            std::string(this->type()) + ").";
-    }
-    return msg;
-  }
+  std::string setTypedValue(const U &value, const boost::true_type &);
 
-  /**
-   * Helper function for setValue(DataItem_sptr). Uses boost type traits to
-   * ensure
-   * it is only used if U is NOT a type that is convertible to
-   * boost::shared_ptr<DataItem>
-   * @param value :: A object of type convertible to boost::shared_ptr<DataItem>
-   */
   template <typename U>
-  std::string setTypedValue(const U &value, const boost::false_type &) {
-    UNUSED_ARG(value);
-    return "Attempt to assign object of type DataItem to property (" + name() +
-           ") of incorrect type";
-  }
+  std::string setTypedValue(const U &value, const boost::false_type &);
 
-  /** Return value for a given alias.
-   * @param alias :: An alias for a value. If a value cannot be found throw an
-   * invalid_argument exception.
-   * @return :: A value.
-   */
-  const TYPE getValueForAlias(const TYPE &alias) const {
-    std::string strAlias = toString(alias);
-    std::string strValue = m_validator->getValueForAlias(strAlias);
-    TYPE value;
-    toValue(strValue, value);
-    return value;
-  }
+  const TYPE getValueForAlias(const TYPE &alias) const;
 
   /// Visitor validator class
   IValidator_sptr m_validator;
@@ -644,31 +108,36 @@ private:
   static Logger g_logger;
 
   /// Private default constructor
-  PropertyWithValue();
+  PropertyWithValue() = default;
 };
 
-template <> void PropertyWithValue<float>::saveProperty(::NeXus::File *file);
-template <> void PropertyWithValue<double>::saveProperty(::NeXus::File *file);
-template <> void PropertyWithValue<int32_t>::saveProperty(::NeXus::File *file);
-template <> void PropertyWithValue<uint32_t>::saveProperty(::NeXus::File *file);
-template <> void PropertyWithValue<int64_t>::saveProperty(::NeXus::File *file);
-template <> void PropertyWithValue<uint64_t>::saveProperty(::NeXus::File *file);
 template <>
-void PropertyWithValue<std::string>::saveProperty(::NeXus::File *file);
+MANTID_KERNEL_DLL void
+PropertyWithValue<float>::saveProperty(::NeXus::File *file);
 template <>
-void PropertyWithValue<std::vector<double>>::saveProperty(::NeXus::File *file);
+MANTID_KERNEL_DLL void
+PropertyWithValue<double>::saveProperty(::NeXus::File *file);
 template <>
-void PropertyWithValue<std::vector<int32_t>>::saveProperty(::NeXus::File *file);
-
-template <typename TYPE>
-void PropertyWithValue<TYPE>::saveProperty(::NeXus::File * /*file*/) {
-  // AppleClang 7.3 and later gives a -Winfinite-recursion warning if I call the
-  // base class method. The function is small enough that reimplementing it
-  // isn't a big deal.
-  throw std::invalid_argument(
-      "PropertyWithValue::saveProperty - Cannot save '" + this->name() +
-      "', property type not implemented.");
-}
+MANTID_KERNEL_DLL void
+PropertyWithValue<int32_t>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<uint32_t>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<int64_t>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<uint64_t>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<std::string>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<std::vector<double>>::saveProperty(::NeXus::File *file);
+template <>
+MANTID_KERNEL_DLL void
+PropertyWithValue<std::vector<int32_t>>::saveProperty(::NeXus::File *file);
 
 template <typename TYPE>
 Logger PropertyWithValue<TYPE>::g_logger("PropertyWithValue");
diff --git a/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
new file mode 100644
index 0000000000000000000000000000000000000000..fb0bdb27655df2f60b419c54a4438c37c5046be5
--- /dev/null
+++ b/Framework/Kernel/inc/MantidKernel/PropertyWithValue.tcc
@@ -0,0 +1,414 @@
+#include "MantidKernel/PropertyWithValue.h"
+#include "MantidKernel/PropertyHelper.h"
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/Logger.h"
+#include "MantidKernel/NullValidator.h"
+#include "MantidKernel/OptionalBool.h"
+
+#ifndef Q_MOC_RUN
+#include <boost/make_shared.hpp>
+#include <boost/algorithm/string/trim.hpp>
+#endif
+
+#include <nexus/NeXusFile.hpp>
+
+#include "MantidKernel/IPropertySettings.h"
+#include <MantidKernel/StringTokenizer.h>
+#include <type_traits>
+#include <vector>
+
+namespace Mantid {
+namespace Kernel {
+
+//------------------------------------------------------------------------------------------------
+// Now the PropertyWithValue class itself
+//------------------------------------------------------------------------------------------------
+
+/** Constructor
+ *  @param name :: The name to assign to the property
+ *  @param defaultValue :: Is stored initial default value of the property
+ *  @param validator :: The validator to use for this property
+ *  @param direction :: Whether this is a Direction::Input, Direction::Output
+ * or Direction::InOut (Input & Output) property
+ */
+template <typename TYPE>
+PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
+                                           const TYPE &defaultValue,
+                                           IValidator_sptr validator,
+                                           const unsigned int direction)
+    : Property(name, typeid(TYPE), direction), m_value(defaultValue),
+      m_initialValue(defaultValue), m_validator(validator) {}
+
+/** Constructor
+ *  @param name :: The name to assign to the property
+ *  @param defaultValue :: Is stored initial default value of the property
+ *  @param direction :: Whether this is a Direction::Input, Direction::Output
+ * or Direction::InOut (Input & Output) property
+ */
+template <typename TYPE>
+PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
+                                           const TYPE &defaultValue,
+                                           const unsigned int direction)
+    : Property(name, typeid(TYPE), direction), m_value(defaultValue),
+      m_initialValue(defaultValue),
+      m_validator(boost::make_shared<NullValidator>()) {}
+
+/*
+  Constructor to handle vector value assignments to m_initialValue
+  so they can be remembered when the algorithm dialog is reloaded.
+*/
+/**Constructor
+  *  @param name :: The name to assign to the property.
+  *  @param defaultValue :: A vector of numerical type, empty to comply with
+ * other definitions.
+  *  @param defaultValueStr :: The numerical values you wish to assign to the
+ * property
+  *  @param validator :: The validator to use for this property
+  *  @param direction :: Whether this is a Direction::Input, Direction::Output
+  * or Direction::InOut (Input & Output) property
+  */
+template <typename TYPE>
+PropertyWithValue<TYPE>::PropertyWithValue(const std::string &name,
+                                           const TYPE &defaultValue,
+                                           const std::string defaultValueStr,
+                                           IValidator_sptr validator,
+                                           const unsigned int direction)
+    : Property(name, typeid(TYPE), direction),
+      m_value(extractToValueVector<TYPE>(defaultValueStr)),
+      m_initialValue(extractToValueVector<TYPE>(defaultValueStr)),
+      m_validator(validator) {
+  UNUSED_ARG(defaultValue);
+}
+
+/**Copy constructor
+*  Note the default value of the copied object is the initial value of
+* original
+*/
+template <typename TYPE>
+PropertyWithValue<TYPE>::PropertyWithValue(const PropertyWithValue &right)
+    : Property(right), m_value(right.m_value),
+      m_initialValue(right.m_initialValue), // the default is the initial
+                                            // value of the original object
+      m_validator(right.m_validator->clone()) {}
+
+/// 'Virtual copy constructor'
+template <typename TYPE>
+PropertyWithValue<TYPE> *PropertyWithValue<TYPE>::clone() const {
+  return new PropertyWithValue<TYPE>(*this);
+}
+
+template <typename TYPE>
+void PropertyWithValue<TYPE>::saveProperty(::NeXus::File * /*file*/) {
+  // AppleClang 7.3 and later gives a -Winfinite-recursion warning if I call the
+  // base class method. The function is small enough that reimplementing it
+  // isn't a big deal.
+  throw std::invalid_argument(
+      "PropertyWithValue::saveProperty - Cannot save '" + this->name() +
+      "', property type not implemented.");
+}
+
+/** Get the value of the property as a string
+ *  @return The property's value
+ */
+template <typename TYPE> std::string PropertyWithValue<TYPE>::value() const {
+  return toString(m_value);
+}
+
+/**
+ * Deep comparison.
+ * @param rhs The other property to compare to.
+ * @return true if the are equal.
+ */
+template <typename TYPE>
+bool PropertyWithValue<TYPE>::
+operator==(const PropertyWithValue<TYPE> &rhs) const {
+  if (this->name() != rhs.name())
+    return false;
+  return (m_value == rhs.m_value);
+}
+
+/**
+ * Deep comparison (not equal).
+ * @param rhs The other property to compare to.
+ * @return true if the are not equal.
+ */
+template <typename TYPE>
+bool PropertyWithValue<TYPE>::
+operator!=(const PropertyWithValue<TYPE> &rhs) const {
+  return !(*this == rhs);
+}
+
+/** Get the size of the property.
+*/
+template <typename TYPE> int PropertyWithValue<TYPE>::size() const {
+  return findSize(m_value);
+}
+
+/** Get the value the property was initialised with -its default value
+ *  @return The default value
+ */
+template <typename TYPE>
+std::string PropertyWithValue<TYPE>::getDefault() const {
+  return toString(m_initialValue);
+}
+
+/** Set the value of the property from a string representation.
+ *  Note that "1" & "0" must be used for bool properties rather than
+ * true/false.
+ *  @param value :: The value to assign to the property
+ *  @return Returns "" if the assignment was successful or a user level
+ * description of the problem
+ */
+template <typename TYPE>
+std::string PropertyWithValue<TYPE>::setValue(const std::string &value) {
+  try {
+    TYPE result = m_value;
+    std::string valueCopy = value;
+    if (autoTrim()) {
+      boost::trim(valueCopy);
+    }
+    toValue(valueCopy, result);
+    // Uses the assignment operator defined below which runs isValid() and
+    // throws based on the result
+    *this = result;
+    return "";
+  } catch (boost::bad_lexical_cast &) {
+    std::string error = "Could not set property " + name() +
+                        ". Can not convert \"" + value + "\" to " + type();
+    g_logger.debug() << error;
+    return error;
+  } catch (std::invalid_argument &except) {
+    g_logger.debug() << "Could not set property " << name() << ": "
+                     << except.what();
+    return except.what();
+  }
+}
+
+/**
+ * Set a property value via a DataItem
+ * @param data :: A shared pointer to a data item
+ * @return "" if the assignment was successful or a user level description of
+ * the problem
+ */
+template <typename TYPE>
+std::string
+PropertyWithValue<TYPE>::setDataItem(const boost::shared_ptr<DataItem> data) {
+  // Pass of the helper function that is able to distinguish whether
+  // the TYPE of the PropertyWithValue can be converted to a
+  // shared_ptr<DataItem>
+  return setTypedValue(
+      data, boost::is_convertible<TYPE, boost::shared_ptr<DataItem>>());
+}
+
+/// Copy assignment operator assigns only the value and the validator not the
+/// name, default (initial) value, etc.
+template <typename TYPE>
+PropertyWithValue<TYPE> &PropertyWithValue<TYPE>::
+operator=(const PropertyWithValue &right) {
+  if (&right == this)
+    return *this;
+  m_value = right.m_value;
+  m_validator = right.m_validator->clone();
+  return *this;
+}
+
+//--------------------------------------------------------------------------------------
+/** Add the value of another property
+* @param right the property to add
+* @return the sum
+*/
+template <typename TYPE>
+PropertyWithValue<TYPE> &PropertyWithValue<TYPE>::
+operator+=(Property const *right) {
+  PropertyWithValue const *rhs = dynamic_cast<PropertyWithValue const *>(right);
+
+  if (rhs) {
+    // This function basically does:
+    //  m_value += rhs->m_value; for values
+    //  or concatenates vectors for vectors
+    addingOperator(m_value, rhs->m_value);
+  } else
+    g_logger.warning() << "PropertyWithValue " << this->name()
+                       << " could not be added to another property of the "
+                          "same name but incompatible type.\n";
+
+  return *this;
+}
+
+//--------------------------------------------------------------------------------------
+/** Assignment operator.
+ *  Allows assignment of a new value to the property by writing,
+ *  e.g., myProperty = 3;
+ *  @param value :: The new value to assign to the property
+ *  @return the reference to itself
+ */
+template <typename TYPE>
+TYPE &PropertyWithValue<TYPE>::operator=(const TYPE &value) {
+  TYPE oldValue = m_value;
+  if (std::is_same<TYPE, std::string>::value) {
+    std::string valueCopy = toString(value);
+    if (autoTrim()) {
+      boost::trim(valueCopy);
+    }
+    toValue(valueCopy, m_value);
+  } else {
+    m_value = value;
+  }
+  std::string problem = this->isValid();
+  if (problem == "") {
+    return m_value;
+  } else if (problem == "_alias") {
+    m_value = getValueForAlias(value);
+    return m_value;
+  } else {
+    m_value = oldValue;
+    throw std::invalid_argument(problem);
+  }
+}
+
+/** Allows you to get the value of the property via an expression like
+ * myProperty()
+ *  @returns the value of the property
+ */
+template <typename TYPE>
+const TYPE &PropertyWithValue<TYPE>::operator()() const {
+  return m_value;
+}
+
+/** Allows you to get the value of the property simply by typing its name.
+ *  Means you can use an expression like: int i = myProperty;
+ * @return the value
+ */
+template <typename TYPE>
+PropertyWithValue<TYPE>::operator const TYPE &() const {
+  return m_value;
+}
+
+/** Check the value chosen for the property is OK, unless overidden it just
+ * calls the validator's isValid()
+ *  N.B. Problems found in validator are written to the log
+ *  if you this function to do checking outside a validator may want
+ * to do more logging
+ *  @returns "" if the value is valid or a discription of the problem
+ */
+template <typename TYPE> std::string PropertyWithValue<TYPE>::isValid() const {
+  return m_validator->isValid(m_value);
+}
+
+/** Indicates if the property's value is the same as it was when it was set
+*  N.B. Uses an unsafe comparison in the case of doubles, consider overriding
+* if the value is a pointer or floating point type
+*  @return true if the value is the same as the initial value or false
+* otherwise
+*/
+template <typename TYPE> bool PropertyWithValue<TYPE>::isDefault() const {
+  return m_initialValue == m_value;
+}
+
+/** Returns the set of valid values for this property, if such a set exists.
+ *  If not, it returns an empty vector.
+ *  @return Returns the set of valid values for this property, or it returns
+ * an empty vector.
+ */
+template <typename TYPE>
+std::vector<std::string> PropertyWithValue<TYPE>::allowedValues() const {
+  return determineAllowedValues(m_value, *m_validator);
+}
+
+/** Returns the set of valid values for this property, if such a set exists.
+*  If not, it returns an empty vector.
+*  @return Returns the set of valid values for this property, or it returns
+* an empty vector.
+*/
+template <typename TYPE>
+bool PropertyWithValue<TYPE>::isMultipleSelectionAllowed() {
+  return m_validator->isMultipleSelectionAllowed();
+}
+
+/**
+ * Replace the current validator with the given one
+ * @param newValidator :: A replacement validator
+ */
+template <typename TYPE>
+void PropertyWithValue<TYPE>::replaceValidator(IValidator_sptr newValidator) {
+  m_validator = newValidator;
+}
+
+/**
+ * Set the value of the property via a reference to another property.
+ * If the value is unacceptable the value is not changed but a string is
+ * returned.
+ * The value is only accepted if the other property has the same type as this
+ * @param right :: A reference to a property.
+ */
+template <typename TYPE>
+std::string
+PropertyWithValue<TYPE>::setValueFromProperty(const Property &right) {
+  auto prop = dynamic_cast<const PropertyWithValue<TYPE> *>(&right);
+  if (!prop) {
+    return "Could not set value: properties have different type.";
+  }
+  m_value = prop->m_value;
+  return "";
+}
+
+/**
+ * Helper function for setValue(DataItem_sptr). Uses boost type traits to
+ * ensure
+ * it is only used if U is a type that is convertible to
+ * boost::shared_ptr<DataItem>
+ * @param value :: A object of type convertible to boost::shared_ptr<DataItem>
+ */
+template <typename TYPE>
+template <typename U>
+std::string PropertyWithValue<TYPE>::setTypedValue(const U &value,
+                                                   const boost::true_type &) {
+  TYPE data = boost::dynamic_pointer_cast<typename TYPE::element_type>(value);
+  std::string msg;
+  if (data) {
+    try {
+      (*this) = data;
+    } catch (std::invalid_argument &exc) {
+      msg = exc.what();
+    }
+  } else {
+    msg = "Invalid DataItem. The object type (" +
+          std::string(typeid(value).name()) +
+          ") does not match the declared type of the property (" +
+          std::string(this->type()) + ").";
+  }
+  return msg;
+}
+
+/**
+ * Helper function for setValue(DataItem_sptr). Uses boost type traits to
+ * ensure
+ * it is only used if U is NOT a type that is convertible to
+ * boost::shared_ptr<DataItem>
+ * @param value :: A object of type convertible to boost::shared_ptr<DataItem>
+ */
+template <typename TYPE>
+template <typename U>
+std::string PropertyWithValue<TYPE>::setTypedValue(const U &value,
+                                                   const boost::false_type &) {
+  UNUSED_ARG(value);
+  return "Attempt to assign object of type DataItem to property (" + name() +
+         ") of incorrect type";
+}
+
+/** Return value for a given alias.
+ * @param alias :: An alias for a value. If a value cannot be found throw an
+ * invalid_argument exception.
+ * @return :: A value.
+ */
+template <typename TYPE>
+const TYPE PropertyWithValue<TYPE>::getValueForAlias(const TYPE &alias) const {
+  std::string strAlias = toString(alias);
+  std::string strValue = m_validator->getValueForAlias(strAlias);
+  TYPE value;
+  toValue(strValue, value);
+  return value;
+}
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Framework/Kernel/inc/MantidKernel/System.h b/Framework/Kernel/inc/MantidKernel/System.h
index 65fbb9545cb6645eb132c260747bb09e13ebe237..9fd4783776846db9976b1a2a6a5b9046e564fd4d 100644
--- a/Framework/Kernel/inc/MantidKernel/System.h
+++ b/Framework/Kernel/inc/MantidKernel/System.h
@@ -94,37 +94,6 @@
  *  For size_t and ptrdiff_t
  */
 #include <cstddef>
-
-/**
- * Information for holding onto stdint.h if it is
- * not available
- */
-#ifdef HAVE_STDINT_H
 #include <cstdint>
-#else
-#ifdef BOOST_CSTDINT_HPP
-#include <cstdint.hpp>
-#else
-#ifdef _WIN32
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-typedef unsigned uint32_t;
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
-#else
-typedef signed char int8_t;
-typedef unsigned char uint8_t;
-typedef short int16_t;
-typedef unsigned short uint16_t;
-typedef int int32_t;
-typedef unsigned int uint32_t;
-typedef long int64_t;
-typedef unsigned long uint64_t;
-#endif
-#endif
-#endif
 
 #endif /*MANTID_KERNEL_SYSTEM_H_*/
diff --git a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
index 9ca7d05fdaa6b517ced578d6ac61c1a0dc0e2520..1aa6a2abba00a274a95752f40328b37057627519 100644
--- a/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
+++ b/Framework/Kernel/inc/MantidKernel/TimeSeriesProperty.h
@@ -178,11 +178,13 @@ public:
   ///  Return the time series as a correct C++ map<DateAndTime, TYPE>. All
   ///  values
   std::map<DateAndTime, TYPE> valueAsCorrectMap() const;
-  ///  Return the time series's values as a vector<TYPE>
+  ///  Return the time series's values (unfiltered) as a vector<TYPE>
   std::vector<TYPE> valuesAsVector() const;
   ///  Return the time series as a correct C++ multimap<DateAndTime, TYPE>. All
   ///  values
   std::multimap<DateAndTime, TYPE> valueAsMultiMap() const;
+  /// Get filtered values as a vector
+  std::vector<TYPE> filteredValuesAsVector() const;
 
   /// Return the time series's times as a vector<DateAndTime>
   std::vector<DateAndTime> timesAsVector() const override;
@@ -296,12 +298,15 @@ public:
     * total size you'll need easily available in advance.  */
   void reserve(size_t size) { m_values.reserve(size); };
 
+  /// If filtering by log, get the time intervals for splitting
+  std::vector<Mantid::Kernel::SplittingInterval> getSplittingIntervals() const;
+
 private:
   //----------------------------------------------------------------------------------------------
   /// Saves the time vector has time + start attribute
   void saveTimeVector(::NeXus::File *file);
-  /// Sort the property into increasing times
-  void sort() const;
+  /// Sort the property into increasing times, if not already sorted
+  void sortIfNecessary() const;
   ///  Find the index of the entry of time t in the mP vector (sorted)
   int findIndex(Kernel::DateAndTime t) const;
   ///  Find the upper_bound of time t in container.
@@ -313,6 +318,8 @@ private:
   size_t findNthIndexFromQuickRef(int n) const;
   /// Set a value from another property
   std::string setValueFromProperty(const Property &right) override;
+  /// Find if time lies in a filtered region
+  bool isTimeFiltered(const Kernel::DateAndTime &time) const;
 
   /// Holds the time series data
   mutable std::vector<TimeValueUnit<TYPE>> m_values;
diff --git a/Framework/Kernel/inc/MantidKernel/UnitLabel.h b/Framework/Kernel/inc/MantidKernel/UnitLabel.h
index 0cd9829df37de1a85768d7f76f3e28775150af05..9348e7d16a616c82abc8ef4a360759b9265c64c0 100644
--- a/Framework/Kernel/inc/MantidKernel/UnitLabel.h
+++ b/Framework/Kernel/inc/MantidKernel/UnitLabel.h
@@ -24,7 +24,6 @@
   File change history is stored at: <https://github.com/mantidproject/mantid>
   Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-#include "MantidKernel/ClassMacros.h"
 #include "MantidKernel/DllConfig.h"
 #include <string>
 
@@ -36,6 +35,8 @@ namespace Kernel {
  */
 class MANTID_KERNEL_DLL UnitLabel {
 public:
+  UnitLabel() = delete;
+
   /// Type that contains a plain-text string
   typedef std::string AsciiString;
   /// Type that can hold a unicode string. This may vary per-platform depending
@@ -80,8 +81,6 @@ public:
   operator std::string() const;
 
 private:
-  DISABLE_DEFAULT_CONSTRUCT(UnitLabel)
-
   /// Value of plain-text label
   std::string m_ascii;
   /// Value of utf-8 encoded string
diff --git a/Framework/Kernel/inc/MantidKernel/V3D.h b/Framework/Kernel/inc/MantidKernel/V3D.h
index cd15ff1070eb146b6a39307957304231158c4027..f7052cf23238a0de0e5e87e5d2aef475324e5ef7 100644
--- a/Framework/Kernel/inc/MantidKernel/V3D.h
+++ b/Framework/Kernel/inc/MantidKernel/V3D.h
@@ -2,8 +2,6 @@
 #define MANTID_KERNEL_V3D_H_
 
 #include <cmath>
-#include <cfloat>
-#include <complex>
 #include <vector>
 #include "MantidKernel/DllConfig.h"
 #include "MantidKernel/Matrix.h"
diff --git a/Framework/Kernel/inc/MantidKernel/VMD.h b/Framework/Kernel/inc/MantidKernel/VMD.h
index 01b448c6fcff4bac2ee7a45d5190e0bb281af8be..e8d60d2ea5d9f0ae5a3baa081e24ef515ce3554d 100644
--- a/Framework/Kernel/inc/MantidKernel/VMD.h
+++ b/Framework/Kernel/inc/MantidKernel/VMD.h
@@ -1,18 +1,13 @@
 #ifndef MANTID_KERNEL_VMD_H_
 #define MANTID_KERNEL_VMD_H_
 
-#include "MantidKernel/StringTokenizer.h"
-#include "MantidKernel/Strings.h"
-#include "MantidKernel/System.h"
-#include "MantidKernel/Tolerance.h"
-#include "MantidKernel/V3D.h"
-#include <algorithm>
-#include <cstddef>
-#include <sstream>
-#include <stdexcept>
+#include "MantidKernel/DllConfig.h"
+#include <string>
+#include <vector>
 
 namespace Mantid {
 namespace Kernel {
+class V3D;
 
 /** Simple vector class for multiple dimensions (i.e. > 3).
 
@@ -42,456 +37,53 @@ namespace Kernel {
 */
 template <typename TYPE = double> class DLLExport VMDBase {
 public:
-  //-------------------------------------------------------------------------------------------
-  /** Default constructor, build with 1 dimension */
-  VMDBase() : nd(1) {
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(0.0);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param nd :: number of dimensions  */
-  VMDBase(size_t nd) : nd(nd) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(0.0);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** 2D Constructor
-   * @param val0 :: value at first dimension
-   * @param val1 :: value at second dimension
-   */
-  VMDBase(double val0, double val1) : nd(2) {
-    data = new TYPE[nd];
-    data[0] = TYPE(val0);
-    data[1] = TYPE(val1);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** 3D Constructor
-   * @param val0 :: value at first dimension
-   * @param val1 :: value at second dimension
-   * @param val2 :: value at third dimension
-   */
-  VMDBase(double val0, double val1, double val2) : nd(3) {
-    data = new TYPE[nd];
-    data[0] = TYPE(val0);
-    data[1] = TYPE(val1);
-    data[2] = TYPE(val2);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** 4D Constructor
-   * @param val0 :: value at first dimension
-   * @param val1 :: value at second dimension
-   * @param val2 :: value at third dimension
-   * @param val3 :: value at fourth dimension
-   */
-  VMDBase(double val0, double val1, double val2, double val3) : nd(4) {
-    data = new TYPE[nd];
-    data[0] = TYPE(val0);
-    data[1] = TYPE(val1);
-    data[2] = TYPE(val2);
-    data[3] = TYPE(val3);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** 5D Constructor
-   * @param val0 :: value at first dimension
-   * @param val1 :: value at second dimension
-   * @param val2 :: value at third dimension
-   * @param val3 :: value at fourth dimension
-   * @param val4 :: value at fifth dimension
-   */
-  VMDBase(double val0, double val1, double val2, double val3, double val4)
-      : nd(5) {
-    data = new TYPE[nd];
-    data[0] = TYPE(val0);
-    data[1] = TYPE(val1);
-    data[2] = TYPE(val2);
-    data[3] = TYPE(val3);
-    data[4] = TYPE(val4);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** 6D Constructor
-   * @param val0 :: value at first dimension
-   * @param val1 :: value at second dimension
-   * @param val2 :: value at third dimension
-   * @param val3 :: value at fourth dimension
-   * @param val4 :: value at fifth dimension
-   * @param val5 :: value at sixth dimension
-   */
+  VMDBase();
+  VMDBase(size_t nd);
+  VMDBase(double val0, double val1);
+  VMDBase(double val0, double val1, double val2);
+  VMDBase(double val0, double val1, double val2, double val3);
+  VMDBase(double val0, double val1, double val2, double val3, double val4);
   VMDBase(double val0, double val1, double val2, double val3, double val4,
-          double val5)
-      : nd(6) {
-    data = new TYPE[nd];
-    data[0] = TYPE(val0);
-    data[1] = TYPE(val1);
-    data[2] = TYPE(val2);
-    data[3] = TYPE(val3);
-    data[4] = TYPE(val4);
-    data[5] = TYPE(val5);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Copy constructor
-   * @param other :: other to copy */
-  VMDBase(const VMDBase &other) : nd(other.nd) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = other.data[d];
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Assignment operator
-   * @param other :: copy into this
-   */
-  VMDBase &operator=(const VMDBase &other) {
-    if ((other.nd) != nd) {
-      nd = other.nd;
-      delete[] data;
-      data = new TYPE[nd];
-    }
-    for (size_t d = 0; d < nd; d++)
-      data[d] = other.data[d];
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param nd :: number of dimensions
-   * @param bareData :: pointer to a nd-sized bare data array */
-  VMDBase(size_t nd, const double *bareData) : nd(nd) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(bareData[d]);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param nd :: number of dimensions
-   * @param bareData :: pointer to a nd-sized bare data array */
-  VMDBase(size_t nd, const float *bareData) : nd(nd) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(bareData[d]);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param vector :: V3D */
-  VMDBase(const V3D &vector) : nd(3) {
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(vector[d]);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param vector :: vector of doubles */
-  template <class T> VMDBase(const std::vector<T> &vector) : nd(vector.size()) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(vector[d]);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor
-   * @param vector :: vector of floats */
-  VMDBase(const std::vector<float> &vector) : nd(vector.size()) {
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    for (size_t d = 0; d < nd; d++)
-      data[d] = TYPE(vector[d]);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Constructor from string
-   * @param str :: string of comma or space-separated numbers for each component
-   */
-  VMDBase(const std::string &str) {
-
-    StringTokenizer strs(str, ", ", StringTokenizer::TOK_IGNORE_EMPTY);
-
-    std::vector<TYPE> vals;
-    std::transform(strs.cbegin(), strs.cend(), std::back_inserter(vals),
-                   [](const std::string &token) {
-                     TYPE v;
-                     if (!Strings::convert(token, v))
-                       throw std::invalid_argument(
-                           "VMDBase: Unable to convert the string '" + token +
-                           "' to a number.");
-                     return v;
-                   });
-
-    nd = vals.size();
-    if (nd <= 0)
-      throw std::invalid_argument("nd must be > 0");
-    data = new TYPE[nd];
-    std::copy(vals.cbegin(), vals.cend(), data);
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /// Destructor
-  virtual ~VMDBase() { delete[] data; }
-
-  //-------------------------------------------------------------------------------------------
-  /// @return the number of dimensions
-  size_t getNumDims() const { return nd; }
-
-  //-------------------------------------------------------------------------------------------
-  /// @return the number of dimensions
-  size_t size() const { return nd; }
-
-  /** @return the value at the index */
-  const TYPE &operator[](const size_t index) const { return data[index]; }
-
-  /** @return the value at the index */
-  TYPE &operator[](const size_t index) { return data[index]; }
-
-  //-------------------------------------------------------------------------------------------
-  /** @return the bare data array directly. */
-  const TYPE *getBareArray() const { return data; }
-
-  //-------------------------------------------------------------------------------------------
-  /** Return a simple string representation of the vector
-   * @param separator :: string to place between values, one space is the
-   * default
-   */
-  std::string toString(const std::string &separator = " ") const {
-    std::ostringstream mess;
-    for (size_t d = 0; d < nd; d++)
-      mess << (d > 0 ? separator : "") << data[d];
-    return mess.str();
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Get the vector as a vector
-   * @tparam T :: type to convert to (double/float)
-   * @return the vector as a std::vector
-   */
-  template <class T> std::vector<T> toVector() const {
-    typename std::vector<T> out;
-    for (size_t d = 0; d < nd; d++)
-      out.push_back(T(data[d]));
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Equals operator with tolerance factor
-    @param v :: VMDBase for comparison
-    @return true if the items are equal
-   */
-  bool operator==(const VMDBase &v) const {
-    if (v.nd != nd)
-      return false;
-    for (size_t d = 0; d < nd; d++)
-      if ((std::fabs(data[d] - v.data[d]) > Tolerance))
-        return false;
-    return true;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Not-equals operator with tolerance factor
-    @param v :: VMDBase for comparison
-    @return true if the items are equal
-   */
-  bool operator!=(const VMDBase &v) const { return !operator==(v); }
-
-  //-------------------------------------------------------------------------------------------
-  /** Add two vectors together
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase operator+(const VMDBase &v) const {
-    VMDBase out(*this);
-    out += v;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Add two vectors together
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase &operator+=(const VMDBase &v) {
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    for (size_t d = 0; d < nd; d++)
-      data[d] += v.data[d];
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Subtract two vectors
-   * @param v
-   *  :: other vector, must match number of dimensions  */
-  VMDBase operator-(const VMDBase &v) const {
-    VMDBase out(*this);
-    out -= v;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Subtract two vectors
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase &operator-=(const VMDBase &v) {
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    for (size_t d = 0; d < nd; d++)
-      data[d] -= v.data[d];
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Inner product of two vectors (element-by-element)
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase operator*(const VMDBase &v) const {
-    VMDBase out(*this);
-    out *= v;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Inner product of two vectors (element-by-element)
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase &operator*=(const VMDBase &v) {
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    for (size_t d = 0; d < nd; d++)
-      data[d] *= v.data[d];
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Inner division of two vectors (element-by-element)
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase operator/(const VMDBase &v) const {
-    VMDBase out(*this);
-    out /= v;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Inner division of two vectors (element-by-element)
-   * @param v :: other vector, must match number of dimensions  */
-  VMDBase &operator/=(const VMDBase &v) {
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    for (size_t d = 0; d < nd; d++)
-      data[d] /= v.data[d];
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Multiply by a scalar
-   * @param scalar :: double scalar to multiply each element  */
-  VMDBase operator*(const double scalar) const {
-    VMDBase out(*this);
-    out *= scalar;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Multiply by a scalar
-   * @param scalar :: double scalar to multiply each element  */
-  VMDBase &operator*=(const double scalar) {
-    for (size_t d = 0; d < nd; d++)
-      data[d] *= TYPE(scalar);
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Divide by a scalar
-   * @param scalar :: double scalar to Divide each element  */
-  VMDBase operator/(const double scalar) const {
-    VMDBase out(*this);
-    out /= scalar;
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Divide by a scalar
-   * @param scalar :: double scalar to Divide each element  */
-  VMDBase &operator/=(const double scalar) {
-    for (size_t d = 0; d < nd; d++)
-      data[d] /= TYPE(scalar);
-    return *this;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Scalar product of two vectors
-   * @param v :: other vector, must match number of dimensions  */
-  TYPE scalar_prod(const VMDBase &v) const {
-    TYPE out = 0;
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    for (size_t d = 0; d < nd; d++)
-      out += (data[d] * v.data[d]);
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Cross product of two vectors. Only works in 3D
-   * @param v :: other vector, also 3D  */
-  VMDBase cross_prod(const VMDBase &v) const {
-    if (v.nd != this->nd)
-      throw std::runtime_error("Mismatch in number of dimensions in operation "
-                               "between two VMDBase vectors.");
-    if (v.nd != 3)
-      throw std::runtime_error(
-          "Cross product of vectors only works in 3 dimensions.");
-    V3D a(data[0], data[1], data[2]);
-    V3D b(v.data[0], v.data[1], v.data[2]);
-    V3D c = a.cross_prod(b);
-    VMDBase out(c);
-    return out;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** @return the length of this vector */
-  TYPE length() const { return TYPE(std::sqrt(this->norm2())); }
-
-  /** @return the length of this vector */
-  TYPE norm() const { return this->length(); }
-
-  /** @return the length of this vector */
-  TYPE norm2() const { return this->scalar_prod(*this); }
-
-  //-------------------------------------------------------------------------------------------
-  /** Normalize this vector to unity length
-   * @return the length of this vector BEFORE normalizing */
-  TYPE normalize() {
-    TYPE length = this->length();
-    for (size_t d = 0; d < nd; d++)
-      data[d] /= length;
-    return length;
-  }
-
-  //-------------------------------------------------------------------------------------------
-  /** Return the angle between this and another vector
-   *  @param v :: The other vector
-   *  @return The angle between the vectors in radians (0 < theta < pi)
-   */
-  TYPE angle(const VMDBase &v) const {
-    return TYPE(acos(this->scalar_prod(v) / (this->norm() * v.norm())));
-  }
+          double val5);
+
+  VMDBase(const VMDBase &other);
+  VMDBase &operator=(const VMDBase &other);
+  VMDBase(size_t nd, const double *bareData);
+  VMDBase(size_t nd, const float *bareData);
+  VMDBase(const V3D &vector);
+  VMDBase(const std::vector<double> &vector);
+  VMDBase(const std::vector<float> &vector);
+  VMDBase(const std::string &str);
+  ~VMDBase();
+
+  size_t getNumDims() const;
+  size_t size() const;
+  const TYPE &operator[](const size_t index) const;
+  TYPE &operator[](const size_t index);
+  const TYPE *getBareArray() const;
+  std::string toString(const std::string &separator = " ") const;
+  template <class T> std::vector<T> toVector() const;
+  bool operator==(const VMDBase &v) const;
+  bool operator!=(const VMDBase &v) const;
+  VMDBase operator+(const VMDBase &v) const;
+  VMDBase &operator+=(const VMDBase &v);
+  VMDBase operator-(const VMDBase &v) const;
+  VMDBase &operator-=(const VMDBase &v);
+  VMDBase operator*(const VMDBase &v) const;
+  VMDBase &operator*=(const VMDBase &v);
+  VMDBase operator/(const VMDBase &v) const;
+  VMDBase &operator/=(const VMDBase &v);
+  VMDBase operator*(const double scalar) const;
+  VMDBase &operator*=(const double scalar);
+  VMDBase operator/(const double scalar) const;
+  VMDBase &operator/=(const double scalar);
+  TYPE scalar_prod(const VMDBase &v) const;
+  VMDBase cross_prod(const VMDBase &v) const;
+  TYPE length() const;
+  TYPE norm() const;
+  TYPE norm2() const;
+  TYPE normalize();
+  TYPE angle(const VMDBase &v) const;
 
   static std::vector<VMDBase>
   makeVectorsOrthogonal(std::vector<VMDBase> &vectors);
diff --git a/Framework/Kernel/src/ArrayBoundedValidator.cpp b/Framework/Kernel/src/ArrayBoundedValidator.cpp
index 2b07a8125d502044c9c4068f4b35ad16e96697b9..68ae912ea9f50fcc354761a3d63dbbe9279f5e50 100644
--- a/Framework/Kernel/src/ArrayBoundedValidator.cpp
+++ b/Framework/Kernel/src/ArrayBoundedValidator.cpp
@@ -137,8 +137,11 @@ template <typename TYPE> void ArrayBoundedValidator<TYPE>::clearUpper() {
 
 // Required explicit instantiations
 template class ArrayBoundedValidator<double>;
-template class ArrayBoundedValidator<int>;
+template class ArrayBoundedValidator<int32_t>;
+template class ArrayBoundedValidator<int64_t>;
+#if defined(_WIN32) || defined(__clang__) && defined(__APPLE__)
 template class ArrayBoundedValidator<long>;
+#endif
 
 } // Kernel
 } // Mantid
diff --git a/Framework/Kernel/src/ArrayLengthValidator.cpp b/Framework/Kernel/src/ArrayLengthValidator.cpp
index 5a4adb6ae10429ad89f7edb4a4d6c3ac1d188ad3..72e740564b5b6739ced66695f33030ddaf66e403 100644
--- a/Framework/Kernel/src/ArrayLengthValidator.cpp
+++ b/Framework/Kernel/src/ArrayLengthValidator.cpp
@@ -185,8 +185,11 @@ std::string ArrayLengthValidator<TYPE>::checkValidity(
 
 // Required explicit instantiations
 template class ArrayLengthValidator<double>;
-template class ArrayLengthValidator<int>;
-template class ArrayLengthValidator<long>;
+template class ArrayLengthValidator<int32_t>;
+template class ArrayLengthValidator<int64_t>;
 template class ArrayLengthValidator<std::string>;
+#if defined(_WIN32) || defined(__clang__) && defined(__APPLE__)
+template class ArrayLengthValidator<long>;
+#endif
 } // namespace Mantid
 } // namespace Kernel
diff --git a/Framework/Kernel/src/ArrayProperty.cpp b/Framework/Kernel/src/ArrayProperty.cpp
index e1192f60a83b0d1b9da4d67fb48049b0544b444f..a951c7972aad406c501338cae00beaf7b86937d8 100644
--- a/Framework/Kernel/src/ArrayProperty.cpp
+++ b/Framework/Kernel/src/ArrayProperty.cpp
@@ -1,21 +1,128 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidKernel/ArrayProperty.h"
 
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
 namespace Mantid {
 namespace Kernel {
 
+/** Constructor
+ *  @param name ::      The name to assign to the property
+ *  @param vec ::       The initial vector of values to assign to the
+ * property.
+ *  @param validator :: The validator to use for this property, if required.
+ *  @param direction :: The direction (Input/Output/InOut) of this property
+ */
+template <typename T>
+ArrayProperty<T>::ArrayProperty(const std::string &name,
+                                const std::vector<T> &vec,
+                                IValidator_sptr validator,
+                                const unsigned int direction)
+    : PropertyWithValue<std::vector<T>>(name, vec, validator, direction) {}
+
+/** Constructor
+ *  Will lead to the property having a default-constructed (i.e. empty) vector
+ *  as its initial (default) value
+ *  @param name ::      The name to assign to the property
+ *  @param validator :: The validator to use for this property, if required
+ *  @param direction :: The direction (Input/Output/InOut) of this property
+ */
+
+template <typename T>
+ArrayProperty<T>::ArrayProperty(const std::string &name,
+                                IValidator_sptr validator,
+                                const unsigned int direction)
+    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), validator,
+                                        direction) {}
+
+/** Constructor that's useful for output properties or inputs with an empty
+ * default and no validator.
+ *  Will lead to the property having a default-constructed (i.e. empty) vector
+ *  as its initial (default) value and no validator
+ *  @param name ::      The name to assign to the property
+ *  @param direction :: The direction (Input/Output/InOut) of this property
+ */
+template <typename T>
+ArrayProperty<T>::ArrayProperty(const std::string &name,
+                                const unsigned int direction)
+    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(),
+                                        IValidator_sptr(new NullValidator),
+                                        direction) {}
+
+/** Constructor from which you can set the property's values through a string:
+ *
+ * Inherits from the constructor of PropertyWithValue specifically made to
+ * handle a list
+ * of numeric values in a string format so that initial value is set
+ * correctly.
+ *
+ *  @param name ::      The name to assign to the property
+ *  @param values ::    A comma-separated string containing the values to
+ * store in the property
+ *  @param validator :: The validator to use for this property, if required
+ *  @param direction :: The direction (Input/Output/InOut) of this property
+ *  @throw std::invalid_argument if the string passed is not compatible with
+ * the array type
+ */
+template <typename T>
+ArrayProperty<T>::ArrayProperty(const std::string &name,
+                                const std::string &values,
+                                IValidator_sptr validator,
+                                const unsigned int direction)
+    : PropertyWithValue<std::vector<T>>(name, std::vector<T>(), values,
+                                        validator, direction) {}
+
+/// 'Virtual copy constructor'
+template <typename T> ArrayProperty<T> *ArrayProperty<T>::clone() const {
+  return new ArrayProperty<T>(*this);
+}
+
+/** Returns the values stored in the ArrayProperty
+ *  @return The stored values as a comma-separated list
+ */
+template <typename T> std::string ArrayProperty<T>::value() const {
+  // Implemented this method for documentation reasons. Just calls base class
+  // method.
+  return PropertyWithValue<std::vector<T>>::value();
+}
+
+/** Sets the values stored in the ArrayProperty from a string representation
+ *  @param value :: The values to assign to the property, given as a
+ * comma-separated list
+ *  @return True if the assignment was successful
+ */
+template <typename T>
+std::string ArrayProperty<T>::setValue(const std::string &value) {
+  // Implemented this method for documentation reasons. Just calls base class
+  // method.
+  return PropertyWithValue<std::vector<T>>::setValue(value);
+}
+
 /// @cond
 
 template class DLLExport ArrayProperty<int32_t>;
+template class DLLExport ArrayProperty<uint32_t>;
 template class DLLExport ArrayProperty<int64_t>;
-template class DLLExport ArrayProperty<size_t>;
+template class DLLExport ArrayProperty<uint64_t>;
+template class DLLExport ArrayProperty<float>;
 template class DLLExport ArrayProperty<double>;
 template class DLLExport ArrayProperty<std::string>;
 
+template class DLLExport ArrayProperty<std::vector<int32_t>>;
+template class DLLExport ArrayProperty<std::vector<uint32_t>>;
+template class DLLExport ArrayProperty<std::vector<int64_t>>;
+template class DLLExport ArrayProperty<std::vector<uint64_t>>;
+template class DLLExport ArrayProperty<std::vector<float>>;
+template class DLLExport ArrayProperty<std::vector<double>>;
 template class DLLExport ArrayProperty<std::vector<std::string>>;
 
+#if defined(_WIN32) || defined(__clang__) && defined(__APPLE__)
+template class DLLExport ArrayProperty<long>;
+template class DLLExport ArrayProperty<unsigned long>;
+template class DLLExport ArrayProperty<std::vector<long>>;
+template class DLLExport ArrayProperty<std::vector<unsigned long>>;
+#endif
+
 /// @endcond
 
 } // namespace Kernel
diff --git a/Framework/Kernel/src/EmptyValues.cpp b/Framework/Kernel/src/EmptyValues.cpp
index c7f6cd92b2ecc537b1c1ded4c25e7549b5e9c2df..bd87b168341101aa95f4b74f7566af2968b6cff0 100644
--- a/Framework/Kernel/src/EmptyValues.cpp
+++ b/Framework/Kernel/src/EmptyValues.cpp
@@ -19,6 +19,12 @@ int EMPTY_INT() { return INT_MAX; }
  */
 long EMPTY_LONG() { return LONG_MAX; }
 
+/**
+ * Returns what we consider an "empty" int64_t within a property
+ * @returns An flag value
+ */
+int64_t EMPTY_INT64() { return INT64_MAX; }
+
 /**
  * Returns what we consider an "empty" double within a property
  * @returns An flag value
diff --git a/Framework/Kernel/src/EnabledWhenProperty.cpp b/Framework/Kernel/src/EnabledWhenProperty.cpp
index d6a11eceb245104ba4c90f9123fcba15e1d4227b..4c41660fb653048b750621c593795aef31fa6e13 100644
--- a/Framework/Kernel/src/EnabledWhenProperty.cpp
+++ b/Framework/Kernel/src/EnabledWhenProperty.cpp
@@ -1,5 +1,7 @@
 #include "MantidKernel/EnabledWhenProperty.h"
 
+#include <boost/lexical_cast.hpp>
+
 using namespace Mantid::Kernel;
 
 namespace Mantid {
diff --git a/Framework/Kernel/src/FacilityInfo.cpp b/Framework/Kernel/src/FacilityInfo.cpp
index 1ade6df6880df9f9ff7bf6c399c143441a614738..ed5491190bcac65965c40ef43f43026cb1e740b0 100644
--- a/Framework/Kernel/src/FacilityInfo.cpp
+++ b/Framework/Kernel/src/FacilityInfo.cpp
@@ -33,7 +33,7 @@ Logger g_log("FacilityInfo");
 FacilityInfo::FacilityInfo(const Poco::XML::Element *elem)
     : m_catalogs(elem), m_name(elem->getAttribute("name")), m_zeroPadding(0),
       m_delimiter(), m_extensions(), m_archiveSearch(), m_instruments(),
-      m_liveListener(), m_noFilePrefix(), m_computeResources() {
+      m_noFilePrefix(), m_computeResources() {
   if (m_name.empty()) {
     g_log.error("Facility name is not defined");
     throw std::runtime_error("Facility name is not defined");
@@ -44,7 +44,6 @@ FacilityInfo::FacilityInfo(const Poco::XML::Element *elem)
   fillDelimiter(elem);
   fillExtensions(elem);
   fillArchiveNames(elem);
-  fillLiveListener(elem);
   fillComputeResources(elem);
   fillNoFilePrefix(elem);
   fillInstruments(elem); // Make sure this is last as it picks up some defaults
@@ -143,16 +142,6 @@ void FacilityInfo::fillInstruments(const Poco::XML::Element *elem) {
   }
 }
 
-/// Called from constructor to fill live listener name
-void FacilityInfo::fillLiveListener(const Poco::XML::Element *elem) {
-  // Get the first livedata element (will be NULL if there's none)
-  Element *live = elem->getChildElement("livedata");
-  if (live) {
-    // Get the name of the listener - empty string will be returned if missing
-    m_liveListener = live->getAttribute("listener");
-  }
-}
-
 /// Called from constructor to fill compute resources map
 void FacilityInfo::fillComputeResources(const Poco::XML::Element *elem) {
   Poco::AutoPtr<Poco::XML::NodeList> pNL_compute =
diff --git a/Framework/Kernel/src/IPropertyManager.cpp b/Framework/Kernel/src/IPropertyManager.cpp
index 54e318ac22e32a85447e27a64221dab4c54152e9..51be0b084e195d1d08a28615030505d32fef1d3d 100644
--- a/Framework/Kernel/src/IPropertyManager.cpp
+++ b/Framework/Kernel/src/IPropertyManager.cpp
@@ -1,7 +1,5 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidKernel/IPropertySettings.h"
 
 ///@cond
 DEFINE_IPROPERTYMANAGER_GETVALUE(int16_t)
@@ -79,6 +77,18 @@ void IPropertyManager::updatePropertyValues(const IPropertyManager &other) {
   }
 }
 
+/** Give settings to a property to determine when it gets enabled/hidden.
+ * Passes ownership of the given IPropertySettings object to the named
+ * property
+ * @param name :: property name
+ * @param settings :: IPropertySettings     */
+void IPropertyManager::setPropertySettings(
+    const std::string &name, std::unique_ptr<IPropertySettings> settings) {
+  Property *prop = getPointerToProperty(name);
+  if (prop)
+    prop->setSettings(std::move(settings));
+}
+
 /**
  * Get all properties in a group.
  * @param group Name of a group.
diff --git a/Framework/Kernel/src/InstrumentInfo.cpp b/Framework/Kernel/src/InstrumentInfo.cpp
index 932712b44399942197ebe038026a7d2f50648ab4..5ddda927a7a31a8a57c39d19fbc616afcb3ba03e 100644
--- a/Framework/Kernel/src/InstrumentInfo.cpp
+++ b/Framework/Kernel/src/InstrumentInfo.cpp
@@ -9,6 +9,7 @@
 #include "MantidKernel/Strings.h"
 
 #include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
 
 #include <Poco/AutoPtr.h>
 #include <Poco/DOM/Element.h>
@@ -29,7 +30,7 @@ Logger g_log("InstrumentInfo");
 */
 InstrumentInfo::InstrumentInfo(const FacilityInfo *f,
                                const Poco::XML::Element *elem)
-    : m_facility(f), m_liveListener(), m_liveDataAddress() {
+    : m_facility(f) {
 
   m_name = elem->getAttribute("name");
   if (m_name.empty()) {
@@ -121,16 +122,64 @@ std::string InstrumentInfo::filePrefix(unsigned int runNumber) const {
 }
 
 /// Returns the name of the live listener
-const std::string &InstrumentInfo::liveListener() const {
-  return m_liveListener;
+std::string InstrumentInfo::liveListener(const std::string &name) const {
+  if (!hasLiveListenerInfo())
+    return "";
+
+  return liveListenerInfo(name).listener();
 }
 
 /** Returns the host & port to connect to for a live data stream
  *  No guarantees are given that the provided string is well-formed and valid
  *    - the caller should check this themselves
  */
-const std::string &InstrumentInfo::liveDataAddress() const {
-  return m_liveDataAddress;
+std::string InstrumentInfo::liveDataAddress(const std::string &name) const {
+  if (!hasLiveListenerInfo())
+    return "";
+
+  return liveListenerInfo(name).address();
+}
+
+/**
+ * Get LiveListenerInfo for specified connection (or default).
+ *
+ * @param name Name attribute of connection to return info on
+ * @return Reference to LiveListenerInfo for specified connection
+ * @throw std::runtime_error When no listeners, or name not found
+ */
+const LiveListenerInfo &
+InstrumentInfo::liveListenerInfo(std::string name) const {
+  if (!hasLiveListenerInfo())
+    throw std::runtime_error("Attempted to access live listener for " + m_name +
+                             " instrument, which has no listeners.");
+
+  // Default to specified default connection
+  if (name.empty())
+    name = m_defaultListener;
+
+  // If no default connection specified, fallback to first connection
+  if (name.empty())
+    return m_listeners.front();
+
+  // Name specified, find requested connection
+  for (auto &listener : m_listeners) {
+    // Names are compared case insensitively
+    if (boost::iequals(listener.name(), name))
+      return listener;
+  }
+
+  // The provided name was not valid / did not match any listeners
+  throw std::runtime_error("Could not find connection " + name +
+                           " for instrument " + m_name);
+}
+
+bool InstrumentInfo::hasLiveListenerInfo() const {
+  return !m_listeners.empty();
+}
+
+const std::vector<LiveListenerInfo> &
+InstrumentInfo::liveListenerInfoList() const {
+  return m_listeners;
 }
 
 /// Return list of techniques
@@ -205,7 +254,7 @@ void InstrumentInfo::fillTechniques(const Poco::XML::Element *elem) {
     if (pNL->length() > 0) {
       Poco::XML::Text *txt = dynamic_cast<Poco::XML::Text *>(pNL->item(0));
       if (txt) {
-        std::string tech = txt->getData();
+        const std::string &tech = txt->getData();
         if (!tech.empty()) {
           m_technique.insert(tech);
         }
@@ -221,32 +270,28 @@ void InstrumentInfo::fillTechniques(const Poco::XML::Element *elem) {
 
 /// Called from constructor to fill live listener name
 void InstrumentInfo::fillLiveData(const Poco::XML::Element *elem) {
-  // Get the first livedata element (will be NULL if there's none)
+  // See if we have a <livedata> element (will be NULL if there's none)
   Poco::XML::Element *live = elem->getChildElement("livedata");
-  if (live) {
-    // Get the name of the listener - empty string will be returned if missing
-    m_liveListener = live->getAttribute("listener");
-    // Get the host+port. Would have liked to put straight into a
-    // Poco::Net::SocketAddress
-    // but that tries to contact the given address on construction, which won't
-    // always be possible (or scalable)
-    m_liveDataAddress = live->getAttribute("address");
-    // Warn rather than throw if there are problems with the address
-    if (m_liveDataAddress.empty()) {
-      g_log.warning()
-          << "No connection details specified for live data listener of "
-          << m_name << "\n";
-    }
-    // Check for a colon, which would suggest that a host & port are present
-    else if (m_liveDataAddress.find(':') == std::string::npos) {
-      g_log.warning() << "Live data address for " << m_name
-                      << " appears not to have both host and port specified.\n";
+  if (!live)
+    return;
+
+  // Load default connection name attribute
+  m_defaultListener = live->getAttribute("default");
+
+  // Get connections under <livedata>
+  Poco::AutoPtr<Poco::XML::NodeList> connections =
+      elem->getElementsByTagName("connection");
+
+  // Load connection info for each child element
+  for (unsigned long i = 0; i < connections->length(); ++i) {
+    auto *conn = dynamic_cast<Poco::XML::Element *>(connections->item(i));
+    try {
+      m_listeners.emplace_back(this, conn);
+    } catch (...) {
+      g_log.error() << "Exception occurred while loading livedata for "
+                    << m_name << " instrument. Skipping faulty connection.\n";
     }
   }
-  // Apply the facility default listener if none specified for this instrument
-  if (m_liveListener.empty()) {
-    m_liveListener = m_facility->liveListener();
-  }
 }
 
 //-------------------------------------------------------------------------
diff --git a/Framework/Kernel/src/LiveListenerInfo.cpp b/Framework/Kernel/src/LiveListenerInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..51eefd2c0d8a22fb15a5aa4584e3ac2673e7f377
--- /dev/null
+++ b/Framework/Kernel/src/LiveListenerInfo.cpp
@@ -0,0 +1,89 @@
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include "MantidKernel/LiveListenerInfo.h"
+
+#include <iosfwd>
+
+#include "MantidKernel/FacilityInfo.h"
+#include "MantidKernel/InstrumentInfo.h"
+#include "MantidKernel/Logger.h"
+
+#include <Poco/DOM/Element.h>
+
+namespace Mantid {
+namespace Kernel {
+namespace {
+// static logger object
+Logger g_log("InstrumentInfo");
+}
+
+/**
+ * Construct from Facility Info XML.
+ *
+ * @param inst Pointer to InstrumentInfo that this LiveListenerInfo belongs to
+ * @param elem The Poco::XML::Element to read the data from
+ */
+LiveListenerInfo::LiveListenerInfo(InstrumentInfo *inst,
+                                   const Poco::XML::Element *elem) {
+  m_name = elem->getAttribute("name");
+  if (m_name.empty()) {
+    g_log.error() << "Listener connection name for " << inst->name()
+                  << "is not defined. This listener will not be selectable.\n";
+  }
+
+  m_address = elem->getAttribute("address");
+  if (m_address.empty()) {
+    g_log.error() << "Listener address for " << inst->name()
+                  << " is not defined.\n";
+  }
+
+  m_listener = elem->getAttribute("listener");
+  if (m_listener.empty()) {
+    g_log.error() << "Listener class for " << inst->name()
+                  << " is not defined.\n";
+  }
+}
+
+/**
+ * Construct manually.
+ *
+ * @param listener Class name of specific listener to use
+ * @param address Address which listener should use to connect
+ * @param name Name designator for this listener connection info
+ */
+LiveListenerInfo::LiveListenerInfo(const std::string &listener,
+                                   const std::string &address,
+                                   const std::string &name)
+    : m_name(name), m_address(address), m_listener(listener) {}
+
+bool LiveListenerInfo::operator==(const LiveListenerInfo &rhs) const {
+  return (this->address() == rhs.address() &&
+          this->listener() == rhs.listener());
+}
+
+const std::string &LiveListenerInfo::name() const { return m_name; }
+
+const std::string &LiveListenerInfo::address() const { return m_address; }
+
+const std::string &LiveListenerInfo::listener() const { return m_listener; }
+
+//-------------------------------------------------------------------------
+// Non-member functions
+//-------------------------------------------------------------------------
+/**
+ * Prints the listener to the stream.
+ *
+ * @param buffer :: A reference to an output stream
+ * @param listener :: A reference to a LiveListenerInfo object
+ * @return A reference to the stream written to
+ */
+std::ostream &operator<<(std::ostream &buffer,
+                         const LiveListenerInfo &listener) {
+  buffer << listener.name() << "(" << listener.address() << ", "
+         << listener.listener() << ")";
+  return buffer;
+}
+
+} // namespace Kernel
+} // namespace Mantid
diff --git a/Framework/Kernel/src/MandatoryValidator.cpp b/Framework/Kernel/src/MandatoryValidator.cpp
index e942e808b4a0dcf82dee4d90d364c9a84d941d65..95fdcc1793429e0d46611d23ae3d73e82641a715 100644
--- a/Framework/Kernel/src/MandatoryValidator.cpp
+++ b/Framework/Kernel/src/MandatoryValidator.cpp
@@ -39,8 +39,19 @@ template <> DLLExport bool checkIsEmpty(const int &value) {
  * @return True if the value is considered empty, see EmptyValues.h
  */
 template <> DLLExport bool checkIsEmpty(const long &value) {
+  // 32 bit for Windows and Clang, 64 bit for GCC
   return (value == Mantid::EMPTY_LONG());
 }
+#if defined(_WIN32) || defined(__clang__) && defined(__APPLE__)
+/**
+ * Specialization of checkIsEmpty for 64 bit intiger
+ * @param value :: A int64_t value
+ * @return True if the value is considered empty, see EmptyValues.h
+ */
+template <> DLLExport bool checkIsEmpty(const int64_t &value) {
+  return (value == Mantid::EMPTY_INT64());
+}
+#endif
 /**
  * Specialization of checkIsEmpty for OptionalBool
  * @param value :: A long value
diff --git a/Framework/Kernel/src/MaskedProperty.cpp b/Framework/Kernel/src/MaskedProperty.cpp
index 71a173945907c9d114e76257c3f3e2dec4d2103c..d61df06576acf192c870b87af0bbb4b72462472d 100644
--- a/Framework/Kernel/src/MaskedProperty.cpp
+++ b/Framework/Kernel/src/MaskedProperty.cpp
@@ -1,6 +1,9 @@
 #include "MantidKernel/MaskedProperty.h"
 #include "MantidKernel/PropertyHistory.h"
 
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
 namespace Mantid {
 namespace Kernel {
 
diff --git a/Framework/Kernel/src/Material.cpp b/Framework/Kernel/src/Material.cpp
index 622d0efa87f30690ead9203ba60095e59cf39a6f..30363639b86dd92f7e5d166aa6488e4fe5dacf8f 100644
--- a/Framework/Kernel/src/Material.cpp
+++ b/Framework/Kernel/src/Material.cpp
@@ -392,7 +392,7 @@ void Material::saveNexus(::NeXus::File *file, const std::string &group) const {
 
   // determine how the information will be stored
   std::string style = "formula"; // default is a chemical formula
-  if (m_chemicalFormula.size() == 0) {
+  if (m_chemicalFormula.empty()) {
     style = "empty";
   } else if (m_chemicalFormula.size() == 1) {
     if (m_chemicalFormula[0].atom->symbol == "user") {
diff --git a/Framework/Kernel/src/MatrixProperty.cpp b/Framework/Kernel/src/MatrixProperty.cpp
index ddd680bdac9ea217da6fab7c7c783134e2d069ef..3d034013529f4c2c6ca3f7fea4ec53570991f58a 100644
--- a/Framework/Kernel/src/MatrixProperty.cpp
+++ b/Framework/Kernel/src/MatrixProperty.cpp
@@ -1,9 +1,9 @@
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
 #include "MantidKernel/MatrixProperty.h"
 #include "MantidKernel/IPropertyManager.h"
 
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
 namespace Mantid {
 namespace Kernel {
 /**
diff --git a/Framework/Kernel/src/MultiFileNameParser.cpp b/Framework/Kernel/src/MultiFileNameParser.cpp
index 2808204f2d7710674a35c1183d94e6856df0bb07..ee2697908883f01a640ce0939a9ef415f5761650 100644
--- a/Framework/Kernel/src/MultiFileNameParser.cpp
+++ b/Framework/Kernel/src/MultiFileNameParser.cpp
@@ -618,7 +618,7 @@ std::vector<std::vector<unsigned int>> generateRange(unsigned int from,
  */
 void validateToken(const std::string &token) {
   // Each token must be non-empty.
-  if (token.size() == 0)
+  if (token.empty())
     throw std::runtime_error("A comma-separated token is empty.");
 
   // Each token must begin and end with a numeric character.
diff --git a/Framework/Kernel/src/NormalDistribution.cpp b/Framework/Kernel/src/NormalDistribution.cpp
index 6b097fff4679f363ef79e6dee4f89ca586414cb0..e7ff30c4280bd54e798bfbebb1b4b41b55f734f4 100644
--- a/Framework/Kernel/src/NormalDistribution.cpp
+++ b/Framework/Kernel/src/NormalDistribution.cpp
@@ -1,6 +1,7 @@
 //------------------------------------------------------------------------------
 // Includes
 //------------------------------------------------------------------------------
+#include <string>
 #include "MantidKernel/NormalDistribution.h"
 #include "MantidKernel/MersenneTwister.h"
 
diff --git a/Framework/Kernel/src/PropertyNexus.cpp b/Framework/Kernel/src/PropertyNexus.cpp
index 0f74bd52806b41e722d94ffac32fb0c2d8fcc38f..10a50b7bd45e63060679a25456bcc347a18bc44d 100644
--- a/Framework/Kernel/src/PropertyNexus.cpp
+++ b/Framework/Kernel/src/PropertyNexus.cpp
@@ -10,6 +10,9 @@
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/make_unique.h"
 
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
+
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/trim.hpp>
 #include <boost/scoped_array.hpp>
diff --git a/Framework/Kernel/src/PropertyWithValue.cpp b/Framework/Kernel/src/PropertyWithValue.cpp
index ba8ba9cecf3650785be6ac8d8381234c7e3c70ff..52d17727d30bd08ba6f867d7554c2b5c4d8a3b4f 100644
--- a/Framework/Kernel/src/PropertyWithValue.cpp
+++ b/Framework/Kernel/src/PropertyWithValue.cpp
@@ -2,8 +2,10 @@
 #include "MantidKernel/PropertyManager.h"
 #include "MantidKernel/Matrix.h"
 
-namespace Mantid {
+// PropertyWithValue implementation
+#include "MantidKernel/PropertyWithValue.tcc"
 
+namespace Mantid {
 namespace Kernel {
 
 #define PROPERTYWITHVALUE_SAVEPROPERTY(type)                                   \
@@ -25,39 +27,62 @@ PROPERTYWITHVALUE_SAVEPROPERTY(std::vector<double>)
 PROPERTYWITHVALUE_SAVEPROPERTY(std::vector<int32_t>)
 
 /// @cond
-#define INSTANTIATE_WITH_EXPORT(Type)                                          \
-  template class DLLExport PropertyWithValue<Type>;
-
-// Explicit instantiations
-INSTANTIATE_WITH_EXPORT(uint16_t)
-INSTANTIATE_WITH_EXPORT(bool)
-INSTANTIATE_WITH_EXPORT(OptionalBool)
+template class MANTID_KERNEL_DLL PropertyWithValue<uint16_t>;
+template class MANTID_KERNEL_DLL PropertyWithValue<bool>;
+template class MANTID_KERNEL_DLL PropertyWithValue<OptionalBool>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<float>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<uint16_t>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<uint32_t>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<int64_t>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<uint64_t>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<bool>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<OptionalBool>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<std::string>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<Matrix<float>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<Matrix<double>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<Matrix<int>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<std::vector<std::vector<int32_t>>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<std::vector<std::vector<std::string>>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<boost::shared_ptr<IValidator>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<boost::shared_ptr<PropertyManager>>;
+#if defined(_WIN32) || defined(__clang__) && defined(__APPLE__)
+template class MANTID_KERNEL_DLL PropertyWithValue<long>;
+template class MANTID_KERNEL_DLL PropertyWithValue<unsigned long>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<long>>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<unsigned long>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<std::vector<std::vector<long>>>;
+#endif
+#ifdef __linux__
+template class MANTID_KERNEL_DLL PropertyWithValue<long long>;
+template class MANTID_KERNEL_DLL PropertyWithValue<unsigned long long>;
+template class MANTID_KERNEL_DLL PropertyWithValue<std::vector<long long>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<std::vector<unsigned long long>>;
+template class MANTID_KERNEL_DLL
+    PropertyWithValue<std::vector<std::vector<long long>>>;
+#endif
 /// @endcond
 
-#define INSTANTIATE_WITH_EXPORT_VECTOR(Type)                                   \
-  template class DLLExport PropertyWithValue<std::vector<Type>>;
-INSTANTIATE_WITH_EXPORT_VECTOR(uint16_t)
-INSTANTIATE_WITH_EXPORT_VECTOR(uint32_t)
-INSTANTIATE_WITH_EXPORT_VECTOR(int64_t)
-INSTANTIATE_WITH_EXPORT_VECTOR(uint64_t)
-INSTANTIATE_WITH_EXPORT_VECTOR(bool)
-INSTANTIATE_WITH_EXPORT_VECTOR(OptionalBool)
-INSTANTIATE_WITH_EXPORT_VECTOR(std::string)
-
 // The explicit template instantiations for some types does not have an export
 // macro
 // since this produces a warning on "gcc: warning: type attributes ignored after
 // type is already define". We can remove the issue, by removing the visibility
 // attribute
+template class PropertyWithValue<float>;
 template class PropertyWithValue<double>;
-template class PropertyWithValue<std::vector<double>>;
-
 template class PropertyWithValue<int32_t>;
-template class PropertyWithValue<std::vector<int32_t>>;
-
 template class PropertyWithValue<uint32_t>;
 template class PropertyWithValue<int64_t>;
 template class PropertyWithValue<uint64_t>;
+
+template class PropertyWithValue<std::vector<double>>;
+template class PropertyWithValue<std::vector<int32_t>>;
+
 template class PropertyWithValue<std::string>;
 
 } // namespace Kernel
diff --git a/Framework/Kernel/src/Quat.cpp b/Framework/Kernel/src/Quat.cpp
index ffc9cba34894112a887e287a5d524cbecb20a4d6..158713f56c1f098ff2e07ff48edcb40e3b41ff64 100644
--- a/Framework/Kernel/src/Quat.cpp
+++ b/Framework/Kernel/src/Quat.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/V3D.h"
 
 #include <boost/algorithm/string.hpp>
+#include <sstream>
 
 namespace Mantid {
 namespace Kernel {
diff --git a/Framework/Kernel/src/RemoteJobManager.cpp b/Framework/Kernel/src/RemoteJobManager.cpp
index 3f11a4bed3f9b67528401478255374a7478c5d76..df29071281e26c4cb02829c7441b8d88f92e41d0 100644
--- a/Framework/Kernel/src/RemoteJobManager.cpp
+++ b/Framework/Kernel/src/RemoteJobManager.cpp
@@ -225,7 +225,7 @@ void RemoteJobManager::initHTTPRequest(Poco::Net::HTTPRequest &req,
   path += extraPath;
 
   uri.setPath(path);
-  if (method == Poco::Net::HTTPRequest::HTTP_GET && queryString.size() > 0) {
+  if (method == Poco::Net::HTTPRequest::HTTP_GET && !queryString.empty()) {
     uri.setQuery(queryString);
   }
 
diff --git a/Framework/Kernel/src/TimeSeriesProperty.cpp b/Framework/Kernel/src/TimeSeriesProperty.cpp
index 1d09e8985ab6c3965357105a855d5bd82dc1e745..4f079f3a1d1d0fc16846b1c833d80a42e4282707 100644
--- a/Framework/Kernel/src/TimeSeriesProperty.cpp
+++ b/Framework/Kernel/src/TimeSeriesProperty.cpp
@@ -71,7 +71,7 @@ TimeSeriesProperty<TYPE>::getDerivative() const {
                              "property with less then two values");
   }
 
-  this->sort();
+  this->sortIfNecessary();
   auto it = this->m_values.begin();
   int64_t t0 = it->time().totalNanoseconds();
   TYPE v0 = it->value();
@@ -162,7 +162,7 @@ operator+=(Property const *right) {
 template <typename TYPE>
 bool TimeSeriesProperty<TYPE>::
 operator==(const TimeSeriesProperty<TYPE> &right) const {
-  sort();
+  sortIfNecessary();
 
   if (this->name() != right.name()) // should this be done?
   {
@@ -261,7 +261,7 @@ template <typename TYPE>
 void TimeSeriesProperty<TYPE>::filterByTime(const Kernel::DateAndTime &start,
                                             const Kernel::DateAndTime &stop) {
   // 0. Sort
-  sort();
+  sortIfNecessary();
 
   // 1. Do nothing for single (constant) value
   if (m_values.size() <= 1)
@@ -319,7 +319,7 @@ template <typename TYPE>
 void TimeSeriesProperty<TYPE>::filterByTimes(
     const std::vector<SplittingInterval> &splittervec) {
   // 1. Sort
-  sort();
+  sortIfNecessary();
 
   // 2. Return for single value
   if (m_values.size() <= 1) {
@@ -406,7 +406,7 @@ void TimeSeriesProperty<TYPE>::splitByTime(
     std::vector<SplittingInterval> &splitter, std::vector<Property *> outputs,
     bool isPeriodic) const {
   // 0. Sort if necessary
-  sort();
+  sortIfNecessary();
 
   if (outputs.empty())
     return;
@@ -581,7 +581,7 @@ void TimeSeriesProperty<TYPE>::makeFilterByValue(
     return;
 
   // 1. Sort
-  sort();
+  sortIfNecessary();
 
   // 2. Do the rest
   bool lastGood(false);
@@ -726,8 +726,7 @@ double TimeSeriesProperty<TYPE>::averageValueInFilter(
     return static_cast<double>(m_values.front().value());
   }
 
-  // Sort, if necessary.
-  sort();
+  sortIfNecessary();
 
   double numerator(0.0), totalTime(0.0);
   // Loop through the filter ranges
@@ -764,8 +763,7 @@ template <typename TYPE>
 double TimeSeriesProperty<TYPE>::timeAverageValue() const {
   double retVal = 0.0;
   try {
-    TimeSplitterType filter;
-    filter.emplace_back(this->firstTime(), this->lastTime());
+    const auto &filter = getSplittingIntervals();
     retVal = this->averageValueInFilter(filter);
   } catch (std::exception &) {
     // just return nan
@@ -803,7 +801,7 @@ template <typename TYPE>
 std::map<DateAndTime, TYPE>
 TimeSeriesProperty<TYPE>::valueAsCorrectMap() const {
   // 1. Sort if necessary
-  sort();
+  sortIfNecessary();
 
   // 2. Data Strcture
   std::map<DateAndTime, TYPE> asMap;
@@ -822,7 +820,7 @@ TimeSeriesProperty<TYPE>::valueAsCorrectMap() const {
  */
 template <typename TYPE>
 std::vector<TYPE> TimeSeriesProperty<TYPE>::valuesAsVector() const {
-  sort();
+  sortIfNecessary();
 
   std::vector<TYPE> out;
   out.reserve(m_values.size());
@@ -859,7 +857,7 @@ TimeSeriesProperty<TYPE>::valueAsMultiMap() const {
  */
 template <typename TYPE>
 std::vector<DateAndTime> TimeSeriesProperty<TYPE>::timesAsVector() const {
-  sort();
+  sortIfNecessary();
 
   std::vector<DateAndTime> out;
   out.reserve(m_values.size());
@@ -878,7 +876,7 @@ std::vector<DateAndTime> TimeSeriesProperty<TYPE>::timesAsVector() const {
 template <typename TYPE>
 std::vector<double> TimeSeriesProperty<TYPE>::timesAsVectorSeconds() const {
   // 1. Sort if necessary
-  sort();
+  sortIfNecessary();
 
   // 2. Output data structure
   std::vector<double> out;
@@ -996,7 +994,7 @@ DateAndTime TimeSeriesProperty<TYPE>::lastTime() const {
     throw std::runtime_error(error);
   }
 
-  sort();
+  sortIfNecessary();
 
   return m_values.rbegin()->time();
 }
@@ -1012,7 +1010,7 @@ template <typename TYPE> TYPE TimeSeriesProperty<TYPE>::firstValue() const {
     throw std::runtime_error(error);
   }
 
-  sort();
+  sortIfNecessary();
 
   return m_values[0].value();
 }
@@ -1029,7 +1027,7 @@ DateAndTime TimeSeriesProperty<TYPE>::firstTime() const {
     throw std::runtime_error(error);
   }
 
-  sort();
+  sortIfNecessary();
 
   return m_values[0].time();
 }
@@ -1046,7 +1044,7 @@ template <typename TYPE> TYPE TimeSeriesProperty<TYPE>::lastValue() const {
     throw std::runtime_error(error);
   }
 
-  sort();
+  sortIfNecessary();
 
   return m_values.rbegin()->value();
 }
@@ -1080,7 +1078,7 @@ template <typename TYPE> int TimeSeriesProperty<TYPE>::realSize() const {
  * @return time series property as a string
  */
 template <typename TYPE> std::string TimeSeriesProperty<TYPE>::value() const {
-  sort();
+  sortIfNecessary();
 
   std::stringstream ins;
   for (size_t i = 0; i < m_values.size(); i++) {
@@ -1104,7 +1102,7 @@ template <typename TYPE> std::string TimeSeriesProperty<TYPE>::value() const {
  */
 template <typename TYPE>
 std::vector<std::string> TimeSeriesProperty<TYPE>::time_tValue() const {
-  sort();
+  sortIfNecessary();
 
   std::vector<std::string> values;
   values.reserve(m_values.size());
@@ -1128,7 +1126,7 @@ std::vector<std::string> TimeSeriesProperty<TYPE>::time_tValue() const {
 template <typename TYPE>
 std::map<DateAndTime, TYPE> TimeSeriesProperty<TYPE>::valueAsMap() const {
   // 1. Sort if necessary
-  sort();
+  sortIfNecessary();
 
   // 2. Build map
 
@@ -1187,7 +1185,8 @@ template <typename TYPE> void TimeSeriesProperty<TYPE>::clear() {
  *  The last value is the last entry in the m_values vector - no sorting is
  *  done or checked for to ensure that the last value is the most recent in
  * time.
- *  It is up to the client to call sort() first if this is a requirement.
+ *  It is up to the client to call sortIfNecessary() first if this is a
+ * requirement.
  */
 template <typename TYPE> void TimeSeriesProperty<TYPE>::clearOutdated() {
   if (realSize() > 1) {
@@ -1271,7 +1270,7 @@ TYPE TimeSeriesProperty<TYPE>::getSingleValue(const DateAndTime &t) const {
   }
 
   // 1. Get sorted
-  sort();
+  sortIfNecessary();
 
   // 2.
   TYPE value;
@@ -1320,7 +1319,7 @@ TYPE TimeSeriesProperty<TYPE>::getSingleValue(const DateAndTime &t,
   }
 
   // 1. Get sorted
-  sort();
+  sortIfNecessary();
 
   // 2.
   TYPE value;
@@ -1376,7 +1375,7 @@ TimeInterval TimeSeriesProperty<TYPE>::nthInterval(int n) const {
   }
 
   // 1. Sort
-  sort();
+  sortIfNecessary();
 
   // 2. Calculate time interval
 
@@ -1495,7 +1494,7 @@ template <typename TYPE> TYPE TimeSeriesProperty<TYPE>::nthValue(int n) const {
   }
 
   // 2. Sort and apply filter
-  sort();
+  sortIfNecessary();
 
   if (m_filter.empty()) {
     // 3. Situation 1:  No filter
@@ -1541,7 +1540,7 @@ template <typename TYPE> TYPE TimeSeriesProperty<TYPE>::nthValue(int n) const {
  */
 template <typename TYPE>
 Kernel::DateAndTime TimeSeriesProperty<TYPE>::nthTime(int n) const {
-  sort();
+  sortIfNecessary();
 
   if (m_values.empty()) {
     const std::string error("nthTime(): TimeSeriesProperty '" + name() +
@@ -1687,8 +1686,8 @@ template <typename TYPE> std::string TimeSeriesProperty<TYPE>::isValid() const {
 }
 
 /*
- * Not implemented in this class
- * @throw Exception::NotImplementedError Not yet implemented
+ * A TimeSeriesProperty never has a default, so return empty string
+ * @returns Empty string as no defaults can be provided
  */
 template <typename TYPE>
 std::string TimeSeriesProperty<TYPE>::getDefault() const {
@@ -1705,20 +1704,26 @@ template <typename TYPE> bool TimeSeriesProperty<TYPE>::isDefault() const {
 /**
  * Return a TimeSeriesPropertyStatistics struct containing the
  * statistics of this TimeSeriesProperty object.
+ *
+ * N.B. This method DOES take filtering into account
  */
 template <typename TYPE>
 TimeSeriesPropertyStatistics TimeSeriesProperty<TYPE>::getStatistics() const {
   TimeSeriesPropertyStatistics out;
   Mantid::Kernel::Statistics raw_stats =
-      Mantid::Kernel::getStatistics(this->valuesAsVector());
+      Mantid::Kernel::getStatistics(this->filteredValuesAsVector());
   out.mean = raw_stats.mean;
   out.standard_deviation = raw_stats.standard_deviation;
   out.median = raw_stats.median;
   out.minimum = raw_stats.minimum;
   out.maximum = raw_stats.maximum;
   if (this->size() > 0) {
-    out.duration =
-        DateAndTime::secondsFromDuration(this->lastTime() - this->firstTime());
+    const auto &intervals = this->getSplittingIntervals();
+    double duration_sec = 0.0;
+    for (const auto &interval : intervals) {
+      duration_sec += interval.duration();
+    }
+    out.duration = duration_sec;
   } else {
     out.duration = std::numeric_limits<double>::quiet_NaN();
   }
@@ -1732,7 +1737,7 @@ TimeSeriesPropertyStatistics TimeSeriesProperty<TYPE>::getStatistics() const {
  */
 template <typename TYPE> void TimeSeriesProperty<TYPE>::eliminateDuplicates() {
   // 1. Sort if necessary
-  sort();
+  sortIfNecessary();
 
   // 2. Detect and Remove Duplicated
   size_t numremoved = 0;
@@ -1786,9 +1791,11 @@ std::string TimeSeriesProperty<TYPE>::toString() const {
 
 //----------------------------------------------------------------------------------
 /*
- * Sort vector mP and set the flag
+ * Sort vector mP and set the flag. Only sorts if the values are not already
+ * sorted.
  */
-template <typename TYPE> void TimeSeriesProperty<TYPE>::sort() const {
+template <typename TYPE>
+void TimeSeriesProperty<TYPE>::sortIfNecessary() const {
   if (m_propSortedFlag == TimeSeriesSortStatus::TSUNKNOWN) {
     bool sorted = is_sorted(m_values.begin(), m_values.end());
     if (sorted)
@@ -1818,7 +1825,7 @@ int TimeSeriesProperty<TYPE>::findIndex(Kernel::DateAndTime t) const {
     return 0;
 
   // 1. Sort
-  sort();
+  sortIfNecessary();
 
   // 2. Extreme value
   if (t <= m_values[0].time()) {
@@ -1868,7 +1875,7 @@ int TimeSeriesProperty<TYPE>::upperBound(Kernel::DateAndTime t, int istart,
   }
 
   // 2. Sort
-  sort();
+  sortIfNecessary();
 
   // 3. Construct the pair for comparison and do lower_bound()
   TimeValueUnit<TYPE> temppair(t, m_values[0].value());
@@ -2186,6 +2193,120 @@ void TimeSeriesProperty<std::string>::histogramData(
                            "properties containing strings");
 }
 
+/**
+ * Get a vector of values taking the filter into account.
+ * Values will be excluded if their times lie in a region where the filter is
+ * false.
+ * @returns :: Vector of included values only
+ */
+template <typename TYPE>
+std::vector<TYPE> TimeSeriesProperty<TYPE>::filteredValuesAsVector() const {
+  if (m_filter.empty()) {
+    return this->valuesAsVector(); // no filtering to do
+  }
+
+  std::vector<TYPE> filteredValues;
+
+  if (!m_filterApplied) {
+    applyFilter();
+  }
+
+  sortIfNecessary();
+
+  const auto &valueMap = valueAsCorrectMap();
+  for (const auto &entry : valueMap) {
+    if (isTimeFiltered(entry.first)) {
+      filteredValues.push_back(entry.second);
+    }
+  }
+
+  return filteredValues;
+}
+
+/**
+ * Find out if the given time is included in the filtered data
+ * i.e. it does not lie in an excluded region
+ * @param time :: [input] Time to check
+ * @returns :: True if time is in an included region, false if the filter
+ * excludes it.
+ */
+template <typename TYPE>
+bool TimeSeriesProperty<TYPE>::isTimeFiltered(
+    const Kernel::DateAndTime &time) const {
+  if (m_filter.empty()) {
+    return false; // no filter
+  }
+
+  if (!m_filterApplied) {
+    applyFilter();
+  }
+
+  // Find which range it lives in
+  auto filterEntry = std::lower_bound(
+      m_filter.begin(), m_filter.end(), time,
+      [](const std::pair<Kernel::DateAndTime, bool> &filterEntry,
+         const Kernel::DateAndTime &t) { return filterEntry.first < t; });
+
+  if (filterEntry != m_filter.begin()) {
+    --filterEntry; // get the latest time BEFORE the given time
+  }
+  return filterEntry->second;
+}
+
+/**
+ * Get a list of the splitting intervals, if filtering is enabled.
+ * Otherwise the interval is just first time - last time.
+ * @returns :: Vector of splitting intervals
+ */
+template <typename TYPE>
+std::vector<SplittingInterval>
+TimeSeriesProperty<TYPE>::getSplittingIntervals() const {
+  std::vector<SplittingInterval> intervals;
+  // Case where there is no filter
+  if (m_filter.empty()) {
+    intervals.emplace_back(firstTime(), lastTime());
+    return intervals;
+  }
+
+  if (!m_filterApplied) {
+    applyFilter();
+  }
+
+  // (local reference to use in lambda)
+  const auto &localFilter = m_filter;
+  /// Count along to find the next time in the filter for which value is 'val'
+  const auto findNext = [&localFilter](size_t &index, const bool val) {
+    for (; index < localFilter.size(); ++index) {
+      const auto &entry = localFilter[index];
+      if (entry.second == val) {
+        return entry.first;
+      }
+    }
+    return localFilter.back().first;
+  };
+
+  // Look through filter to find start/stop pairs
+  size_t index = 0;
+  while (index < m_filter.size()) {
+    DateAndTime start, stop;
+    if (index == 0) {
+      if (m_filter[0].second) {
+        start = m_filter[0].first;
+      } else {
+        start = firstTime();
+      }
+    } else {
+      start = findNext(index, true);
+    }
+    stop = findNext(index, false);
+    if (stop != start) { // avoid empty ranges
+      intervals.emplace_back(start, stop);
+    }
+  }
+
+  return intervals;
+}
+
 /// @cond
 // -------------------------- Macro to instantiation concrete types
 // --------------------------------
diff --git a/Framework/Kernel/src/V2D.cpp b/Framework/Kernel/src/V2D.cpp
index f53139dcea3b9b9a8a3e4bc4e302a87f6ece8a35..85545693ba479ab623c3fc70d18ca3d018bd7adf 100644
--- a/Framework/Kernel/src/V2D.cpp
+++ b/Framework/Kernel/src/V2D.cpp
@@ -1,9 +1,7 @@
-//-----------------------------------------------------------------------------
-// Includes
-//-----------------------------------------------------------------------------
 #include "MantidKernel/V2D.h"
 #include "MantidKernel/V3D.h"
 #include "MantidKernel/Exception.h"
+#include <complex>
 #include <limits>
 
 namespace Mantid {
diff --git a/Framework/Kernel/src/V3D.cpp b/Framework/Kernel/src/V3D.cpp
index 163c806efb6edacc0262f686837c8187220852fb..ef0a3bf2d1e7fd76157bc05b62375f2423001829 100644
--- a/Framework/Kernel/src/V3D.cpp
+++ b/Framework/Kernel/src/V3D.cpp
@@ -1,5 +1,6 @@
 #include <cfloat>
 #include <cmath>
+#include <complex>
 #include <vector>
 
 #include "MantidKernel/V3D.h"
diff --git a/Framework/Kernel/src/VMD.cpp b/Framework/Kernel/src/VMD.cpp
index 2d0a526fff2e2208c0ecec8e172dff8271809b2f..c3bddeec97af9e5fd772ed7cc2a13e2dab9f3851 100644
--- a/Framework/Kernel/src/VMD.cpp
+++ b/Framework/Kernel/src/VMD.cpp
@@ -1,10 +1,484 @@
 #include "MantidKernel/VMD.h"
+#include "MantidKernel/StringTokenizer.h"
+#include "MantidKernel/Strings.h"
+#include "MantidKernel/System.h"
+#include "MantidKernel/Tolerance.h"
+#include "MantidKernel/V3D.h"
+#include <algorithm>
+#include <cstddef>
+#include <sstream>
+#include <stdexcept>
 
 using namespace Mantid::Kernel;
 
 namespace Mantid {
 namespace Kernel {
 
+/** Default constructor, build with 1 dimension */
+template <typename TYPE> VMDBase<TYPE>::VMDBase() : nd(1) {
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(0.0);
+}
+
+/** Constructor
+ * @param nd :: number of dimensions  */
+template <typename TYPE> VMDBase<TYPE>::VMDBase(size_t nd) : nd(nd) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(0.0);
+}
+
+/** 2D Constructor
+ * @param val0 :: value at first dimension
+ * @param val1 :: value at second dimension
+ */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(double val0, double val1)
+    : nd(2) {
+  data = new TYPE[nd];
+  data[0] = TYPE(val0);
+  data[1] = TYPE(val1);
+}
+
+/** 3D Constructor
+ * @param val0 :: value at first dimension
+ * @param val1 :: value at second dimension
+ * @param val2 :: value at third dimension
+ */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(double val0, double val1, double val2)
+    : nd(3) {
+  data = new TYPE[nd];
+  data[0] = TYPE(val0);
+  data[1] = TYPE(val1);
+  data[2] = TYPE(val2);
+}
+
+/** 4D Constructor
+ * @param val0 :: value at first dimension
+ * @param val1 :: value at second dimension
+ * @param val2 :: value at third dimension
+ * @param val3 :: value at fourth dimension
+ */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(double val0, double val1, double val2, double val3)
+    : nd(4) {
+  data = new TYPE[nd];
+  data[0] = TYPE(val0);
+  data[1] = TYPE(val1);
+  data[2] = TYPE(val2);
+  data[3] = TYPE(val3);
+}
+
+/** 5D Constructor
+ * @param val0 :: value at first dimension
+ * @param val1 :: value at second dimension
+ * @param val2 :: value at third dimension
+ * @param val3 :: value at fourth dimension
+ * @param val4 :: value at fifth dimension
+ */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(double val0, double val1, double val2, double val3,
+                       double val4)
+    : nd(5) {
+  data = new TYPE[nd];
+  data[0] = TYPE(val0);
+  data[1] = TYPE(val1);
+  data[2] = TYPE(val2);
+  data[3] = TYPE(val3);
+  data[4] = TYPE(val4);
+}
+
+/** 6D Constructor
+ * @param val0 :: value at first dimension
+ * @param val1 :: value at second dimension
+ * @param val2 :: value at third dimension
+ * @param val3 :: value at fourth dimension
+ * @param val4 :: value at fifth dimension
+ * @param val5 :: value at sixth dimension
+ */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(double val0, double val1, double val2, double val3,
+                       double val4, double val5)
+    : nd(6) {
+  data = new TYPE[nd];
+  data[0] = TYPE(val0);
+  data[1] = TYPE(val1);
+  data[2] = TYPE(val2);
+  data[3] = TYPE(val3);
+  data[4] = TYPE(val4);
+  data[5] = TYPE(val5);
+}
+
+/** Copy constructor
+ * @param other :: other to copy */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(const VMDBase &other)
+    : nd(other.nd) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = other.data[d];
+}
+
+/** Assignment operator
+ * @param other :: copy into this
+ */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator=(const VMDBase &other) {
+  if ((other.nd) != nd) {
+    nd = other.nd;
+    delete[] data;
+    data = new TYPE[nd];
+  }
+  for (size_t d = 0; d < nd; d++)
+    data[d] = other.data[d];
+  return *this;
+}
+
+/** Constructor
+ * @param nd :: number of dimensions
+ * @param bareData :: pointer to a nd-sized bare data array */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(size_t nd, const double *bareData)
+    : nd(nd) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(bareData[d]);
+}
+
+/** Constructor
+ * @param nd :: number of dimensions
+ * @param bareData :: pointer to a nd-sized bare data array */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(size_t nd, const float *bareData)
+    : nd(nd) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(bareData[d]);
+}
+
+/** Constructor
+ * @param vector :: V3D */
+template <typename TYPE> VMDBase<TYPE>::VMDBase(const V3D &vector) : nd(3) {
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(vector[d]);
+}
+
+/** Constructor
+ * @param vector :: vector of doubles */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(const std::vector<double> &vector)
+    : nd(vector.size()) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(vector[d]);
+}
+
+/** Constructor
+ * @param vector :: vector of floats */
+template <typename TYPE>
+VMDBase<TYPE>::VMDBase(const std::vector<float> &vector)
+    : nd(vector.size()) {
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  for (size_t d = 0; d < nd; d++)
+    data[d] = TYPE(vector[d]);
+}
+
+/** Constructor from string
+ * @param str :: string of comma or space-separated numbers for each component
+ */
+template <typename TYPE> VMDBase<TYPE>::VMDBase(const std::string &str) {
+
+  StringTokenizer strs(str, ", ", StringTokenizer::TOK_IGNORE_EMPTY);
+
+  std::vector<TYPE> vals;
+  std::transform(strs.cbegin(), strs.cend(), std::back_inserter(vals),
+                 [](const std::string &token) {
+                   TYPE v;
+                   if (!Strings::convert(token, v))
+                     throw std::invalid_argument(
+                         "VMDBase: Unable to convert the string '" + token +
+                         "' to a number.");
+                   return v;
+                 });
+
+  nd = vals.size();
+  if (nd <= 0)
+    throw std::invalid_argument("nd must be > 0");
+  data = new TYPE[nd];
+  std::copy(vals.cbegin(), vals.cend(), data);
+}
+
+/// Destructor
+template <typename TYPE> VMDBase<TYPE>::~VMDBase() { delete[] data; }
+
+/// @return the number of dimensions
+template <typename TYPE> size_t VMDBase<TYPE>::getNumDims() const { return nd; }
+
+/// @return the number of dimensions
+template <typename TYPE> size_t VMDBase<TYPE>::size() const { return nd; }
+
+/** @return the value at the index */
+template <typename TYPE>
+const TYPE &VMDBase<TYPE>::operator[](const size_t index) const {
+  return data[index];
+}
+
+/** @return the value at the index */
+template <typename TYPE> TYPE &VMDBase<TYPE>::operator[](const size_t index) {
+  return data[index];
+}
+
+/** @return the bare data array directly. */
+template <typename TYPE> const TYPE *VMDBase<TYPE>::getBareArray() const {
+  return data;
+}
+
+/** Return a simple string representation of the vector
+ * @param separator :: string to place between values, one space is the
+ * default
+ */
+template <typename TYPE>
+std::string VMDBase<TYPE>::toString(const std::string &separator) const {
+  std::ostringstream mess;
+  for (size_t d = 0; d < nd; d++)
+    mess << (d > 0 ? separator : "") << data[d];
+  return mess.str();
+}
+
+/** Get the vector as a vector
+ * @tparam T :: type to convert to (double/float)
+ * @return the vector as a std::vector
+ */
+template <typename TYPE>
+template <class T>
+std::vector<T> VMDBase<TYPE>::toVector() const {
+  typename std::vector<T> out;
+  for (size_t d = 0; d < nd; d++)
+    out.push_back(T(data[d]));
+  return out;
+}
+
+/** Equals operator with tolerance factor
+  @param v :: VMDBase for comparison
+  @return true if the items are equal
+ */
+template <typename TYPE>
+bool VMDBase<TYPE>::operator==(const VMDBase &v) const {
+  if (v.nd != nd)
+    return false;
+  for (size_t d = 0; d < nd; d++)
+    if ((std::fabs(data[d] - v.data[d]) > Tolerance))
+      return false;
+  return true;
+}
+
+/** Not-equals operator with tolerance factor
+  @param v :: VMDBase for comparison
+  @return true if the items are equal
+ */
+template <typename TYPE>
+bool VMDBase<TYPE>::operator!=(const VMDBase &v) const {
+  return !operator==(v);
+}
+
+/** Add two vectors together
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator+(const VMDBase &v) const {
+  VMDBase out(*this);
+  out += v;
+  return out;
+}
+
+/** Add two vectors together
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator+=(const VMDBase &v) {
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  for (size_t d = 0; d < nd; d++)
+    data[d] += v.data[d];
+  return *this;
+}
+
+/** Subtract two vectors
+ * @param v
+ *  :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator-(const VMDBase &v) const {
+  VMDBase out(*this);
+  out -= v;
+  return out;
+}
+
+/** Subtract two vectors
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator-=(const VMDBase &v) {
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  for (size_t d = 0; d < nd; d++)
+    data[d] -= v.data[d];
+  return *this;
+}
+
+/** Inner product of two vectors (element-by-element)
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator*(const VMDBase &v) const {
+  VMDBase out(*this);
+  out *= v;
+  return out;
+}
+
+/** Inner product of two vectors (element-by-element)
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator*=(const VMDBase &v) {
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  for (size_t d = 0; d < nd; d++)
+    data[d] *= v.data[d];
+  return *this;
+}
+
+/** Inner division of two vectors (element-by-element)
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator/(const VMDBase &v) const {
+  VMDBase out(*this);
+  out /= v;
+  return out;
+}
+
+/** Inner division of two vectors (element-by-element)
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator/=(const VMDBase &v) {
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  for (size_t d = 0; d < nd; d++)
+    data[d] /= v.data[d];
+  return *this;
+}
+
+/** Multiply by a scalar
+ * @param scalar :: double scalar to multiply each element  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator*(const double scalar) const {
+  VMDBase out(*this);
+  out *= scalar;
+  return out;
+}
+
+/** Multiply by a scalar
+ * @param scalar :: double scalar to multiply each element  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator*=(const double scalar) {
+  for (size_t d = 0; d < nd; d++)
+    data[d] *= TYPE(scalar);
+  return *this;
+}
+
+/** Divide by a scalar
+ * @param scalar :: double scalar to Divide each element  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::operator/(const double scalar) const {
+  VMDBase out(*this);
+  out /= scalar;
+  return out;
+}
+
+/** Divide by a scalar
+ * @param scalar :: double scalar to Divide each element  */
+template <typename TYPE>
+VMDBase<TYPE> &VMDBase<TYPE>::operator/=(const double scalar) {
+  for (size_t d = 0; d < nd; d++)
+    data[d] /= TYPE(scalar);
+  return *this;
+}
+
+/** Scalar product of two vectors
+ * @param v :: other vector, must match number of dimensions  */
+template <typename TYPE>
+TYPE VMDBase<TYPE>::scalar_prod(const VMDBase &v) const {
+  TYPE out = 0;
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  for (size_t d = 0; d < nd; d++)
+    out += (data[d] * v.data[d]);
+  return out;
+}
+
+/** Cross product of two vectors. Only works in 3D
+ * @param v :: other vector, also 3D  */
+template <typename TYPE>
+VMDBase<TYPE> VMDBase<TYPE>::cross_prod(const VMDBase &v) const {
+  if (v.nd != this->nd)
+    throw std::runtime_error("Mismatch in number of dimensions in operation "
+                             "between two VMDBase vectors.");
+  if (v.nd != 3)
+    throw std::runtime_error(
+        "Cross product of vectors only works in 3 dimensions.");
+  V3D a(data[0], data[1], data[2]);
+  V3D b(v.data[0], v.data[1], v.data[2]);
+  V3D c = a.cross_prod(b);
+  VMDBase out(c);
+  return out;
+}
+
+/** @return the length of this vector */
+template <typename TYPE> TYPE VMDBase<TYPE>::length() const {
+  return TYPE(std::sqrt(this->norm2()));
+}
+
+/** @return the length of this vector */
+template <typename TYPE> TYPE VMDBase<TYPE>::norm() const {
+  return this->length();
+}
+
+/** @return the length of this vector */
+template <typename TYPE> TYPE VMDBase<TYPE>::norm2() const {
+  return this->scalar_prod(*this);
+}
+
+/** Normalize this vector to unity length
+ * @return the length of this vector BEFORE normalizing */
+template <typename TYPE> TYPE VMDBase<TYPE>::normalize() {
+  TYPE length = this->length();
+  for (size_t d = 0; d < nd; d++)
+    data[d] /= length;
+  return length;
+}
+
+/** Return the angle between this and another vector
+ *  @param v :: The other vector
+ *  @return The angle between the vectors in radians (0 < theta < pi)
+ */
+template <typename TYPE> TYPE VMDBase<TYPE>::angle(const VMDBase &v) const {
+  return TYPE(acos(this->scalar_prod(v) / (this->norm() * v.norm())));
+}
+
 //-------------------------------------------------------------------------------------------------
 /** Make an orthogonal system with 2 input 3D vectors.
  * Currently only works in 3D!
@@ -117,8 +591,8 @@ VMDBase<TYPE>::getNormalVector(const std::vector<VMDBase<TYPE>> &vectors) {
 }
 
 /// Instantiate VMDBase classes
-template class MANTID_KERNEL_DLL VMDBase<double>;
-template class MANTID_KERNEL_DLL VMDBase<float>;
+template class VMDBase<double>;
+template class VMDBase<float>;
 
 /**
   Prints a text representation of itself
diff --git a/Framework/Kernel/test/ArrayPropertyTest.h b/Framework/Kernel/test/ArrayPropertyTest.h
index c5ff6e73cdf2f246b3bbd1d3fcc8a20c696fbc9a..1805ef6bad8e34d4a0c6724e90bad05722c0e9f9 100644
--- a/Framework/Kernel/test/ArrayPropertyTest.h
+++ b/Framework/Kernel/test/ArrayPropertyTest.h
@@ -146,6 +146,14 @@ public:
     TS_ASSERT_THROWS(ArrayProperty<double> dd("dd", "aa,bb"), std::bad_cast)
   }
 
+  void testConstructorByString_long() {
+    ArrayProperty<long> prop("long", "0:2,5");
+    TS_ASSERT_EQUALS(prop.operator()()[0], 0);
+    TS_ASSERT_EQUALS(prop.operator()()[1], 1);
+    TS_ASSERT_EQUALS(prop.operator()()[2], 2);
+    TS_ASSERT_EQUALS(prop.operator()()[3], 5);
+  }
+
   void testCopyConstructor() {
     ArrayProperty<int> i = *iProp;
     TS_ASSERT(!i.name().compare("intProp"))
diff --git a/Framework/Kernel/test/FacilitiesTest.h b/Framework/Kernel/test/FacilitiesTest.h
index 25aa2cee8d236b10d70c53d6b3359315a156136b..684bf4d04a79788c547a82bab8acc6673a2c77c1 100644
--- a/Framework/Kernel/test/FacilitiesTest.h
+++ b/Framework/Kernel/test/FacilitiesTest.h
@@ -74,7 +74,6 @@ public:
     TS_ASSERT_EQUALS(fac->extensions()[0], ".xyz");
     TS_ASSERT_EQUALS(fac->preferredExtension(), ".xyz");
     TS_ASSERT(fac->archiveSearch().empty());
-    TS_ASSERT(fac->liveListener().empty());
     TS_ASSERT_EQUALS(fac->instruments().size(), 1);
     TS_ASSERT_EQUALS(fac->instruments().front().name(), "AnInst");
     TS_ASSERT_EQUALS(fac->instruments("Measuring Stuff").front().name(),
@@ -155,9 +154,6 @@ public:
     TS_ASSERT_EQUALS(crysInstr.size(), 1);
     TS_ASSERT_EQUALS(fac->instruments("rubbish category").size(), 0);
 
-    // Test default live listener is empty
-    TS_ASSERT(fac->liveListener().empty())
-
     delete fac;
   }
 
@@ -197,25 +193,6 @@ public:
     delete fac;
   }
 
-  void testListener() {
-    const std::string xmlStr =
-        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
-        "<facilities>"
-        "  <facility name=\"TESTER\" FileExtensions=\"*.*\" >"
-        "    <livedata listener=\"Listener1\" />"
-        "    <instrument name=\"ABCD\" >"
-        "      <livedata listener=\"Listener2\" />"
-        "      <technique>None</technique>"
-        "    </instrument>"
-        "  </facility>"
-        "</facilities>";
-
-    FacilityInfo *fac = getFacility(xmlStr);
-    TS_ASSERT(fac);
-    TS_ASSERT_EQUALS(fac->liveListener(), "Listener1");
-    delete fac;
-  }
-
 private:
   FacilityInfo *getFacility(const std::string &xmlStr) const {
     Poco::XML::DOMParser parser;
diff --git a/Framework/Kernel/test/InstrumentInfoTest.h b/Framework/Kernel/test/InstrumentInfoTest.h
index d859873ddbae3baf3862ac085a123d9c7b367467..8f65a009ac8bfb0b9c0c522b453d99b873ffdcd2 100644
--- a/Framework/Kernel/test/InstrumentInfoTest.h
+++ b/Framework/Kernel/test/InstrumentInfoTest.h
@@ -55,9 +55,7 @@ public:
         "<facilities>"
         "  <facility name=\"MyFacility\" zeropadding=\"99\" delimiter=\"!\" "
         "FileExtensions=\".xyz\">"
-        "    <livedata listener=\"I'm listening\" />"
         "    <instrument name=\"AnInst\">"
-        "      <livedata address=\"127.0.0.1:99\" />"
         "      <technique>Measuring Stuff</technique>"
         "    </instrument>"
         "  </facility>"
@@ -70,7 +68,6 @@ public:
 
     TS_ASSERT_EQUALS(inst.zeroPadding(123), 99);
     TS_ASSERT_EQUALS(inst.delimiter(), "!");
-    TS_ASSERT_EQUALS(inst.liveListener(), "I'm listening");
 
     delete fac;
   }
@@ -81,10 +78,8 @@ public:
         "<facilities>"
         "  <facility name=\"MyFacility\" zeropadding=\"99\" delimiter=\"!\" "
         "FileExtensions=\".xyz\">"
-        "    <livedata listener=\"I'm listening\" />"
         "    <instrument name=\"AnInst\" delimiter=\"?\" >"
         "      <zeropadding size=\"66\"/>"
-        "      <livedata listener=\"pardon\" />"
         "      <technique>Measuring Stuff</technique>"
         "    </instrument>"
         "  </facility>"
@@ -97,7 +92,6 @@ public:
 
     TS_ASSERT_EQUALS(inst.zeroPadding(123), 66);
     TS_ASSERT_EQUALS(inst.delimiter(), "?");
-    TS_ASSERT_EQUALS(inst.liveListener(), "pardon");
 
     delete fac;
   }
@@ -106,8 +100,11 @@ public:
     const std::string instStr =
         "<instrument name=\"MyInst\" shortname=\"mine\" delimiter=\":\" >"
         "  <zeropadding size=\"8\"/>"
-        "  <livedata listener=\"AListener\" address=\"myinst.facility.gov:99\" "
-        "/>"
+        "  <livedata>"
+        "    <connection name=\"default\" "
+        "                listener=\"AListener\" "
+        "                address=\"myinst.facility.gov:99\" />"
+        "  </livedata>"
         "  <technique>Measuring Stuff</technique>"
         "  <technique>Doing Stuff</technique>"
         "</instrument>";
@@ -268,4 +265,4 @@ private:
     return new FacilityInfo(elem);
   }
 };
-#endif /*MANTID_FACILITIESTEST_H_*/
+#endif // INSTRUMENTINFOTEST_H_
diff --git a/Framework/Kernel/test/LiveListenerInfoTest.h b/Framework/Kernel/test/LiveListenerInfoTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c14b1434a7f5d70017e1d35b74f378db5c1d3af
--- /dev/null
+++ b/Framework/Kernel/test/LiveListenerInfoTest.h
@@ -0,0 +1,177 @@
+#ifndef LIVELISTENERINFOTEST_H_
+#define LIVELISTENERINFOTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidKernel/Exception.h"
+#include "MantidKernel/LiveListenerInfo.h"
+#include "MantidKernel/FacilityInfo.h"
+
+#include <Poco/AutoPtr.h>
+#include <Poco/DOM/DOMParser.h>
+#include <Poco/DOM/Document.h>
+#include <Poco/DOM/Element.h>
+
+using namespace Mantid::Kernel;
+
+class LiveListenerInfoTest : public CxxTest::TestSuite {
+public:
+  void test_xml_throws_no_connection() {
+    TS_ASSERT_THROWS_NOTHING(createMinimalFacility("<livedata />"));
+  }
+
+  void test_xml_empty_connection() {
+    const std::string xml = "<livedata>"
+                            "<connection />"
+                            "</livedata>";
+
+    FacilityInfo *fac = nullptr;
+    TS_ASSERT_THROWS_NOTHING(fac = createMinimalFacility(xml));
+
+    InstrumentInfo inst = fac->instruments().front();
+    LiveListenerInfo info = inst.liveListenerInfo();
+
+    TS_ASSERT_EQUALS(info.name(), "");
+    TS_ASSERT_EQUALS(info.address(), "");
+    TS_ASSERT_EQUALS(info.listener(), "");
+  }
+
+  void test_xml_single_connection() {
+    const std::string xml = "<livedata>"
+                            "<connection name='n' address='a' listener='l' />"
+                            "</livedata>";
+
+    FacilityInfo *fac = nullptr;
+    TS_ASSERT_THROWS_NOTHING(fac = createMinimalFacility(xml));
+
+    InstrumentInfo inst = fac->instruments().front();
+    LiveListenerInfo info = inst.liveListenerInfo();
+
+    TS_ASSERT_EQUALS(info.name(), "n");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+  }
+
+  void test_xml_two_connections() {
+    const std::string xml = "<livedata>"
+                            "<connection name='n1' address='a' listener='l' />"
+                            "<connection name='n2' address='A' listener='L' />"
+                            "</livedata>";
+
+    FacilityInfo *fac = nullptr;
+    TS_ASSERT_THROWS_NOTHING(fac = createMinimalFacility(xml));
+
+    InstrumentInfo inst = fac->instruments().front();
+    LiveListenerInfo info;
+
+    info = inst.liveListenerInfo();
+    TS_ASSERT_EQUALS(info.name(), "n1");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+
+    info = inst.liveListenerInfo("n1");
+    TS_ASSERT_EQUALS(info.name(), "n1");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+
+    info = inst.liveListenerInfo("n2");
+    TS_ASSERT_EQUALS(info.name(), "n2");
+    TS_ASSERT_EQUALS(info.address(), "A");
+    TS_ASSERT_EQUALS(info.listener(), "L");
+
+    TS_ASSERT_THROWS(inst.liveListenerInfo("n3"), std::runtime_error);
+  }
+
+  void test_xml_two_connections_default() {
+    const std::string xml = "<livedata default='n2'>"
+                            "<connection name='n1' address='a' listener='l' />"
+                            "<connection name='n2' address='A' listener='L' />"
+                            "</livedata>";
+
+    FacilityInfo *fac = nullptr;
+    TS_ASSERT_THROWS_NOTHING(fac = createMinimalFacility(xml));
+
+    InstrumentInfo inst = fac->instruments().front();
+    LiveListenerInfo info;
+
+    info = inst.liveListenerInfo();
+    TS_ASSERT_EQUALS(info.name(), "n2");
+    TS_ASSERT_EQUALS(info.address(), "A");
+    TS_ASSERT_EQUALS(info.listener(), "L");
+
+    info = inst.liveListenerInfo("n1");
+    TS_ASSERT_EQUALS(info.name(), "n1");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+
+    info = inst.liveListenerInfo("n2");
+    TS_ASSERT_EQUALS(info.name(), "n2");
+    TS_ASSERT_EQUALS(info.address(), "A");
+    TS_ASSERT_EQUALS(info.listener(), "L");
+
+    TS_ASSERT_THROWS(inst.liveListenerInfo("n3"), std::runtime_error);
+  }
+
+  void test_manual_construction() {
+    TS_ASSERT_THROWS_NOTHING(LiveListenerInfo{});
+
+    LiveListenerInfo info;
+    TS_ASSERT_EQUALS(info.name(), "");
+    TS_ASSERT_EQUALS(info.address(), "");
+    TS_ASSERT_EQUALS(info.listener(), "");
+
+    TS_ASSERT_THROWS_NOTHING(info = LiveListenerInfo("l"));
+    TS_ASSERT_EQUALS(info.name(), "");
+    TS_ASSERT_EQUALS(info.address(), "");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+
+    TS_ASSERT_THROWS_NOTHING(info = LiveListenerInfo("l", "a"));
+    TS_ASSERT_EQUALS(info.name(), "");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+
+    TS_ASSERT_THROWS_NOTHING(info = LiveListenerInfo("l", "a", "n"));
+    TS_ASSERT_EQUALS(info.name(), "n");
+    TS_ASSERT_EQUALS(info.address(), "a");
+    TS_ASSERT_EQUALS(info.listener(), "l");
+  }
+
+  void test_equality() {
+    LiveListenerInfo info1("l", "a", "n");
+    LiveListenerInfo info2 = info1;
+
+    TS_ASSERT_EQUALS(info1, info2);
+    TS_ASSERT_EQUALS(info1.name(), info2.name());
+    TS_ASSERT_EQUALS(info1.address(), info2.address());
+    TS_ASSERT_EQUALS(info1.listener(), info2.listener());
+
+    LiveListenerInfo info3;
+    TS_ASSERT_DIFFERS(info1, info3);
+  }
+
+private:
+  FacilityInfo *createMinimalFacility(const std::string &livedataXml) {
+    const std::string xmlStr =
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+        "<facilities>"
+        "  <facility name=\"MyFacility\" FileExtensions=\".xyz\">"
+        "    <instrument name=\"INST\">"
+        "      <technique>Technique</technique>" +
+        livedataXml + "    </instrument>"
+                      "  </facility>"
+                      "</facilities>";
+
+    return createFacility(xmlStr);
+  }
+
+  FacilityInfo *createFacility(const std::string &xml) {
+    Poco::XML::DOMParser parser;
+    Poco::AutoPtr<Poco::XML::Document> pDoc = parser.parseString(xml);
+    Poco::XML::Element *pRootElem = pDoc->documentElement();
+    Poco::XML::Element *elem = pRootElem->getChildElement("facility");
+
+    return new FacilityInfo(elem);
+  }
+};
+
+#endif // LIVELISTENERINFOTEST_H_
diff --git a/Framework/Kernel/test/LogParserTest.h b/Framework/Kernel/test/LogParserTest.h
index 10694ec8978ec232cb03c597e437a3513f783fe7..81249f6310179910c36cb207b8b8d0befe63d6e0 100644
--- a/Framework/Kernel/test/LogParserTest.h
+++ b/Framework/Kernel/test/LogParserTest.h
@@ -10,6 +10,8 @@
 #include "MantidKernel/make_unique.h"
 #include "MantidKernel/PropertyWithValue.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include <boost/lexical_cast.hpp>
+#include <boost/scoped_ptr.hpp>
 
 #include <Poco/File.h>
 
@@ -694,9 +696,8 @@ private:
     const auto *prop_with_value =
         dynamic_cast<PropertyWithValue<int> *>(prop.get());
 
-    int value;
     TS_ASSERT(prop_with_value != NULL);
-    Mantid::Kernel::toValue<int>(prop_with_value->value(), value);
+    int value = boost::lexical_cast<int>(prop_with_value->value());
     TS_ASSERT_EQUALS(expected_period, value);
   }
 
diff --git a/Framework/Kernel/test/PropertyWithValueTest.h b/Framework/Kernel/test/PropertyWithValueTest.h
index 147806b007028cd555fc3283758ff4edf90766de..dcc38f6c99c25ecc6a9bbf5d4cccb8169784436c 100644
--- a/Framework/Kernel/test/PropertyWithValueTest.h
+++ b/Framework/Kernel/test/PropertyWithValueTest.h
@@ -23,7 +23,7 @@ public:
     iProp = new PropertyWithValue<int>("intProp", 1);
     dProp = new PropertyWithValue<double>("doubleProp", 9.99);
     sProp = new PropertyWithValue<std::string>("stringProp", "theValue");
-    lProp = new PropertyWithValue<long long>("int64Prop", -9876543210987654LL);
+    lProp = new PropertyWithValue<int64_t>("int64Prop", -9876543210987654LL);
     bProp = new PropertyWithValue<OptionalBool>("boolProp", bool(true));
   }
 
@@ -54,7 +54,7 @@ public:
 
     TS_ASSERT(!lProp->name().compare("int64Prop"));
     TS_ASSERT(!lProp->documentation().compare(""));
-    TS_ASSERT(typeid(long long) == *lProp->type_info());
+    TS_ASSERT(typeid(int64_t) == *lProp->type_info());
     TS_ASSERT(lProp->isDefault());
 
     TS_ASSERT(!bProp->name().compare("boolProp"));
@@ -148,7 +148,7 @@ public:
     TS_ASSERT_EQUALS(s.setValue("it works"), "");
     TS_ASSERT_EQUALS(s.operator()(), "it works");
 
-    PropertyWithValue<long long> l("test", 1);
+    PropertyWithValue<int64_t> l("test", 1);
     TS_ASSERT_EQUALS(l.setValue("10"), "");
     TS_ASSERT_EQUALS(l, 10);
     TS_ASSERT_EQUALS(l.setValue("1234567890123456"), "");
@@ -194,7 +194,7 @@ public:
             i.type());
     TS_ASSERT_EQUALS(i.getDefault(), "3");
 
-    PropertyWithValue<long long> l("defau1", 987987987987LL);
+    PropertyWithValue<int64_t> l("defau1", 987987987987LL);
     TS_ASSERT_EQUALS(l.getDefault(), "987987987987");
     TS_ASSERT_EQUALS(l.setValue("5"), "");
     TS_ASSERT_EQUALS(l.getDefault(), "987987987987");
@@ -242,10 +242,10 @@ public:
     TS_ASSERT(s.isDefault());
     TS_ASSERT_EQUALS(sProp->operator()(), "theValue");
 
-    PropertyWithValue<long long> l = *lProp;
+    PropertyWithValue<int64_t> l = *lProp;
     TS_ASSERT(!lProp->name().compare("int64Prop"));
     TS_ASSERT(!lProp->documentation().compare(""));
-    TS_ASSERT(typeid(long long) == *lProp->type_info());
+    TS_ASSERT(typeid(int64_t) == *lProp->type_info());
     TS_ASSERT(lProp->isDefault());
     TS_ASSERT_EQUALS(l, -9876543210987654LL);
   }
@@ -272,7 +272,7 @@ public:
     TS_ASSERT(!s.isDefault());
     TS_ASSERT_EQUALS(sProp->operator()(), "theValue");
 
-    PropertyWithValue<long long> l("Prop4", 5);
+    PropertyWithValue<int64_t> l("Prop4", 5);
     l = *lProp;
     TS_ASSERT(!l.name().compare("Prop4"));
     TS_ASSERT(!l.documentation().compare(""));
@@ -300,7 +300,7 @@ public:
     s = "testing";
     TS_ASSERT(i.isDefault());
 
-    PropertyWithValue<long long> l("Prop4", 987987987987LL);
+    PropertyWithValue<int64_t> l("Prop4", 987987987987LL);
     TS_ASSERT_EQUALS(l = 2, 2);
     TS_ASSERT(!l.isDefault());
     l = 987987987987LL;
@@ -321,7 +321,7 @@ public:
     TS_ASSERT_EQUALS(ss.operator()(), "tested");
     TS_ASSERT_EQUALS(s.operator()(), "tested");
 
-    PropertyWithValue<long long> ll("Prop4.4", 6);
+    PropertyWithValue<int64_t> ll("Prop4.4", 6);
     l = ll = 789789789789LL;
     TS_ASSERT_EQUALS(ll, 789789789789LL);
     TS_ASSERT_EQUALS(l, 789789789789LL);
@@ -368,7 +368,7 @@ public:
     TS_ASSERT_EQUALS(d, 9.99);
     std::string str = *sProp;
     TS_ASSERT(!str.compare("theValue"));
-    long long l = *lProp;
+    int64_t l = *lProp;
     TS_ASSERT_EQUALS(l, -9876543210987654LL);
   }
 
@@ -419,7 +419,7 @@ public:
 
     TS_ASSERT_DIFFERS(dynamic_cast<Property *>(lProp),
                       static_cast<Property *>(0));
-    PropertyWithValue<long long> l("Prop4", 789789789789LL);
+    PropertyWithValue<int64_t> l("Prop4", 789789789789LL);
     Property *pppp = dynamic_cast<Property *>(&l);
     TS_ASSERT(!pppp->name().compare("Prop4"));
     TS_ASSERT(!pppp->value().compare("789789789789"));
@@ -500,9 +500,9 @@ public:
     TS_ASSERT_EQUALS(ps.isValid(), "");
 
     // int64 tests
-    PropertyWithValue<long long> pl(
+    PropertyWithValue<int64_t> pl(
         "test", 987987987987LL,
-        boost::make_shared<BoundedValidator<long long>>(0, 789789789789LL));
+        boost::make_shared<BoundedValidator<int64_t>>(0, 789789789789LL));
     TS_ASSERT_EQUALS(pl.isValid(), start + "987987987987" + greaterThan +
                                        "789789789789" + end);
     TS_ASSERT_EQUALS(pl.setValue("-1"), start + "-1" + lessThan + "0" + end);
@@ -739,7 +739,7 @@ private:
   PropertyWithValue<int> *iProp;
   PropertyWithValue<double> *dProp;
   PropertyWithValue<std::string> *sProp;
-  PropertyWithValue<long long> *lProp;
+  PropertyWithValue<int64_t> *lProp;
   PropertyWithValue<OptionalBool> *bProp;
 };
 
diff --git a/Framework/Kernel/test/TimeSeriesPropertyTest.h b/Framework/Kernel/test/TimeSeriesPropertyTest.h
index 90e0693bdb573820429d4ef4ca5782368dacacc9..764ce1f79f96072e80baf172fc774132e52ce6b5 100644
--- a/Framework/Kernel/test/TimeSeriesPropertyTest.h
+++ b/Framework/Kernel/test/TimeSeriesPropertyTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/Exception.h"
+#include "MantidKernel/make_unique.h"
 #include "MantidKernel/PropertyWithValue.h"
 #include "MantidKernel/TimeSplitter.h"
 
@@ -702,6 +703,7 @@ public:
     TS_ASSERT_DELTA(stats.mean, 6.0, 1e-3);
     TS_ASSERT_DELTA(stats.duration, 100.0, 1e-3);
     TS_ASSERT_DELTA(stats.standard_deviation, 3.1622, 1e-3);
+    TS_ASSERT_DELTA(log->timeAverageValue(), 5.5, 1e-3);
 
     delete log;
   }
@@ -1923,7 +1925,130 @@ public:
     delete log;
   }
 
+  /// Test that getStatistics respects the filter
+  void test_getStatistics_filtered() {
+    const auto &log = getFilteredTestLog();
+
+    // Get the stats and compare to expected values
+    const auto &stats = log->getStatistics();
+    TS_ASSERT_DELTA(stats.minimum, 1.0, 1e-6);
+    TS_ASSERT_DELTA(stats.maximum, 10.0, 1e-6);
+    TS_ASSERT_DELTA(stats.median, 6.0, 1e-6);
+    TS_ASSERT_DELTA(stats.mean, 5.77778, 1e-3);
+    TS_ASSERT_DELTA(stats.duration, 85.0, 1e-6);
+    TS_ASSERT_DELTA(stats.standard_deviation, 2.8974, 1e-4);
+  }
+
+  /// Test that timeAverageValue respects the filter
+  void test_timeAverageValue_filtered() {
+    const auto &log = getFilteredTestLog();
+    TS_ASSERT_DELTA(log->timeAverageValue(), 5.588, 1e-3);
+  }
+
+  void test_filteredValuesAsVector() {
+    const auto &log = getFilteredTestLog();
+
+    const auto &unfilteredValues = log->valuesAsVector();
+    const auto &filteredValues = log->filteredValuesAsVector();
+
+    TS_ASSERT_DIFFERS(unfilteredValues.size(), filteredValues.size());
+    TS_ASSERT_EQUALS(unfilteredValues.size(), 11);
+    TS_ASSERT_EQUALS(filteredValues.size(), 9);
+  }
+
+  void test_getSplittingIntervals_noFilter() {
+    const auto &log = getTestLog(); // no filter
+    const auto &intervals = log->getSplittingIntervals();
+    TS_ASSERT_EQUALS(intervals.size(), 1);
+    const auto &range = intervals.front();
+    TS_ASSERT_EQUALS(range.start(), log->firstTime());
+    TS_ASSERT_EQUALS(range.stop(), log->lastTime());
+  }
+
+  void test_getSplittingIntervals_repeatedEntries() {
+    const auto &log = getTestLog();
+    // Add the filter
+    auto filter =
+        Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>("Filter");
+    Mantid::Kernel::DateAndTime firstStart("2007-11-30T16:17:00"),
+        firstEnd("2007-11-30T16:17:15"), secondStart("2007-11-30T16:18:35"),
+        secondEnd("2007-11-30T16:18:40");
+    filter->addValue(firstStart.toISO8601String(), true);
+    filter->addValue(firstEnd.toISO8601String(), false);
+    filter->addValue("2007-11-30T16:17:25", false);
+    filter->addValue(secondStart.toISO8601String(), true);
+    filter->addValue("2007-11-30T16:18:38", true);
+    filter->addValue(secondEnd.toISO8601String(), false);
+    log->filterWith(filter.get());
+    const auto &intervals = log->getSplittingIntervals();
+    TS_ASSERT_EQUALS(intervals.size(), 2);
+    if (intervals.size() == 2) {
+      const auto &firstRange = intervals.front(),
+                 &secondRange = intervals.back();
+      TS_ASSERT_EQUALS(firstRange.start(), firstStart);
+      TS_ASSERT_EQUALS(firstRange.stop(), firstEnd);
+      TS_ASSERT_EQUALS(secondRange.start(), secondStart);
+      TS_ASSERT_EQUALS(secondRange.stop(), secondEnd);
+    }
+  }
+
+  void test_getSplittingIntervals_startEndTimes() {
+    const auto &log = getTestLog();
+    // Add the filter
+    auto filter =
+        Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>("Filter");
+    Mantid::Kernel::DateAndTime firstEnd("2007-11-30T16:17:05"),
+        secondStart("2007-11-30T16:17:10"), secondEnd("2007-11-30T16:17:15"),
+        thirdStart("2007-11-30T16:18:35");
+    filter->addValue(log->firstTime(), true);
+    filter->addValue(firstEnd.toISO8601String(), false);
+    filter->addValue(secondStart.toISO8601String(), true);
+    filter->addValue(secondEnd.toISO8601String(), false);
+    filter->addValue(thirdStart.toISO8601String(), true);
+    log->filterWith(filter.get());
+    const auto &intervals = log->getSplittingIntervals();
+    TS_ASSERT_EQUALS(intervals.size(), 3);
+    if (intervals.size() == 3) {
+      TS_ASSERT_EQUALS(intervals[0].start(), log->firstTime());
+      TS_ASSERT_EQUALS(intervals[0].stop(), firstEnd);
+      TS_ASSERT_EQUALS(intervals[1].start(), secondStart);
+      TS_ASSERT_EQUALS(intervals[1].stop(), secondEnd);
+      TS_ASSERT_EQUALS(intervals[2].start(), thirdStart);
+      TS_ASSERT(intervals[2].stop() > thirdStart);
+    }
+  }
+
 private:
+  /// Generate a test log
+  std::unique_ptr<TimeSeriesProperty<double>> getTestLog() {
+    // Build the log
+    auto log =
+        Mantid::Kernel::make_unique<TimeSeriesProperty<double>>("DoubleLog");
+    Mantid::Kernel::DateAndTime logTime("2007-11-30T16:17:00");
+    const double incrementSecs(10.0);
+    for (int i = 1; i < 12; ++i) {
+      const double val = static_cast<double>(i);
+      log->addValue(logTime.toISO8601String(), val);
+      logTime += incrementSecs;
+    }
+    return log;
+  }
+
+  /// Generate a test log that has been filtered
+  std::unique_ptr<TimeSeriesProperty<double>> getFilteredTestLog() {
+    // Build the log
+    auto log = getTestLog();
+    // Add the filter
+    auto filter =
+        Mantid::Kernel::make_unique<TimeSeriesProperty<bool>>("Filter");
+    filter->addValue("2007-11-30T16:17:00", true);
+    filter->addValue("2007-11-30T16:17:15", false);
+    filter->addValue("2007-11-30T16:17:25", true);
+    filter->addValue("2007-11-30T16:18:35", false);
+    log->filterWith(filter.get());
+    return log;
+  }
+
   TimeSeriesProperty<int> *iProp;
   TimeSeriesProperty<double> *dProp;
   TimeSeriesProperty<std::string> *sProp;
diff --git a/Framework/Kernel/test/VMDTest.h b/Framework/Kernel/test/VMDTest.h
index 0d550ab59a508ebce516b1ca4b6b48ed55d047b2..7bc51cad7c1bdcc8cfae86655c0096d0aec12c65 100644
--- a/Framework/Kernel/test/VMDTest.h
+++ b/Framework/Kernel/test/VMDTest.h
@@ -7,6 +7,7 @@
 #include <cmath>
 
 #include "MantidKernel/VMD.h"
+#include "MantidKernel/V3D.h"
 
 using namespace Mantid;
 using namespace Mantid::Kernel;
diff --git a/Framework/LiveData/inc/MantidLiveData/LiveDataAlgorithm.h b/Framework/LiveData/inc/MantidLiveData/LiveDataAlgorithm.h
index 3c4a9fc1b0cd39bea72ba869f6854807e1e2dc0f..686e453c74050ffa7e531b779d38a2f545d63be0 100644
--- a/Framework/LiveData/inc/MantidLiveData/LiveDataAlgorithm.h
+++ b/Framework/LiveData/inc/MantidLiveData/LiveDataAlgorithm.h
@@ -44,7 +44,8 @@ public:
 
   void copyPropertyValuesFrom(const LiveDataAlgorithm &other);
 
-  Mantid::API::ILiveListener_sptr getLiveListener();
+  Mantid::API::ILiveListener_sptr getLiveListener(bool start = true);
+  Mantid::API::ILiveListener_sptr createLiveListener(bool connect = false);
   void setLiveListener(Mantid::API::ILiveListener_sptr listener);
 
   std::map<std::string, std::string> validateInputs() override;
diff --git a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
index 82e025b3b54ae0f87acd56e9000e05fed252c51c..6396042255336735245f5b98118910180602c3d1 100644
--- a/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
+++ b/Framework/LiveData/inc/MantidLiveData/SNSLiveEventDataListener.h
@@ -99,9 +99,9 @@ private:
   // complicated and I didn't want to be repeating the same tests in several
   // places...
   bool readyForInitPart2() {
-    if (m_instrumentXML.size() == 0)
+    if (m_instrumentXML.empty())
       return false;
-    if (m_instrumentName.size() == 0)
+    if (m_instrumentName.empty())
       return false;
     if (m_dataStartTime == Kernel::DateAndTime())
       return false;
diff --git a/Framework/LiveData/src/FileEventDataListener.cpp b/Framework/LiveData/src/FileEventDataListener.cpp
index 81ac4301f8688e6673c3ecfd3bd07a5997e78602..e35a1f290d127eab8e97675582fc162d223eb46b 100644
--- a/Framework/LiveData/src/FileEventDataListener.cpp
+++ b/Framework/LiveData/src/FileEventDataListener.cpp
@@ -1,4 +1,5 @@
 #include "MantidLiveData/FileEventDataListener.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/LiveListenerFactory.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/FileFinder.h"
diff --git a/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp b/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
index 4e58d79eba570e35a807de44afcd4c193d011463..0f0f8e1e88ab50d3a75ad23810b3a1d3423f626e 100644
--- a/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
+++ b/Framework/LiveData/src/ISIS/ISISLiveEventDataListener.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/SpectrumDetectorMapping.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/TimeSeriesProperty.h"
diff --git a/Framework/LiveData/src/LiveDataAlgorithm.cpp b/Framework/LiveData/src/LiveDataAlgorithm.cpp
index 97f346199884739da12d124c3d6e06638beb21ff..1e4d8670c592aba116cbf389b96589f30e703898 100644
--- a/Framework/LiveData/src/LiveDataAlgorithm.cpp
+++ b/Framework/LiveData/src/LiveDataAlgorithm.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/LiveListenerFactory.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
@@ -32,22 +33,36 @@ void LiveDataAlgorithm::initProps() {
   auto &instrInfo =
       Kernel::ConfigService::Instance().getFacility().instruments();
   for (const auto &instrument : instrInfo) {
-    if (!instrument.liveDataAddress().empty()) {
+    if (instrument.hasLiveListenerInfo()) {
       instruments.push_back(instrument.name());
     }
   }
-#ifndef NDEBUG
-  // Debug builds only: Add all the listeners by hand for development testing
-  // purposes
-  std::vector<std::string> listeners =
-      Mantid::API::LiveListenerFactory::Instance().getKeys();
-  instruments.insert(instruments.end(), listeners.begin(), listeners.end());
-#endif
+
+  // All available listener class names
+  auto listeners = LiveListenerFactory::Instance().getKeys();
+  listeners.push_back(""); // Allow not specifying a listener too
+
   declareProperty(Kernel::make_unique<PropertyWithValue<std::string>>(
                       "Instrument", "",
                       boost::make_shared<StringListValidator>(instruments)),
                   "Name of the instrument to monitor.");
 
+  declareProperty(make_unique<PropertyWithValue<std::string>>("Connection", "",
+                                                              Direction::Input),
+                  "Selects the listener connection entry to use. "
+                  "Default connection will be used if not specified");
+
+  declareProperty(
+      Kernel::make_unique<PropertyWithValue<std::string>>(
+          "Listener", "", boost::make_shared<StringListValidator>(listeners)),
+      "Name of the listener class to use. "
+      "If specified, overrides class specified by Connection.");
+
+  declareProperty(make_unique<PropertyWithValue<std::string>>("Address", "",
+                                                              Direction::Input),
+                  "Address for the listener to connect to. "
+                  "If specified, overrides address specified by Connection.");
+
   declareProperty(make_unique<PropertyWithValue<std::string>>("StartTime", "",
                                                               Direction::Input),
                   "Absolute start time, if you selected FromTime.\n"
@@ -170,28 +185,66 @@ bool LiveDataAlgorithm::hasPostProcessing() const {
 }
 
 //----------------------------------------------------------------------------------------------
-/** Return or create the ILiveListener for this algorithm.
+/**
+ * Return or create the ILiveListener for this algorithm.
  *
  * If the ILiveListener has not already been created, it creates it using
  * the properties on the algorithm. It then starts the listener
- * by calling the ILiveListener->start(StartTime) method.
+ * by calling the ILiveListener->start(StartTime) method if start is true.
  *
- * @return ILiveListener_sptr
+ * @param start Whether to start data acquisition right away
+ * @return Shared pointer to interface of this algorithm's LiveListener.
  */
-ILiveListener_sptr LiveDataAlgorithm::getLiveListener() {
+ILiveListener_sptr LiveDataAlgorithm::getLiveListener(bool start) {
   if (m_listener)
     return m_listener;
 
-  // Not stored? Need to create it
-  std::string inst = this->getPropertyValue("Instrument");
-  m_listener = LiveListenerFactory::Instance().create(inst, true, this);
+  // Create a new listener
+  m_listener = createLiveListener(start);
 
   // Start at the given date/time
-  m_listener->start(this->getStartTime());
+  if (start)
+    m_listener->start(this->getStartTime());
 
   return m_listener;
 }
 
+/**
+ * Creates a new instance of a LiveListener based on current values of this
+ * algorithm's properties, respecting Facilities.xml defaults as well as any
+ * provided properties to override them.
+ *
+ * The created LiveListener is not stored or cached as this algorithm's
+ * LiveListener. This is useful for creating temporary instances.
+ *
+ * @param connect Whether the created LiveListener should attempt to connect
+ *                immediately after creation.
+ * @return Shared pointer to interface of created LiveListener instance.
+ */
+ILiveListener_sptr LiveDataAlgorithm::createLiveListener(bool connect) {
+  // Get the LiveListenerInfo from Facilities.xml
+  std::string inst_name = this->getPropertyValue("Instrument");
+  std::string conn_name = this->getPropertyValue("Connection");
+
+  const auto &inst = ConfigService::Instance().getInstrument(inst_name);
+  const auto &conn = inst.liveListenerInfo(conn_name);
+
+  // See if listener and/or address override has been specified
+  std::string listener = this->getPropertyValue("Listener");
+  if (listener.empty())
+    listener = conn.listener();
+
+  std::string address = this->getPropertyValue("Address");
+  if (address.empty())
+    address = conn.address();
+
+  // Construct new LiveListenerInfo with overrides, if given
+  LiveListenerInfo info(listener, address);
+
+  // Create and return
+  return LiveListenerFactory::Instance().create(info, connect, this);
+}
+
 //----------------------------------------------------------------------------------------------
 /** Directly set the LiveListener for this algorithm.
  *
@@ -291,9 +344,7 @@ std::map<std::string, std::string> LiveDataAlgorithm::validateInputs() {
   if (m_listener) {
     eventListener = m_listener->buffersEvents();
   } else {
-    eventListener = LiveListenerFactory::Instance()
-                        .create(instrument, false)
-                        ->buffersEvents();
+    eventListener = createLiveListener()->buffersEvents();
   }
   if (!eventListener && getPropertyValue("AccumulationMethod") == "Add") {
     out["AccumulationMethod"] =
diff --git a/Framework/LiveData/src/LoadLiveData.cpp b/Framework/LiveData/src/LoadLiveData.cpp
index 50d6e8d122180aa8b5327b854186b4fbc9333e9b..7d47082628a32fca93206d5dbc5218d5dac64989 100644
--- a/Framework/LiveData/src/LoadLiveData.cpp
+++ b/Framework/LiveData/src/LoadLiveData.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/ReadLock.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidKernel/CPUTimer.h"
 
diff --git a/Framework/LiveData/src/MonitorLiveData.cpp b/Framework/LiveData/src/MonitorLiveData.cpp
index b245674366a5e5b0c6f1c987d7b7e1d8fcb2afbc..eec8a8fd35b1ce06176559baef43e1692fc63454 100644
--- a/Framework/LiveData/src/MonitorLiveData.cpp
+++ b/Framework/LiveData/src/MonitorLiveData.cpp
@@ -1,6 +1,8 @@
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Memory.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/WriteLock.h"
 #include "MantidLiveData/LoadLiveData.h"
diff --git a/Framework/LiveData/src/SNSLiveEventDataListener.cpp b/Framework/LiveData/src/SNSLiveEventDataListener.cpp
index 533b5c089cbae8a4891fa916a95461c465209872..05ac1dcca276ea9562fc35106bf3d5a1889120bc 100644
--- a/Framework/LiveData/src/SNSLiveEventDataListener.cpp
+++ b/Framework/LiveData/src/SNSLiveEventDataListener.cpp
@@ -10,6 +10,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/Events.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/TimeSeriesProperty.h"
@@ -1198,8 +1199,8 @@ bool SNSLiveEventDataListener::rxPacket(const ADARA::AnnotationPkt &pkt) {
   } // mutex auto unlocks here
 
   // if there's a comment in the packet, log it at the info level
-  std::string comment = pkt.comment();
-  if (comment.size() > 0) {
+  const std::string &comment = pkt.comment();
+  if (!comment.empty()) {
     g_log.information() << "Annotation: " << comment << '\n';
   }
 
diff --git a/Framework/LiveData/src/StartLiveData.cpp b/Framework/LiveData/src/StartLiveData.cpp
index 37a6dd95ebb4b584755aa641362d3ab6ddc2a0dc..29830267bf8ea6e1fbd159a1629cf68fa03e079f 100644
--- a/Framework/LiveData/src/StartLiveData.cpp
+++ b/Framework/LiveData/src/StartLiveData.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/AlgorithmProxy.h"
 #include "MantidAPI/AlgorithmProperty.h"
 #include "MantidAPI/LiveListenerFactory.h"
+#include "MantidAPI/Workspace.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ArrayBoundedValidator.h"
 
@@ -71,19 +72,22 @@ void StartLiveData::init() {
 }
 
 /**
- * After Instrument property is set copy any properties that the instrument's
- * listener may have to this algorithm.
+ * After Listener or Connection properties are set, copy any properties that
+ * the listener may have to this algorithm.
+ *
+ * @param propName Name of property that was just set
  */
 void StartLiveData::afterPropertySet(const std::string &propName) {
-  if (propName == "Instrument") {
+  // If any of these properties change, the listener class might change
+  if (propName == "Instrument" || propName == "Listener" ||
+      propName == "Connection") {
     // Properties of old listener, if any, need to be removed
     removeListenerProperties();
 
-    // Get of instance of listener for this instrument
-    auto listener = LiveListenerFactory::Instance().create(
-        getPropertyValue(propName), false);
+    // Get temp instance of listener for this instrument with current properties
+    auto listener = createLiveListener();
 
-    // Copy over properties of new listener to this algorithm
+    // Copy over properties of listener to this algorithm
     copyListenerProperties(listener);
   }
 }
@@ -108,12 +112,19 @@ void StartLiveData::copyListenerProperties(
  * Removes previously copied ILiveListener properties.
  */
 void StartLiveData::removeListenerProperties() {
-  // Remove all properties tagged with the listener property group
-  for (auto prop : getProperties()) {
+  std::vector<std::string> propertiesToRemove;
+
+  // Find properties tagged with the listener property group
+  for (const auto &prop : getProperties()) {
     if (prop->getGroup() == listenerPropertyGroup) {
-      removeProperty(prop->name());
+      propertiesToRemove.push_back(prop->name());
     }
   }
+
+  // Remove identified properties
+  for (const auto &prop : propertiesToRemove) {
+    removeProperty(prop);
+  }
 }
 
 //----------------------------------------------------------------------------------------------
diff --git a/Framework/LiveData/test/FileEventDataListenerTest.h b/Framework/LiveData/test/FileEventDataListenerTest.h
index 8268b53daed7858840c6d2b19b7a7891eb327543..bdcdc758c7d5dce2d0d8f82f30ab63a80036a9b8 100644
--- a/Framework/LiveData/test/FileEventDataListenerTest.h
+++ b/Framework/LiveData/test/FileEventDataListenerTest.h
@@ -2,6 +2,7 @@
 #define MANTID_LIVEDATA_FILEEVENTDATALISTENERTEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidKernel/ConfigService.h"
 #include "MantidAPI/LiveListenerFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 
diff --git a/Framework/LiveData/test/MonitorLiveDataTest.h b/Framework/LiveData/test/MonitorLiveDataTest.h
index 301d3e19a9dd42e1a4f90ff57440b6a6a74d0a45..fef854358edb0216d4574f1f4a47cf91f36722a9 100644
--- a/Framework/LiveData/test/MonitorLiveDataTest.h
+++ b/Framework/LiveData/test/MonitorLiveDataTest.h
@@ -7,6 +7,7 @@
 
 #include "MantidLiveData/MonitorLiveData.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/Strings.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidKernel/ConfigService.h"
diff --git a/Framework/LiveData/test/StartLiveDataTest.h b/Framework/LiveData/test/StartLiveDataTest.h
index 023343ebd11be6149873e508b8dd7c9c1df932bf..da11133464ace110a32975c456895bc6a6fb6f71 100644
--- a/Framework/LiveData/test/StartLiveDataTest.h
+++ b/Framework/LiveData/test/StartLiveDataTest.h
@@ -102,7 +102,7 @@ public:
 
     // Make an existing output workspace "fake" that should be overwritten
     AnalysisDataService::Instance().addOrReplace(
-        "fake", WorkspaceCreationHelper::Create2DWorkspace(23, 12));
+        "fake", WorkspaceCreationHelper::create2DWorkspace(23, 12));
 
     EventWorkspace_sptr ws;
     ws = doExecEvent("Add", 0, "", "");
diff --git a/Framework/LiveData/test/TestGroupDataListener.cpp b/Framework/LiveData/test/TestGroupDataListener.cpp
index bc442527bd263bfb007ff726d4a33e4d13e9b22f..63798f8a30e319a6a853838f0dcd906f8f70fad0 100644
--- a/Framework/LiveData/test/TestGroupDataListener.cpp
+++ b/Framework/LiveData/test/TestGroupDataListener.cpp
@@ -40,7 +40,7 @@ void TestGroupDataListener::start(
 /** Create the default empty event workspace */
 void TestGroupDataListener::createWorkspace() {
   // create a group
-  m_buffer = WorkspaceCreationHelper::CreateWorkspaceGroup(3, 2, 10, "tst");
+  m_buffer = WorkspaceCreationHelper::createWorkspaceGroup(3, 2, 10, "tst");
   // it must not be in the ADS
   API::AnalysisDataService::Instance().deepRemoveGroup("tst");
 }
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD.h
index b595bfaf8e834e0211cf7f2b5a074b1ad6182a0d..b1692ca3fa01a7fd1f15346ed0c2adc3a2846c56 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/CentroidPeaksMD.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/IMDEventWorkspace_fwd.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
@@ -16,8 +17,12 @@ namespace MDAlgorithms {
  * @author Janik Zikovsky
  * @date 2011-06-01
  */
-class DLLExport CentroidPeaksMD : public API::Algorithm {
+class DLLExport CentroidPeaksMD : public API::Algorithm,
+                                  public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  CentroidPeaksMD();
+
   /// Algorithm's name for identification
   const std::string name() const override { return "CentroidPeaksMD"; };
   /// Summary of algorithms purpose
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h
index 212e0608c2e093fdfb28afda5036255664bda50f..6b2cdab5a565553a9d638043281894251e7851d0 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWSDExpToMomentum.h
@@ -97,6 +97,12 @@ private:
   API::IMDEventWorkspace_sptr m_outputWS;
   Geometry::Instrument_sptr m_virtualInstrument;
 
+  /// Shifts in detector position set from user (calibration): all in the unit
+  /// as meter
+  double m_detSampleDistanceShift;
+  double m_detXShift;
+  double m_detYShift;
+
   Kernel::V3D m_samplePos;
   Kernel::V3D m_sourcePos;
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
index 51263d1b46f8275994583af73a8e83e7871d30e2..2768a7ac1aa17f7f8aba067ad49b41bbc9a3a5b6 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h
@@ -7,6 +7,8 @@
 #include "MantidGeometry/IDTypes.h"
 #include "MantidKernel/FileDescriptor.h"
 
+#include <deque>
+
 namespace Mantid {
 namespace MDAlgorithms {
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
index 1063f3d689c4168006aa98ac691a9b7bccb0ef98..0d261d677e1db296a8547c7a3c88279bc63abe45 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegrateEllipsoids.h
@@ -12,6 +12,9 @@
 #include "MantidDataObjects/PeaksWorkspace.h"
 
 namespace Mantid {
+namespace API {
+class DetectorInfo;
+}
 namespace MDAlgorithms {
 
 class DLLExport IntegrateEllipsoids : public API::Algorithm {
@@ -37,7 +40,7 @@ private:
                         Kernel::DblMatrix const &UBinv, bool hkl_integ);
 
   /// Calculate if this Q is on a detector
-  void calculateE1(Geometry::Instrument_const_sptr inst);
+  void calculateE1(const API::DetectorInfo &detectorInfo);
 
   void runMaskDetectors(Mantid::DataObjects::PeaksWorkspace_sptr peakWS,
                         std::string property, std::string values);
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
index 4c2c16351cf4d6f2d79ce9388e1cba449bcdd769..2cae330fbf9fac946683465635c493b100cd2127 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/IntegratePeaksMD2.h
@@ -9,6 +9,9 @@
 #include "MantidAPI/CompositeFunction.h"
 
 namespace Mantid {
+namespace API {
+class DetectorInfo;
+}
 namespace MDAlgorithms {
 
 /** Integrate single-crystal peaks in reciprocal-space.
@@ -44,7 +47,7 @@ private:
   Mantid::API::IMDEventWorkspace_sptr inWS;
 
   /// Calculate if this Q is on a detector
-  void calculateE1(Geometry::Instrument_const_sptr inst);
+  void calculateE1(const API::DetectorInfo &detectorInfo);
   double detectorQ(Mantid::Kernel::V3D QLabFrame, double r);
   void runMaskDetectors(Mantid::DataObjects::PeaksWorkspace_sptr peakWS,
                         std::string property, std::string values);
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadILLAscii.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadILLAscii.h
index 4756d66f92eac5122ca77d20fd72144480a20bcf..3cfc72e43da568b517909f7595ef5b12b356062f 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadILLAscii.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadILLAscii.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 #include "MantidMDAlgorithms/LoadILLAsciiHelper.h"
 #include "MantidAPI/IFileLoader.h"
@@ -38,7 +39,8 @@ namespace MDAlgorithms {
  File change history is stored at: <https://github.com/mantidproject/mantid>
  Code Documentation is available at: <http://doxygen.mantidproject.org>
  */
-class DLLExport LoadILLAscii : public API::IFileLoader<Kernel::FileDescriptor> {
+class DLLExport LoadILLAscii : public API::IFileLoader<Kernel::FileDescriptor>,
+                               public API::DeprecatedAlgorithm {
 public:
   const std::string name() const override;
   int version() const override;
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
index 7a5e3bea51ef257648242bff8303b7fafce0ddc9..09414c9b161118e729decf67f7415c3c15857d14 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormDirectSC.h
@@ -60,11 +60,6 @@ private:
   void calculateNormalization(const std::vector<coord_t> &otherValues,
                               const Kernel::Matrix<coord_t> &affineTrans);
 
-  std::vector<detid_t> removeGroupedIDs(const API::ExperimentInfo &exptInfo,
-                                        const std::vector<detid_t> &detIDs);
-  Geometry::IDetector_const_sptr
-  getThetaPhi(const detid_t detID, const API::ExperimentInfo &exptInfo,
-              double &theta, double &phi);
   std::vector<Kernel::VMD> calculateIntersections(const double theta,
                                                   const double phi);
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
index b7d0f3ddfad0703bf1c72cc1f3ca919735e3998a..8ba22641dfb9b96503ca5fb2f1d8bf218b749886 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/MDNormSCD.h
@@ -63,11 +63,6 @@ private:
                                      const API::MatrixWorkspace &integrFlux,
                                      size_t sp,
                                      std::vector<double> &yValues) const;
-  std::vector<detid_t> removeGroupedIDs(const API::ExperimentInfo &exptInfo,
-                                        const std::vector<detid_t> &detIDs);
-  Geometry::IDetector_const_sptr
-  getThetaPhi(const detid_t detID, const API::ExperimentInfo &exptInfo,
-              double &theta, double &phi);
   std::vector<Kernel::VMD> calculateIntersections(const double theta,
                                                   const double phi);
 
diff --git a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h
index c3ffe130d930b885fd39866a3fcaf6e66d8d97c2..71841a2059636db307644ef742fde62a73d64660 100644
--- a/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h
+++ b/Framework/MDAlgorithms/inc/MantidMDAlgorithms/Quantification/CachedExperimentInfo.h
@@ -24,6 +24,7 @@
 */
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidGeometry/IDetector.h"
+#include "MantidGeometry/Objects/BoundingBox.h"
 #include "MantidKernel/ClassMacros.h"
 #include "MantidKernel/Matrix.h"
 
diff --git a/Framework/MDAlgorithms/src/AccumulateMD.cpp b/Framework/MDAlgorithms/src/AccumulateMD.cpp
index f78ad4e98b34a3d9237da76d4a9bf0796b856a7f..63c4467e051a48de2f30278a820e6c9fbb7dbd71 100644
--- a/Framework/MDAlgorithms/src/AccumulateMD.cpp
+++ b/Framework/MDAlgorithms/src/AccumulateMD.cpp
@@ -6,12 +6,17 @@
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/PropertyWithValue.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileFinder.h"
 #include "MantidAPI/HistoryView.h"
 #include "MantidDataObjects/MDHistoWorkspaceIterator.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidKernel/EnabledWhenProperty.h"
+
 #include <Poco/File.h>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
index cbf036aaa7a463dcbe00d4f842eb9534d111afce..0d15d133c9477ad740b95059894fb8e7f0cb1c98 100644
--- a/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/BoxControllerSettingsAlgorithm.cpp
@@ -3,6 +3,7 @@
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/StringTokenizer.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
index 4af3ee1f476b02a17f792b2e51dac3eaf8a76abe..b1bccf772186a66d0a33c104770b74b5024b2880 100644
--- a/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
+++ b/Framework/MDAlgorithms/src/CalculateCoverageDGS.cpp
@@ -1,11 +1,14 @@
 #include "MantidMDAlgorithms/CalculateCoverageDGS.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ArrayLengthValidator.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidGeometry/Instrument.h"
@@ -13,6 +16,8 @@
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidKernel/VectorHelper.h"
 
+#include <boost/lexical_cast.hpp>
+
 namespace Mantid {
 namespace MDAlgorithms {
 using namespace Mantid::Kernel;
@@ -131,7 +136,7 @@ void CalculateCoverageDGS::init() {
 
   for (int i = 1; i <= 4; i++) {
     std::string dim("Dimension");
-    dim += Kernel::toString(i);
+    dim += boost::lexical_cast<std::string>(i);
     declareProperty(dim, options[i - 1],
                     boost::make_shared<StringListValidator>(options),
                     "Dimension to bin or integrate");
@@ -161,14 +166,13 @@ void CalculateCoverageDGS::exec() {
       getProperty("InputWorkspace");
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
   // cache two theta and phi
-  auto instrument = inputWS->getInstrument();
-  std::vector<detid_t> detIDS = instrument->getDetectorIDs(true);
+  const auto &detectorInfo = inputWS->detectorInfo();
   std::vector<double> tt, phi;
-  for (auto &id : detIDS) {
-    auto detector = instrument->getDetector(id);
-    if (!detector->isMasked()) {
-      tt.push_back(detector->getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)));
-      phi.push_back(detector->getPhi());
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    if (!detectorInfo.isMasked(i) && !detectorInfo.isMonitor(i)) {
+      const auto &detector = detectorInfo.detector(i);
+      tt.push_back(detector.getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)));
+      phi.push_back(detector.getPhi());
     }
   }
 
@@ -196,7 +200,7 @@ void CalculateCoverageDGS::exec() {
   size_t q1NumBins = 1, q2NumBins = 1, q3NumBins = 1, dENumBins = 1;
   for (int i = 1; i <= 4; i++) {
     std::string dim("Dimension");
-    dim += Kernel::toString(i);
+    dim += boost::lexical_cast<std::string>(i);
     std::string dimensioni = getProperty(dim);
     if (dimensioni == "Q1") {
       affineMat[i - 1][0] = 1.;
diff --git a/Framework/MDAlgorithms/src/CentroidPeaksMD.cpp b/Framework/MDAlgorithms/src/CentroidPeaksMD.cpp
index ce66efc09465025272708ef095555192154c560b..7c8f59197405c7d55d46eb4be046c85441bc7d78 100644
--- a/Framework/MDAlgorithms/src/CentroidPeaksMD.cpp
+++ b/Framework/MDAlgorithms/src/CentroidPeaksMD.cpp
@@ -21,6 +21,8 @@ using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
 using namespace Mantid::DataObjects;
 
+CentroidPeaksMD::CentroidPeaksMD() { this->useAlgorithm("CentroidPeaksMD", 2); }
+
 //----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
diff --git a/Framework/MDAlgorithms/src/CompactMD.cpp b/Framework/MDAlgorithms/src/CompactMD.cpp
index 9d1a5382dee686698e9e801de0461a61c077bb74..84f22c58767e48ede53fe586f4136e1592c3e133 100644
--- a/Framework/MDAlgorithms/src/CompactMD.cpp
+++ b/Framework/MDAlgorithms/src/CompactMD.cpp
@@ -1,5 +1,8 @@
 #include "MantidMDAlgorithms/CompactMD.h"
 #include "MantidAPI/IMDIterator.h"
+
+#include <boost/lexical_cast.hpp>
+
 using namespace Mantid::API;
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
@@ -147,4 +150,4 @@ void CompactMD::exec() {
   this->setProperty("OutputWorkspace", out_ws);
 }
 }
-}
\ No newline at end of file
+}
diff --git a/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp b/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp
index 4223a88d247cf121b17b51b33020dc46cbff1658..e11d0a2a9c98131cf29363fb787b4066361e7c5d 100644
--- a/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp
+++ b/Framework/MDAlgorithms/src/CompareMDWorkspaces.cpp
@@ -178,8 +178,7 @@ void CompareMDWorkspaces::compareMDHistoWorkspaces(
 */
 template <typename MDE, size_t nd>
 void CompareMDWorkspaces::compareMDWorkspaces(
-    typename MDEventWorkspace<MDE, nd>::sptr ws) {
-  typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
+    typename MDEventWorkspace<MDE, nd>::sptr ws1) {
   typename MDEventWorkspace<MDE, nd>::sptr ws2 =
       boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(inWS2);
   if (!ws1 || !ws2)
diff --git a/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp b/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp
index c3ceb29ea17ccbdce5cf9d5f56dc624a7f96dc82..5d63160194163e6240dc79cedcbce3adeac175ea 100644
--- a/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp
+++ b/Framework/MDAlgorithms/src/ConvertCWSDExpToMomentum.cpp
@@ -7,6 +7,7 @@
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidGeometry/Instrument/ComponentHelper.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/MDWSDescription.h"
 #include "MantidMDAlgorithms/MDWSTransform.h"
 #include "MantidAPI/FileProperty.h"
@@ -37,6 +38,21 @@ void ConvertCWSDExpToMomentum::init() {
                                                       Direction::Input),
       "Name of table workspace for data file names in the experiment.");
 
+  declareProperty(
+      "DetectorSampleDistanceShift", 0.0,
+      "Amount of shift in sample-detector distance from 0.3750 meter.");
+
+  declareProperty(
+      "DetectorCenterXShift", 0.0,
+      "Amount of shift of detector center in X-direction from (115, 128).");
+
+  declareProperty(
+      "DetectorCenterYShift", 0.0,
+      "Amount of shift of detector center in Y-direction from (115, 128).");
+
+  declareProperty("UserDefinedWavelength", EMPTY_DBL(),
+                  "User defined wave length if it is specified.");
+
   declareProperty("CreateVirtualInstrument", false,
                   "Flag to create virtual instrument.");
 
@@ -87,10 +103,13 @@ void ConvertCWSDExpToMomentum::exec() {
     g_log.error() << "Importing error: " << errmsg << "\n";
     throw std::runtime_error(errmsg);
   }
+  m_detSampleDistanceShift = getProperty("DetectorSampleDistanceShift");
+  m_detXShift = getProperty("DetectorCenterXShift");
+  m_detYShift = getProperty("DetectorCenterYShift");
 
   // background
   std::string bkgdwsname = getPropertyValue("BackgroundWorkspace");
-  if (bkgdwsname.size() > 0) {
+  if (!bkgdwsname.empty()) {
     m_removeBackground = true;
     m_backgroundWS = getProperty("BackgroundWorkspace");
     // check background
@@ -214,7 +233,7 @@ void ConvertCWSDExpToMomentum::addMDEvents(bool usevirtual) {
 
   // Check whether to add / or \ to m_dataDir
   std::string sep;
-  if (m_dataDir.size() > 0) {
+  if (!m_dataDir.empty()) {
 // Determine system
 #if _WIN64
     const bool isWindows = true;
@@ -541,7 +560,7 @@ bool ConvertCWSDExpToMomentum::getInputs(bool virtualinstrument,
 
   errmsg = errss.str();
 
-  return (errmsg.size() == 0);
+  return (errmsg.empty());
 }
 
 //----------------------------------------------------------------------------------------------
@@ -600,6 +619,15 @@ ConvertCWSDExpToMomentum::loadSpiceData(const std::string &filename,
     sizelist[1] = 256;
     loader->setProperty("DetectorGeometry", sizelist);
     loader->setProperty("LoadInstrument", true);
+    loader->setProperty("ShiftedDetectorDistance", m_detSampleDistanceShift);
+    loader->setProperty("DetectorCenterXShift", m_detXShift);
+    loader->setProperty("DetectorCenterYShift", m_detYShift);
+
+    double wavelength = getProperty("UserDefinedWavelength");
+
+    if (wavelength != EMPTY_DBL()) {
+      loader->setProperty("UserSpecifiedWaveLength", wavelength);
+    }
 
     loader->execute();
 
diff --git a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
index 0b4cfb8c09e8d03c85fc907c89b421410b518b94..8d3ad9c0fdb2c5fab94b19c6f5ecfceab3cac00c 100644
--- a/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
+++ b/Framework/MDAlgorithms/src/ConvertCWSDMDtoHKL.cpp
@@ -1,5 +1,6 @@
 #include "MantidMDAlgorithms/ConvertCWSDMDtoHKL.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDIterator.h"
@@ -105,7 +106,7 @@ void ConvertCWSDMDtoHKL::exec() {
 
   std::string qsamplefilename = getPropertyValue("QSampleFileName");
   // Abort with an empty string
-  if (qsamplefilename.size() > 0)
+  if (!qsamplefilename.empty())
     saveEventsToFile(qsamplefilename, vec_event_qsample, vec_event_signal,
                      vec_event_det);
 
@@ -116,7 +117,7 @@ void ConvertCWSDMDtoHKL::exec() {
   // Get file name
   std::string hklfilename = getPropertyValue("HKLFileName");
   // Abort mission if no file name is given
-  if (hklfilename.size() > 0)
+  if (!hklfilename.empty())
     saveEventsToFile(hklfilename, vec_event_hkl, vec_event_signal,
                      vec_event_det);
 
@@ -136,7 +137,7 @@ void ConvertCWSDMDtoHKL::exec() {
 
 void ConvertCWSDMDtoHKL::getUBMatrix() {
   std::string peakwsname = getPropertyValue("PeaksWorkspace");
-  if (peakwsname.size() > 0 &&
+  if (!peakwsname.empty() &&
       AnalysisDataService::Instance().doesExist(peakwsname)) {
     // Get from peak works
     DataObjects::PeaksWorkspace_sptr peakws = getProperty("PeaksWorkspace");
@@ -221,7 +222,7 @@ void ConvertCWSDMDtoHKL::saveMDToFile(
   std::string filename = getPropertyValue("QSampleFileName");
 
   // Abort with an empty string
-  if (filename.size() == 0)
+  if (filename.empty())
     return;
   if (vec_event_qsample.size() != vec_event_signal.size())
     throw std::runtime_error(
diff --git a/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp b/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp
index 93898efc6aac2ad4fab39739c8e6b326ade77a7f..b863c49c5157ec73ae80074f03a61fc29c047fa4 100644
--- a/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDetectorFaceMD.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/ArrayLengthValidator.h"
 #include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
+#include "MantidKernel/Unit.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidGeometry/Instrument/RectangularDetector.h"
diff --git a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
index 67072208957d5369f20b051c98230b8418fd9496..21d131ade6e6383a94c1f9e17a566546bf1fe653 100644
--- a/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToDiffractionMDWorkspace.cpp
@@ -20,6 +20,7 @@
 #include "MantidKernel/ProgressText.h"
 #include "MantidKernel/System.h"
 #include "MantidKernel/Timer.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitLabelTypes.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/ConfigService.h"
diff --git a/Framework/MDAlgorithms/src/ConvertToMD.cpp b/Framework/MDAlgorithms/src/ConvertToMD.cpp
index 357b1895c9e41ce8fd54288603d5bef07d82d5ef..92f7f1693cafffff8f78efdb554f2ad799cc4748 100644
--- a/Framework/MDAlgorithms/src/ConvertToMD.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToMD.cpp
@@ -357,10 +357,7 @@ void ConvertToMD::copyMetaData(API::IMDEventWorkspace_sptr &mdEventWS) const {
   auto mapping = boost::make_shared<det2group_map>();
   for (size_t i = 0; i < m_InWS2D->getNumberHistograms(); ++i) {
     const auto &dets = m_InWS2D->getSpectrum(i).getDetectorIDs();
-    if (!dets.empty()) {
-      mapping->emplace(*dets.begin(),
-                       std::vector<detid_t>(dets.begin(), dets.end()));
-    }
+    mapping->emplace(*dets.begin(), dets);
   }
 
   // The last experiment info should always be the one that refers
diff --git a/Framework/MDAlgorithms/src/ConvertToMDParent.cpp b/Framework/MDAlgorithms/src/ConvertToMDParent.cpp
index c1ab2ba739b112a5d9000c176f4e77f6c344a03f..69eec8c85ef1f5ee2edc564fc847d3d2adeb5bf4 100644
--- a/Framework/MDAlgorithms/src/ConvertToMDParent.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToMDParent.cpp
@@ -1,5 +1,6 @@
 #include "MantidMDAlgorithms/ConvertToMDParent.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
diff --git a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
index 17ca579dfd540b6d65f53a061651b8ca8c20ead7..67332bf786317f9b1d5337bccf159c235e5f18e2 100644
--- a/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
+++ b/Framework/MDAlgorithms/src/ConvertToReflectometryQ.cpp
@@ -22,6 +22,7 @@
 #include "MantidKernel/EnabledWhenProperty.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/TimeSeriesProperty.h"
+#include "MantidKernel/Unit.h"
 
 #include "MantidMDAlgorithms/ReflectometryTransformKiKf.h"
 #include "MantidMDAlgorithms/ReflectometryTransformQxQz.h"
diff --git a/Framework/MDAlgorithms/src/CreateMD.cpp b/Framework/MDAlgorithms/src/CreateMD.cpp
index a492605d2b14f04ab6c51b32e319152870b9f356..7241c8dc04155765d937ee231d47f14e24201551 100644
--- a/Framework/MDAlgorithms/src/CreateMD.cpp
+++ b/Framework/MDAlgorithms/src/CreateMD.cpp
@@ -1,5 +1,6 @@
 #include "MantidMDAlgorithms/CreateMD.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
diff --git a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
index ddf4bdc9fca8e93ba2abe6f21f428021e7365a67..bcfb380c3351029af75f08f3c3fc0e85765dedc9 100644
--- a/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
+++ b/Framework/MDAlgorithms/src/GetSpiceDataRawCountsFromMD.cpp
@@ -108,7 +108,7 @@ void GetSpiceDataRawCountsFromMD::exec() {
                               ylabel, donormalize);
   } else if (mode.compare("Sample Log") == 0) {
     std::string samplelogname = getProperty("SampleLogName");
-    if (samplelogname.size() == 0)
+    if (samplelogname.empty())
       throw std::runtime_error(
           "For mode 'Sample Log', value of 'SampleLogName' must be specified.");
     exportSampleLogValue(datamdws, samplelogname, vecX, vecY, xlabel, ylabel);
@@ -220,7 +220,7 @@ void GetSpiceDataRawCountsFromMD::exportIndividualDetCounts(
   std::vector<double> vecDetCounts;
   int runnumber = -1;
   bool get2theta = false;
-  if (xlabel.size() == 0) {
+  if (xlabel.empty()) {
     // xlabel is in default and thus use 2-theta for X
     get2theta = true;
   }
@@ -305,7 +305,7 @@ void GetSpiceDataRawCountsFromMD::exportSampleLogValue(
   ylabel = samplelogname;
 
   // X values
-  if (xlabel.size() == 0) {
+  if (xlabel.empty()) {
     // default
     xlabel = "Pt.";
   }
@@ -513,7 +513,7 @@ MatrixWorkspace_sptr GetSpiceDataRawCountsFromMD::createOutputWorkspace(
 
   // Set label
   outws->setYUnitLabel(ylabel);
-  if (xlabel.size() != 0) {
+  if (!xlabel.empty()) {
     try {
       outws->getAxis(0)->setUnit(xlabel);
     } catch (...) {
diff --git a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
index d66b667fd9674db809b6ba27aaf2614bd53db80b..dad6746a2f8d769078aa5e6aaec6150c956425c6 100644
--- a/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
+++ b/Framework/MDAlgorithms/src/IntegrateEllipsoids.cpp
@@ -1,5 +1,7 @@
 #include "MantidMDAlgorithms/IntegrateEllipsoids.h"
 
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
@@ -324,9 +326,7 @@ void IntegrateEllipsoids::exec() {
       g_log.error("Can't execute MaskBTP algorithm for this instrument to set "
                   "edge for IntegrateIfOnEdge option");
     }
-    // Get the instrument and its detectors
-    Geometry::Instrument_const_sptr inst = in_peak_ws->getInstrument();
-    calculateE1(inst); // fill E1Vec for use in detectorQ
+    calculateE1(in_peak_ws->detectorInfo()); // fill E1Vec for use in detectorQ
   }
 
   Mantid::DataObjects::PeaksWorkspace_sptr peak_ws =
@@ -585,17 +585,15 @@ void IntegrateEllipsoids::initTargetWSDescr(MatrixWorkspace_sptr &wksp) {
  *
  * @param inst: instrument
  */
-void IntegrateEllipsoids::calculateE1(Geometry::Instrument_const_sptr inst) {
-  std::vector<detid_t> detectorIDs = inst->getDetectorIDs();
-
-  for (auto &detectorID : detectorIDs) {
-    Mantid::Geometry::IDetector_const_sptr det = inst->getDetector(detectorID);
-    if (det->isMonitor())
+void IntegrateEllipsoids::calculateE1(const API::DetectorInfo &detectorInfo) {
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    if (detectorInfo.isMonitor(i))
       continue; // skip monitor
-    if (!det->isMasked())
+    if (!detectorInfo.isMasked(i))
       continue; // edge is masked so don't check if not masked
-    double tt1 = det->getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)); // two theta
-    double ph1 = det->getPhi();                                // phi
+    const auto &det = detectorInfo.detector(i);
+    double tt1 = det.getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)); // two theta
+    double ph1 = det.getPhi();                                // phi
     V3D E1 = V3D(-std::sin(tt1) * std::cos(ph1), -std::sin(tt1) * std::sin(ph1),
                  1. - std::cos(tt1)); // end of trajectory
     E1 = E1 * (1. / E1.norm());       // normalize
diff --git a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
index 4c724bcb83d0a2615662feb52351fe6496cc42e0..82ee67bace0ac3997e3dd46ad003be4ed13127bf 100644
--- a/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
+++ b/Framework/MDAlgorithms/src/IntegratePeaksCWSD.cpp
@@ -125,7 +125,7 @@ void IntegratePeaksCWSD::processInputs() {
 
   // Input peaks
   std::vector<double> peak_center = getProperty("PeakCentre");
-  if (peak_center.size() > 0) {
+  if (!peak_center.empty()) {
     // assigned peak center
     if (peak_center.size() != 3)
       throw std::invalid_argument("PeakCentre must have 3 elements.");
@@ -187,7 +187,7 @@ void IntegratePeaksCWSD::processInputs() {
 
   // optional mask workspace
   std::string maskwsname = getPropertyValue("MaskWorkspace");
-  if (maskwsname.size() > 0) {
+  if (!maskwsname.empty()) {
     // process mask workspace
     m_maskDets = true;
     m_maskWS = getProperty("MaskWorkspace");
@@ -254,7 +254,7 @@ void IntegratePeaksCWSD::simplePeakIntegration(
       // ... debug */
 
       // Check whether this detector is masked
-      if (vecMaskedDetID.size() > 0) {
+      if (!vecMaskedDetID.empty()) {
         detid_t detid = mditer->getInnerDetectorID(iev);
         std::vector<detid_t>::const_iterator it;
 
diff --git a/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp b/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp
index 93bc846481f64e5b918f0d561d69bd4110427e0a..295a8dacd2e95dd8a2ec45954ee555336b10de9c 100644
--- a/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp
+++ b/Framework/MDAlgorithms/src/IntegratePeaksMD2.cpp
@@ -13,6 +13,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidKernel/Utils.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/Column.h"
@@ -170,9 +171,7 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
                 "edge for IntegrateIfOnEdge option");
   }
 
-  // Get the instrument and its detectors
-  Geometry::Instrument_const_sptr inst = inPeakWS->getInstrument();
-  calculateE1(inst); // fill E1Vec for use in detectorQ
+  calculateE1(inPeakWS->detectorInfo()); // fill E1Vec for use in detectorQ
   Mantid::Kernel::SpecialCoordinateSystem CoordinatesToUse =
       ws->getSpecialCoordinateSystem();
 
@@ -703,17 +702,15 @@ void IntegratePeaksMD2::integrate(typename MDEventWorkspace<MDE, nd>::sptr ws) {
  *
  * @param inst: instrument
  */
-void IntegratePeaksMD2::calculateE1(Geometry::Instrument_const_sptr inst) {
-  std::vector<detid_t> detectorIDs = inst->getDetectorIDs();
-
-  for (auto &detectorID : detectorIDs) {
-    Mantid::Geometry::IDetector_const_sptr det = inst->getDetector(detectorID);
-    if (det->isMonitor())
+void IntegratePeaksMD2::calculateE1(const API::DetectorInfo &detectorInfo) {
+  for (size_t i = 0; i < detectorInfo.size(); ++i) {
+    if (detectorInfo.isMonitor(i))
       continue; // skip monitor
-    if (!det->isMasked())
+    if (!detectorInfo.isMasked(i))
       continue; // edge is masked so don't check if not masked
-    double tt1 = det->getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)); // two theta
-    double ph1 = det->getPhi();                                // phi
+    const auto &det = detectorInfo.detector(i);
+    double tt1 = det.getTwoTheta(V3D(0, 0, 0), V3D(0, 0, 1)); // two theta
+    double ph1 = det.getPhi();                                // phi
     V3D E1 = V3D(-std::sin(tt1) * std::cos(ph1), -std::sin(tt1) * std::sin(ph1),
                  1. - std::cos(tt1)); // end of trajectory
     E1 = E1 * (1. / E1.norm());       // normalize
diff --git a/Framework/MDAlgorithms/src/LoadILLAscii.cpp b/Framework/MDAlgorithms/src/LoadILLAscii.cpp
index e5cb0a709f132cdf732e78fb9f5c504e027c3954..589437c2d6779eb87385ee750fa55e59f09105de 100644
--- a/Framework/MDAlgorithms/src/LoadILLAscii.cpp
+++ b/Framework/MDAlgorithms/src/LoadILLAscii.cpp
@@ -270,7 +270,7 @@ IMDEventWorkspace_sptr LoadILLAscii::mergeWorkspaces(
     std::vector<API::MatrixWorkspace_sptr> &workspaceList) {
 
   Poco::TemporaryFile tmpFile;
-  std::string tempFileName = tmpFile.path();
+  const std::string &tempFileName = tmpFile.path();
   g_log.debug() << "Dumping WSs in a temp file: " << tempFileName << '\n';
 
   std::ofstream myfile;
diff --git a/Framework/MDAlgorithms/src/LoadMD.cpp b/Framework/MDAlgorithms/src/LoadMD.cpp
index 9ab86e6b054d38f0b219c9a51b0bfb200aba3930..1840056ee62f63d3ee6979b7c64055d338847dfa 100644
--- a/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/RegisterFileLoader.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/IMDDimensionFactory.h"
 #include "MantidGeometry/MDGeometry/MDDimensionExtents.h"
@@ -27,6 +28,7 @@
 #include <nexus/NeXusException.hpp>
 #include <boost/algorithm/string.hpp>
 #include <boost/regex.hpp>
+#include <iostream>
 #include <vector>
 
 typedef std::unique_ptr<Mantid::API::IBoxControllerIO> file_holder_type;
diff --git a/Framework/MDAlgorithms/src/LoadSQW.cpp b/Framework/MDAlgorithms/src/LoadSQW.cpp
index dcda30704a79e32fb176c27ea7f6cd0ed19b16ee..b7d88df0e6fe3ad5d9d696d310ed148596ff714b 100644
--- a/Framework/MDAlgorithms/src/LoadSQW.cpp
+++ b/Framework/MDAlgorithms/src/LoadSQW.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/WorkspaceProperty.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimensionBuilder.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidKernel/CPUTimer.h"
diff --git a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
index af8c4b43df728be47813e01d008209789402573b..d4d7a5a0733ce25e5be3fa6373bcded39537ae23 100644
--- a/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
+++ b/Framework/MDAlgorithms/src/MDNormDirectSC.cpp
@@ -3,14 +3,18 @@
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/CompositeValidator.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/VectorHelper.h"
 #include "MantidKernel/ConfigService.h"
+#include "MantidKernel/PhysicalConstants.h"
 
 namespace Mantid {
 namespace MDAlgorithms {
@@ -118,8 +122,10 @@ void MDNormDirectSC::exec() {
   cacheInputs();
   auto outputWS = binInputWS();
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
+  outputWS->setDisplayNormalization(Mantid::API::NoNormalization);
   setProperty<Workspace_sptr>("OutputWorkspace", outputWS);
   createNormalizationWS(*outputWS);
+  m_normWS->setDisplayNormalization(Mantid::API::NoNormalization);
   setProperty("OutputNormalizationWorkspace", m_normWS);
 
   // Check for other dimensions if we could measure anything in the original
@@ -437,14 +443,11 @@ void MDNormDirectSC::calculateNormalization(
   }
   const double protonCharge = exptInfoZero.run().getProtonCharge();
 
-  auto instrument = exptInfoZero.getInstrument();
-  std::vector<detid_t> detIDs = instrument->getDetectorIDs(true);
-  // Prune out those that are part of a group and simply leave the head of the
-  // group
-  detIDs = removeGroupedIDs(exptInfoZero, detIDs);
+  const SpectrumInfo spectrumInfo(exptInfoZero);
 
   // Mapping
-  const int64_t ndets = static_cast<int64_t>(detIDs.size());
+  const int64_t ndets =
+      static_cast<int64_t>(exptInfoZero.numberOfDetectorGroups());
   bool haveSA = false;
   API::MatrixWorkspace_const_sptr solidAngleWS =
       getProperty("SolidAngleWorkspace");
@@ -459,22 +462,15 @@ void MDNormDirectSC::calculateNormalization(
   for (int64_t i = 0; i < ndets; i++) {
     PARALLEL_START_INTERUPT_REGION
 
-    const auto detID = detIDs[i];
-    double theta(0.0), phi(0.0);
-    bool skip(false);
-    try {
-      auto spectrum = getThetaPhi(detID, exptInfoZero, theta, phi);
-      if (spectrum->isMonitor() || spectrum->isMasked())
-        continue;
-    } catch (
-        std::exception &) // detector might not exist or has no been included
-                          // in grouping
-    {
-      skip = true; // Intel compiler has a problem with continue inside a catch
-                   // inside openmp...
-    }
-    if (skip)
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i) ||
+        spectrumInfo.isMasked(i)) {
       continue;
+    }
+    const auto &detector = spectrumInfo.detector(i);
+    double theta = detector.getTwoTheta(m_samplePos, m_beamDir);
+    double phi = detector.getPhi();
+    // If the dtefctor is a group, this should be the ID of the first detector
+    const auto detID = detector.getID();
 
     // Intersections
     auto intersections = calculateIntersections(theta, phi);
@@ -533,64 +529,6 @@ void MDNormDirectSC::calculateNormalization(
   PARALLEL_CHECK_INTERUPT_REGION
 }
 
-/**
- * Checks for IDs that are actually part of the same group and just keeps one
- * from the group.
- * For a 1:1 map, none will be removed.
- * @param exptInfo An ExperimentInfo object that defines the grouping
- * @param detIDs A list of existing IDs
- * @return A new list of IDs
- */
-std::vector<detid_t>
-MDNormDirectSC::removeGroupedIDs(const ExperimentInfo &exptInfo,
-                                 const std::vector<detid_t> &detIDs) {
-  const size_t ntotal = detIDs.size();
-  std::vector<detid_t> singleIDs;
-  singleIDs.reserve(ntotal / 2); // reserve half. In the case of 1:1 it will
-                                 // double to the correct size once
-  std::set<detid_t> groupedIDs;
-
-  for (auto curID : detIDs) {
-    if (groupedIDs.count(curID) == 1)
-      continue; // Already been processed
-
-    try {
-      const auto &members = exptInfo.getGroupMembers(curID);
-      singleIDs.push_back(members.front());
-      std::copy(members.begin() + 1, members.end(),
-                std::inserter(groupedIDs, groupedIDs.begin()));
-    } catch (std::runtime_error &) {
-      singleIDs.push_back(curID);
-    }
-  }
-
-  g_log.debug() << "Found " << singleIDs.size() << " spectra from  "
-                << detIDs.size() << " IDs\n";
-  return singleIDs;
-}
-
-/**
- * Get the theta and phi angles for the given ID. If the detector was part of a
- * group,
- * as defined in the ExperimentInfo object, then the theta/phi are for the whole
- * set.
- * @param detID A reference to a single ID
- * @param exptInfo A reference to the ExperimentInfo that defines that
- * spectrum->detector mapping
- * @param theta [Output] Set to the theta angle for the detector (set)
- * @param phi [Output] Set to the phi angle for the detector (set)
- * @return A poiner to the Detector object for this spectrum as a whole
- *         (may be a single pixel or group)
- */
-Geometry::IDetector_const_sptr
-MDNormDirectSC::getThetaPhi(const detid_t detID, const ExperimentInfo &exptInfo,
-                            double &theta, double &phi) {
-  const auto spectrum = exptInfo.getDetectorByID(detID);
-  theta = spectrum->getTwoTheta(m_samplePos, m_beamDir);
-  phi = spectrum->getPhi();
-  return spectrum;
-}
-
 /**
  * Calculate the points of intersection for the given detector with cuboid
  * surrounding the
diff --git a/Framework/MDAlgorithms/src/MDNormSCD.cpp b/Framework/MDAlgorithms/src/MDNormSCD.cpp
index 99efceaf9c60422b9efa5850798b430cc6af508c..4d59359dfa0a8e0fa180ea11dd2dd3e05b67391d 100644
--- a/Framework/MDAlgorithms/src/MDNormSCD.cpp
+++ b/Framework/MDAlgorithms/src/MDNormSCD.cpp
@@ -3,12 +3,16 @@
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/CompositeValidator.h"
+#include "MantidKernel/ConfigService.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/VectorHelper.h"
 
@@ -113,8 +117,10 @@ void MDNormSCD::exec() {
   cacheInputs();
   auto outputWS = binInputWS();
   convention = Kernel::ConfigService::Instance().getString("Q.convention");
+  outputWS->setDisplayNormalization(Mantid::API::NoNormalization);
   setProperty<Workspace_sptr>("OutputWorkspace", outputWS);
   createNormalizationWS(*outputWS);
+  m_normWS->setDisplayNormalization(Mantid::API::NoNormalization);
   setProperty("OutputNormalizationWorkspace", m_normWS);
 
   // Check for other dimensions if we could measure anything in the original
@@ -387,14 +393,11 @@ void MDNormSCD::calculateNormalization(
   }
   const double protonCharge = exptInfoZero.run().getProtonCharge();
 
-  auto instrument = exptInfoZero.getInstrument();
-  std::vector<detid_t> detIDs = instrument->getDetectorIDs(true);
-  // Prune out those that are part of a group and simply leave the head of the
-  // group
-  detIDs = removeGroupedIDs(exptInfoZero, detIDs);
+  const SpectrumInfo spectrumInfo(exptInfoZero);
 
   // Mappings
-  const int64_t ndets = static_cast<int64_t>(detIDs.size());
+  const int64_t ndets =
+      static_cast<int64_t>(exptInfoZero.numberOfDetectorGroups());
   const detid2index_map fluxDetToIdx =
       integrFlux->getDetectorIDToWorkspaceIndexMap();
   const detid2index_map solidAngDetToIdx =
@@ -405,22 +408,15 @@ void MDNormSCD::calculateNormalization(
   for (int64_t i = 0; i < ndets; i++) {
     PARALLEL_START_INTERUPT_REGION
 
-    const auto detID = detIDs[i];
-    double theta(0.0), phi(0.0);
-    bool skip(false);
-    try {
-      auto spectrum = getThetaPhi(detID, exptInfoZero, theta, phi);
-      if (spectrum->isMonitor() || spectrum->isMasked())
-        continue;
-    } catch (
-        std::exception &) // detector might not exist or has no been included
-                          // in grouping
-    {
-      skip = true; // Intel compiler has a problem with continue inside a catch
-                   // inside openmp...
-    }
-    if (skip)
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i) ||
+        spectrumInfo.isMasked(i)) {
       continue;
+    }
+    const auto &detector = spectrumInfo.detector(i);
+    double theta = detector.getTwoTheta(m_samplePos, m_beamDir);
+    double phi = detector.getPhi();
+    // If the dtefctor is a group, this should be the ID of the first detector
+    const auto detID = detector.getID();
 
     // Intersections
     auto intersections = calculateIntersections(theta, phi);
@@ -570,64 +566,6 @@ void MDNormSCD::calcIntegralsForIntersections(
   }
 }
 
-/**
- * Checks for IDs that are actually part of the same group and just keeps one
- * from the group.
- * For a 1:1 map, none will be removed.
- * @param exptInfo An ExperimentInfo object that defines the grouping
- * @param detIDs A list of existing IDs
- * @return A new list of IDs
- */
-std::vector<detid_t>
-MDNormSCD::removeGroupedIDs(const ExperimentInfo &exptInfo,
-                            const std::vector<detid_t> &detIDs) {
-  const size_t ntotal = detIDs.size();
-  std::vector<detid_t> singleIDs;
-  singleIDs.reserve(ntotal / 2); // reserve half. In the case of 1:1 it will
-                                 // double to the correct size once
-  std::set<detid_t> groupedIDs;
-
-  for (auto curID : detIDs) {
-    if (groupedIDs.count(curID) == 1)
-      continue; // Already been processed
-
-    try {
-      const auto &members = exptInfo.getGroupMembers(curID);
-      singleIDs.push_back(members.front());
-      std::copy(members.begin() + 1, members.end(),
-                std::inserter(groupedIDs, groupedIDs.begin()));
-    } catch (std::runtime_error &) {
-      singleIDs.push_back(curID);
-    }
-  }
-
-  g_log.debug() << "Found " << singleIDs.size() << " spectra from  "
-                << detIDs.size() << " IDs\n";
-  return singleIDs;
-}
-
-/**
- * Get the theta and phi angles for the given ID. If the detector was part of a
- * group,
- * as defined in the ExperimentInfo object, then the theta/phi are for the whole
- * set.
- * @param detID A reference to a single ID
- * @param exptInfo A reference to the ExperimentInfo that defines that
- * spectrum->detector mapping
- * @param theta [Output] Set to the theta angle for the detector (set)
- * @param phi [Output] Set to the phi angle for the detector (set)
- * @return A poiner to the Detector object for this spectrum as a whole
- *         (may be a single pixel or group)
- */
-Geometry::IDetector_const_sptr
-MDNormSCD::getThetaPhi(const detid_t detID, const ExperimentInfo &exptInfo,
-                       double &theta, double &phi) {
-  const auto spectrum = exptInfo.getDetectorByID(detID);
-  theta = spectrum->getTwoTheta(m_samplePos, m_beamDir);
-  phi = spectrum->getPhi();
-  return spectrum;
-}
-
 /**
  * Calculate the points of intersection for the given detector with cuboid
  * surrounding the
diff --git a/Framework/MDAlgorithms/src/MDWSDescription.cpp b/Framework/MDAlgorithms/src/MDWSDescription.cpp
index 442c5a2070a8522be22a5fb6582039fc707a2563..5c638c4b3925d6d24558de1e2a5dce19cffa72f5 100644
--- a/Framework/MDAlgorithms/src/MDWSDescription.cpp
+++ b/Framework/MDAlgorithms/src/MDWSDescription.cpp
@@ -11,6 +11,7 @@
 
 #include "MantidMDAlgorithms/MDTransfFactory.h"
 #include "MantidGeometry/MDGeometry/MDFrameFactory.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -321,7 +322,7 @@ void MDWSDescription::getMinMax(std::vector<double> &min,
 /** Method checks if the workspace is expected to be processed in powder mode */
 bool MDWSDescription::isPowder() const {
   return (this->AlgID == "|Q|") ||
-         (this->AlgID.size() == 0 && !m_InWS->sample().hasOrientedLattice());
+         (this->AlgID.empty() && !m_InWS->sample().hasOrientedLattice());
 }
 
 /** Returns symbolic representation of current Emode */
diff --git a/Framework/MDAlgorithms/src/MDWSTransform.cpp b/Framework/MDAlgorithms/src/MDWSTransform.cpp
index 8c3ed24ff0065754c5bf6ca3329702e81267934f..441fa7c6324e151be2dc4888bb12eea5cc6c9a85 100644
--- a/Framework/MDAlgorithms/src/MDWSTransform.cpp
+++ b/Framework/MDAlgorithms/src/MDWSTransform.cpp
@@ -6,6 +6,7 @@
 #include "MantidGeometry/MDGeometry/QLab.h"
 #include "MantidGeometry/MDGeometry/QSample.h"
 #include "MantidKernel/MDUnit.h"
+#include "MantidKernel/Tolerance.h"
 
 #include <cfloat>
 
diff --git a/Framework/MDAlgorithms/src/MergeMD.cpp b/Framework/MDAlgorithms/src/MergeMD.cpp
index bdcfb08fa19f636f73065f4945c8238fa8ec51f4..9359273e58f90fb53f2381f46a335ad3c6b21117 100644
--- a/Framework/MDAlgorithms/src/MergeMD.cpp
+++ b/Framework/MDAlgorithms/src/MergeMD.cpp
@@ -4,6 +4,8 @@
 #include "MantidDataObjects/MDBoxIterator.h"
 #include "MantidKernel/CPUTimer.h"
 #include "MantidKernel/MandatoryValidator.h"
+#include "MantidKernel/Strings.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
@@ -16,7 +18,6 @@ namespace MDAlgorithms {
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(MergeMD)
 
-//----------------------------------------------------------------------------------------------
 /// Algorithm's name for identification. @see Algorithm::name
 const std::string MergeMD::name() const { return "MergeMD"; }
 
@@ -26,9 +27,6 @@ int MergeMD::version() const { return 1; }
 /// Algorithm's category for identification. @see Algorithm::category
 const std::string MergeMD::category() const { return "MDAlgorithms\\Creation"; }
 
-//----------------------------------------------------------------------------------------------
-
-//----------------------------------------------------------------------------------------------
 /** Initialize the algorithm's properties.
  */
 void MergeMD::init() {
@@ -48,7 +46,6 @@ void MergeMD::init() {
   this->initBoxControllerProps("2", 500, 16);
 }
 
-//----------------------------------------------------------------------------------------------
 /** Create the output MDWorkspace from a list of input
  *
  * @param inputs :: list of names of input MDWorkspaces
@@ -162,11 +159,10 @@ void MergeMD::createOutputWorkspace(std::vector<std::string> &inputs) {
  * @param ws ::  MDEventWorkspace to clone
  */
 template <typename MDE, size_t nd>
-void MergeMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws) {
+void MergeMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws2) {
   // CPUTimer tim;
   typename MDEventWorkspace<MDE, nd>::sptr ws1 =
       boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(out);
-  typename MDEventWorkspace<MDE, nd>::sptr ws2 = ws;
   if (!ws1 || !ws2)
     throw std::runtime_error("Incompatible workspace types passed to MergeMD.");
 
diff --git a/Framework/MDAlgorithms/src/MinusMD.cpp b/Framework/MDAlgorithms/src/MinusMD.cpp
index 91d846e94bfed80b43ee710483bdbad9ba71188f..c0c2cb8e91ac001e301bb50730f765f7f7d4a0fb 100644
--- a/Framework/MDAlgorithms/src/MinusMD.cpp
+++ b/Framework/MDAlgorithms/src/MinusMD.cpp
@@ -51,8 +51,7 @@ void MinusMD::checkInputs() {
  * @param ws ::  MDEventWorkspace being added to
  */
 template <typename MDE, size_t nd>
-void MinusMD::doMinus(typename MDEventWorkspace<MDE, nd>::sptr ws) {
-  typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
+void MinusMD::doMinus(typename MDEventWorkspace<MDE, nd>::sptr ws1) {
   typename MDEventWorkspace<MDE, nd>::sptr ws2 =
       boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(m_operand_event);
   if (!ws1 || !ws2)
diff --git a/Framework/MDAlgorithms/src/PlusMD.cpp b/Framework/MDAlgorithms/src/PlusMD.cpp
index 3beb2ec6044ae32e080b86d1f3b56831c9c054f1..1fbe4b1d6b00551f2cdaa3e45e25a33fc06f007e 100644
--- a/Framework/MDAlgorithms/src/PlusMD.cpp
+++ b/Framework/MDAlgorithms/src/PlusMD.cpp
@@ -25,8 +25,7 @@ DECLARE_ALGORITHM(PlusMD)
  * @param ws ::  MDEventWorkspace being added to
  */
 template <typename MDE, size_t nd>
-void PlusMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws) {
-  typename MDEventWorkspace<MDE, nd>::sptr ws1 = ws;
+void PlusMD::doPlus(typename MDEventWorkspace<MDE, nd>::sptr ws1) {
   typename MDEventWorkspace<MDE, nd>::sptr ws2 =
       boost::dynamic_pointer_cast<MDEventWorkspace<MDE, nd>>(m_operand_event);
   if (!ws1 || !ws2)
diff --git a/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp b/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp
index 20d9ba263b34ce4871f08399f388b23d070e7f15..f934df1598b7cdfe7ce7f7310d48f5234b9f8450 100644
--- a/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp
+++ b/Framework/MDAlgorithms/src/PreprocessDetectorsToMD.cpp
@@ -1,8 +1,10 @@
 #include "MantidMDAlgorithms/PreprocessDetectorsToMD.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/InstrumentValidator.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/PropertyWithValue.h"
@@ -241,6 +243,7 @@ void PreprocessDetectorsToMD::processDetectorsPositions(
   Mantid::API::Progress theProgress(this, 0, 1, nHist);
   //// Loop over the spectra
   uint32_t liveDetectorsCount(0);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (size_t i = 0; i < nHist; i++) {
     sp2detMap[i] = std::numeric_limits<uint64_t>::quiet_NaN();
     detId[i] = std::numeric_limits<int32_t>::quiet_NaN();
@@ -250,33 +253,26 @@ void PreprocessDetectorsToMD::processDetectorsPositions(
     Azimuthal[i] = std::numeric_limits<double>::quiet_NaN();
     //     detMask[i]  = true;
 
-    // get detector or detector group which corresponds to the spectra i
-    Geometry::IDetector_const_sptr spDet;
-    try {
-      spDet = inputWS->getDetector(i);
-    } catch (Kernel::Exception::NotFoundError &) {
-      continue;
-    }
-
-    // Check that we aren't dealing with monitor...
-    if (spDet->isMonitor())
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
       continue;
 
     // if masked detectors state is not used, masked detectors just ignored;
-    bool maskDetector = spDet->isMasked();
+    bool maskDetector = spectrumInfo.isMasked(i);
     if (m_getIsMasked)
       *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;
     else if (maskDetector)
       continue;
 
+    const auto &spDet = spectrumInfo.detector(i);
+
     // calculate the requested values;
     sp2detMap[i] = liveDetectorsCount;
-    detId[liveDetectorsCount] = int32_t(spDet->getID());
+    detId[liveDetectorsCount] = int32_t(spDet.getID());
     detIDMap[liveDetectorsCount] = i;
-    L2[liveDetectorsCount] = spDet->getDistance(*sample);
+    L2[liveDetectorsCount] = spectrumInfo.l2(i);
 
-    double polar = inputWS->detectorTwoTheta(*spDet);
-    double azim = spDet->getPhi();
+    double polar = spectrumInfo.twoTheta(i);
+    double azim = spDet.getPhi();
     TwoTheta[liveDetectorsCount] = polar;
     Azimuthal[liveDetectorsCount] = azim;
 
@@ -297,7 +293,7 @@ void PreprocessDetectorsToMD::processDetectorsPositions(
     // defined;
     if (pEfixedArray) {
       try {
-        Geometry::Parameter_sptr par = pmap.getRecursive(spDet.get(), "eFixed");
+        Geometry::Parameter_sptr par = pmap.getRecursive(&spDet, "eFixed");
         if (par)
           Efi = par->value<double>();
       } catch (std::runtime_error &) {
@@ -340,21 +336,13 @@ void PreprocessDetectorsToMD::updateMasksState(
         " are inconsistent as have different numner of detectors");
 
   uint32_t liveDetectorsCount(0);
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   for (size_t i = 0; i < nHist; i++) {
-    // get detector or detector group which corresponds to the spectra i
-    Geometry::IDetector_const_sptr spDet;
-    try {
-      spDet = inputWS->getDetector(i);
-    } catch (Kernel::Exception::NotFoundError &) {
-      continue;
-    }
-
-    // Check that we aren't dealing with monitor...
-    if (spDet->isMonitor())
+    if (!spectrumInfo.hasDetectors(i) || spectrumInfo.isMonitor(i))
       continue;
 
     // if masked detectors state is not used, masked detectors just ignored;
-    bool maskDetector = spDet->isMasked();
+    bool maskDetector = spectrumInfo.isMasked(i);
     *(pMasksArray + liveDetectorsCount) = maskDetector ? 1 : 0;
 
     liveDetectorsCount++;
diff --git a/Framework/MDAlgorithms/src/Quantification/Resolution/ModeratorChopperResolution.cpp b/Framework/MDAlgorithms/src/Quantification/Resolution/ModeratorChopperResolution.cpp
index e2d8d70fd70985d1eb25ad30af4bf689b60c4648..58f2358db5f31caa605201b3f4574735fdb0f43b 100644
--- a/Framework/MDAlgorithms/src/Quantification/Resolution/ModeratorChopperResolution.cpp
+++ b/Framework/MDAlgorithms/src/Quantification/Resolution/ModeratorChopperResolution.cpp
@@ -1,4 +1,3 @@
-// Includes
 #include "MantidMDAlgorithms/Quantification/Resolution/ModeratorChopperResolution.h"
 #include "MantidMDAlgorithms/Quantification/CachedExperimentInfo.h"
 
@@ -6,6 +5,7 @@
 #include "MantidAPI/ChopperModel.h"
 #include "MantidAPI/ModeratorModel.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidKernel/PhysicalConstants.h"
 
 namespace Mantid {
 namespace MDAlgorithms {
diff --git a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
index f550a26f303e0ced7257b84777620d96a66be572..6f7c4c4b8b86889f8cc95e5719199573399934d1 100644
--- a/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
+++ b/Framework/MDAlgorithms/src/QueryMDWorkspace.cpp
@@ -9,6 +9,7 @@
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidKernel/EnabledWhenProperty.h"
 #include "MantidKernel/ListValidator.h"
+#include "MantidKernel/Strings.h"
 
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
diff --git a/Framework/MDAlgorithms/src/SaveMD.cpp b/Framework/MDAlgorithms/src/SaveMD.cpp
index 4d5c6a22fa55efbb2fb92a96f1b7c3c01c31e0e1..a547ff5dbcb27706f273a1ef9f2fc1dec717b8ed 100644
--- a/Framework/MDAlgorithms/src/SaveMD.cpp
+++ b/Framework/MDAlgorithms/src/SaveMD.cpp
@@ -1,7 +1,9 @@
 #include "MantidAPI/CoordTransform.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/Matrix.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidDataObjects/MDBoxIterator.h"
 #include "MantidDataObjects/MDEventFactory.h"
diff --git a/Framework/MDAlgorithms/src/SaveMD2.cpp b/Framework/MDAlgorithms/src/SaveMD2.cpp
index 9a99a554f247c2fe7250b168d7486eae4e9c0507..22fb267dc2c8278a41480ae911ce906e6fefd0a7 100644
--- a/Framework/MDAlgorithms/src/SaveMD2.cpp
+++ b/Framework/MDAlgorithms/src/SaveMD2.cpp
@@ -1,7 +1,9 @@
 #include "MantidAPI/CoordTransform.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidKernel/Matrix.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidDataObjects/MDBoxIterator.h"
 #include "MantidDataObjects/MDEventFactory.h"
diff --git a/Framework/MDAlgorithms/src/SaveZODS.cpp b/Framework/MDAlgorithms/src/SaveZODS.cpp
index 495b4d8fd9b8139c968de5cd6fefbef25e5f5402..c96478ff4597d16d9ca6fc3fad861e9601c700b7 100644
--- a/Framework/MDAlgorithms/src/SaveZODS.cpp
+++ b/Framework/MDAlgorithms/src/SaveZODS.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/Sample.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/System.h"
 #include "MantidMDAlgorithms/SaveZODS.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
diff --git a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
index 05d6ee29d070ee276d31ccd2334ce312d75661d1..d0f50931975c02fbf4e536eda7ef6bd143f9683b 100644
--- a/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
+++ b/Framework/MDAlgorithms/src/SlicingAlgorithm.cpp
@@ -177,7 +177,7 @@ void SlicingAlgorithm::makeBasisVectorFromString(const std::string &str) {
 
   // Get the entire name
   std::string name = Strings::strip(input.substr(0, n_first_comma));
-  if (name.size() == 0)
+  if (name.empty())
     throw std::invalid_argument("name should not be blank.");
 
   // Now remove the name and comma
@@ -251,20 +251,19 @@ void SlicingAlgorithm::makeBasisVectorFromString(const std::string &str) {
   double binningScaling = double(numBins) / (lengthInInput);
 
   // Extract the arguments
-  std::string id = name;
   std::string units = Strings::strip(strs[0]);
 
   // Create the appropriate frame
   auto frame = createMDFrameForNonAxisAligned(units, basis);
 
   // Create the output dimension
-  MDHistoDimension_sptr out(
-      new MDHistoDimension(name, id, *frame, static_cast<coord_t>(min),
-                           static_cast<coord_t>(max), numBins));
+  auto out = boost::make_shared<MDHistoDimension>(
+      name, name, *frame, static_cast<coord_t>(min), static_cast<coord_t>(max),
+      numBins);
 
   // Put both in the algo for future use
   m_bases.push_back(basis);
-  m_binDimensions.push_back(out);
+  m_binDimensions.push_back(std::move(out));
   m_binningScaling.push_back(binningScaling);
   m_transformScaling.push_back(transformScaling);
 }
@@ -430,8 +429,7 @@ void SlicingAlgorithm::createGeneralTransform() {
   if (m_outD == inD) {
     // Can't reverse transform if you lost dimensions.
     auto ctTo = new DataObjects::CoordTransformAffine(inD, m_outD);
-    Matrix<coord_t> fromMatrix = ctFrom->getMatrix();
-    Matrix<coord_t> toMatrix = fromMatrix;
+    Matrix<coord_t> toMatrix = ctFrom->getMatrix();
     // Invert the affine matrix to get the reverse transformation
     toMatrix.Invert();
     ctTo->setMatrix(toMatrix);
@@ -490,7 +488,7 @@ void SlicingAlgorithm::makeAlignedDimensionFromString(const std::string &str) {
     Strings::convert(strs[0], min);
     Strings::convert(strs[1], max);
     Strings::convert(strs[2], numBins);
-    if (name.size() == 0)
+    if (name.empty())
       throw std::invalid_argument("Name should not be blank.");
     if (min >= max)
       throw std::invalid_argument("Min should be > max.");
diff --git a/Framework/MDAlgorithms/src/TransformMD.cpp b/Framework/MDAlgorithms/src/TransformMD.cpp
index f45c06b8905a9e0f14a65463b11d12876b1132d7..1ab5a51281d655b2f6df47e376e15431b6122ae0 100644
--- a/Framework/MDAlgorithms/src/TransformMD.cpp
+++ b/Framework/MDAlgorithms/src/TransformMD.cpp
@@ -2,6 +2,7 @@
 #include "MantidKernel/System.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidDataObjects/MDEventFactory.h"
diff --git a/Framework/MDAlgorithms/test/AccumulateMDTest.h b/Framework/MDAlgorithms/test/AccumulateMDTest.h
index a92680b2e974dd347d62ca91d7430a4080393480..eb145a00780c6f1818966aceb4d8221bca1ddf06 100644
--- a/Framework/MDAlgorithms/test/AccumulateMDTest.h
+++ b/Framework/MDAlgorithms/test/AccumulateMDTest.h
@@ -98,7 +98,7 @@ public:
 
     // Create a cheap workspace
     std::string ws_name = "ACCUMULATEMDTEST_EXISTENTWORKSPACE";
-    auto bkg_ws = WorkspaceCreationHelper::Create1DWorkspaceRand(1);
+    auto bkg_ws = WorkspaceCreationHelper::create1DWorkspaceRand(1);
     // add to ADS (no choice but to use ADS here)
     AnalysisDataService::Instance().add(ws_name, bkg_ws);
 
diff --git a/Framework/MDAlgorithms/test/BinaryOperationMDTest.h b/Framework/MDAlgorithms/test/BinaryOperationMDTest.h
index f1b857f6999a86e5db568872f88d1bf38d3aa20c..eef27e2ee8c0fad55df02a2a20bd72d4f3e4462a 100644
--- a/Framework/MDAlgorithms/test/BinaryOperationMDTest.h
+++ b/Framework/MDAlgorithms/test/BinaryOperationMDTest.h
@@ -65,7 +65,7 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3, 5, 10.0, 1.0);
     event_A = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
     event_B = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
-    scalar = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.5);
+    scalar = WorkspaceCreationHelper::createWorkspaceSingleValue(2.5);
     AnalysisDataService::Instance().addOrReplace("histo_A", histo_A);
     AnalysisDataService::Instance().addOrReplace("histo_B", histo_B);
     AnalysisDataService::Instance().addOrReplace("histo2d_100", histo2d_100);
diff --git a/Framework/MDAlgorithms/test/CalculateCoverageDGSTest.h b/Framework/MDAlgorithms/test/CalculateCoverageDGSTest.h
index 3fecfe997cae2a827423dc8bcccf5d27abc12ef2..cce9d3b1979a916d97a6d6f055207391246553be 100644
--- a/Framework/MDAlgorithms/test/CalculateCoverageDGSTest.h
+++ b/Framework/MDAlgorithms/test/CalculateCoverageDGSTest.h
@@ -44,7 +44,7 @@ public:
     std::string outWSName("CalculateCoverageDGSTest_OutputWS"),
         inputWSName("CalculateCoverageDGSTest_InputWS");
     MatrixWorkspace_sptr inputWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+        WorkspaceCreationHelper::create2DWorkspace(1, 1);
     std::vector<V3D> detectorPositions{{1, 1, 1}};
     V3D sampPos(0., 0., 0.), sourcePos(0, 0, -1.);
     WorkspaceCreationHelper::createInstrumentForWorkspaceWithDistances(
diff --git a/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
index eb046c21c3b1ff4620b5dc8625111f5578d5c24e..20cc3c1e71d4af2a93c79713f6767ca8980bbc78 100644
--- a/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
+++ b/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidMDAlgorithms/ConvertCWPDMDToSpectra.h"
 #include "MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
index 2c12b9bf3626246484e7133ce41b3eebe59d999e..f4d1d2d243bd2d0d039246d3093a80b6625114a9 100644
--- a/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
+++ b/Framework/MDAlgorithms/test/ConvertCWSDExpToMomentumTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidMDAlgorithms/ConvertCWSDExpToMomentum.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidDataObjects/TableWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/ConvertEventsToMDTest.h b/Framework/MDAlgorithms/test/ConvertEventsToMDTest.h
index 12d0396783372586ff2da57c57f51739167e879a..f98c98e79a8b40d55a88d23dc599b5a50dfdff08 100644
--- a/Framework/MDAlgorithms/test/ConvertEventsToMDTest.h
+++ b/Framework/MDAlgorithms/test/ConvertEventsToMDTest.h
@@ -74,7 +74,7 @@ public:
     int numHist = 10;
     Mantid::API::MatrixWorkspace_sptr wsEv =
         boost::dynamic_pointer_cast<MatrixWorkspace>(
-            WorkspaceCreationHelper::CreateRandomEventWorkspace(100, numHist,
+            WorkspaceCreationHelper::createRandomEventWorkspace(100, numHist,
                                                                 0.1));
     wsEv->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(numHist));
diff --git a/Framework/MDAlgorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h b/Framework/MDAlgorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h
index ae6baa36487e8434c0322a1273bb102baa055c43..5015e2cd5b18188243a967915f341d35c5a07e69 100644
--- a/Framework/MDAlgorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/ConvertMDHistoToMatrixWorkspaceTest.h
@@ -138,7 +138,7 @@ public:
 public:
   void test_input_workspace_must_be_imdhisto() {
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(1, 1, 0);
+        WorkspaceCreationHelper::create1DWorkspaceConstant(1, 1, 0);
     ConvertMDHistoToMatrixWorkspace alg;
     alg.setRethrows(true);
     alg.initialize();
diff --git a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
index 5ed79dddd957c0a646c4a8c6f1e784c97109acb8..c9956ef5d6c958a1a371d48ff2e3bb476eba7ca7 100644
--- a/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
+++ b/Framework/MDAlgorithms/test/ConvertSpiceDataToRealSpaceTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDIterator.h"
 #include "MantidAPI/ITableWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h b/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
index 3ef04716e3125c55402befb3c0d6809be3b0bf08..65ff6bd5aa8a4b5a81e690252fb2ced6bd8631cc 100644
--- a/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToMDComponentsTest.h
@@ -3,6 +3,8 @@
 // tests for different parts of ConvertToMD exec functions
 
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/SpectrumInfo.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/ConvertToMD.h"
 #include "MantidMDAlgorithms/MDWSTransform.h"
 #include "MantidTestHelpers/ComponentCreationHelper.h"
@@ -342,9 +344,10 @@ public:
       // detectorList.push_back(spDet->getID());
     }
 
-    std::vector<size_t>::const_iterator wit;
-    for (wit = indexLis.begin(); wit != indexLis.end(); ++wit) {
-      inputWS->maskWorkspaceIndex(*wit);
+    auto &spectrumInfo = inputWS->mutableSpectrumInfo();
+    for (const auto i : indexLis) {
+      inputWS->getSpectrum(i).clearData();
+      spectrumInfo.setMasked(i, true);
     }
   }
 };
diff --git a/Framework/MDAlgorithms/test/ConvertToMDMinMaxGlobalTest.h b/Framework/MDAlgorithms/test/ConvertToMDMinMaxGlobalTest.h
index 3329bddbebea70012b3d425ef0c8461bdadf2900..383395ba770910335d63f555b3a0b8446e6aff07 100644
--- a/Framework/MDAlgorithms/test/ConvertToMDMinMaxGlobalTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToMDMinMaxGlobalTest.h
@@ -182,7 +182,7 @@ private:
                                                   double Ef) {
 
     Mantid::API::MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 100, xmin, dx);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 100, xmin, dx);
 
     if ((Ei > 0 || Ef > 0) && deltaEUnits) {
       ws->getAxis(0)->setUnit("DeltaE");
@@ -192,7 +192,6 @@ private:
 
     Mantid::Geometry::Instrument_sptr testInst(
         new Mantid::Geometry::Instrument);
-    ws->setInstrument(testInst);
     // Define a source and sample position
     // Define a source component
     Mantid::Geometry::ObjComponent *source = new Mantid::Geometry::ObjComponent(
@@ -212,6 +211,7 @@ private:
     physicalPixel->setPos(0.5, 0, 5.0);
     testInst->add(physicalPixel);
     testInst->markAsDetector(physicalPixel);
+    ws->setInstrument(testInst);
 
     ws->getSpectrum(0).addDetectorID(physicalPixel->getID());
 
@@ -221,9 +221,8 @@ private:
     }
 
     if (Ef > 0) {
-      Mantid::Geometry::ParameterMap pmap(ws->instrumentParameters());
+      auto &pmap = ws->instrumentParameters();
       pmap.addDouble(physicalPixel, "Efixed", Ef);
-      ws->replaceInstrumentParameters(pmap);
     }
     Mantid::Geometry::OrientedLattice latt(2, 3, 4, 90, 90, 90);
     ws->mutableSample().setOrientedLattice(&latt);
diff --git a/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h b/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h
index 4b4fa3d45001d4f685a146e7933b0003824a3340..a44301f6cfcccc4958fab660a9541038e934bbca 100644
--- a/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToMDMinMaxLocalTest.h
@@ -202,7 +202,7 @@ private:
                                                   double Ef) {
 
     Mantid::API::MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(1, 100, xmin, dx);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(1, 100, xmin, dx);
 
     if ((Ei > 0 || Ef > 0) && deltaEUnits) {
       ws->getAxis(0)->setUnit("DeltaE");
@@ -212,7 +212,6 @@ private:
 
     Mantid::Geometry::Instrument_sptr testInst(
         new Mantid::Geometry::Instrument);
-    ws->setInstrument(testInst);
     // Define a source and sample position
     // Define a source component
     Mantid::Geometry::ObjComponent *source = new Mantid::Geometry::ObjComponent(
@@ -232,6 +231,7 @@ private:
     physicalPixel->setPos(0.5, 0, 5.0);
     testInst->add(physicalPixel);
     testInst->markAsDetector(physicalPixel);
+    ws->setInstrument(testInst);
 
     ws->getSpectrum(0).addDetectorID(physicalPixel->getID());
 
@@ -240,11 +240,6 @@ private:
           new Mantid::Kernel::PropertyWithValue<double>("Ei", Ei));
     }
 
-    if (Ef > 0) {
-      Mantid::Geometry::ParameterMap pmap(ws->instrumentParameters());
-      pmap.addDouble(physicalPixel, "Efixed", Ef);
-      ws->replaceInstrumentParameters(pmap);
-    }
     Mantid::Geometry::OrientedLattice latt(2, 3, 4, 90, 90, 90);
     ws->mutableSample().setOrientedLattice(&latt);
 
diff --git a/Framework/MDAlgorithms/test/ConvertToMDTest.h b/Framework/MDAlgorithms/test/ConvertToMDTest.h
index 7adc9502125f931e4b1c716084003899b885adad..0ce60001178a404db8bc797ff0059775577b0d29 100644
--- a/Framework/MDAlgorithms/test/ConvertToMDTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToMDTest.h
@@ -2,6 +2,7 @@
 #define MANTID_MD_CONVERT2_Q_NDANY_TEST_H_
 
 #include "MantidAPI/BoxController.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/ConvertToMD.h"
 #include "MantidMDAlgorithms/ConvToMDSelector.h"
 #include "MantidMDAlgorithms/PreprocessDetectorsToMD.h"
@@ -730,7 +731,7 @@ public:
     numHist = 100 * 100;
     size_t nEvents = 1000;
     inWsEv = boost::dynamic_pointer_cast<MatrixWorkspace>(
-        WorkspaceCreationHelper::CreateRandomEventWorkspace(nEvents, numHist,
+        WorkspaceCreationHelper::createRandomEventWorkspace(nEvents, numHist,
                                                             0.1));
     inWsEv->setInstrument(
         ComponentCreationHelper::createTestInstrumentCylindrical(int(numHist)));
diff --git a/Framework/MDAlgorithms/test/ConvertToQ3DdETest.h b/Framework/MDAlgorithms/test/ConvertToQ3DdETest.h
index d87f587291bb36b6132eaad1b9d4f53c5fe511b7..00a48fb04ec7b2f9295f5f388fc2d6b3f474caa0 100644
--- a/Framework/MDAlgorithms/test/ConvertToQ3DdETest.h
+++ b/Framework/MDAlgorithms/test/ConvertToQ3DdETest.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/Sample.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidMDAlgorithms/ConvertToMD.h"
 #include "MantidMDAlgorithms/MDWSDescription.h"
@@ -39,7 +40,7 @@ public:
 
   void testExecThrow() {
     Mantid::API::MatrixWorkspace_sptr ws2D =
-        WorkspaceCreationHelper::CreateGroupedWorkspace2DWithRingsAndBoxes();
+        WorkspaceCreationHelper::createGroupedWorkspace2DWithRingsAndBoxes();
 
     AnalysisDataService::Instance().addOrReplace("testWSProcessed", ws2D);
 
diff --git a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
index 2bee175de5b0acacc481fa2d938cee0bcbfc86ca..5f44b55e93d9b9bb4cd01fa0cca8884624f1492c 100644
--- a/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
+++ b/Framework/MDAlgorithms/test/ConvertToReflectometryQTest.h
@@ -9,6 +9,7 @@
 #include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidKernel/PropertyWithValue.h"
+#include "MantidKernel/Unit.h"
 #include "MantidMDAlgorithms/ConvertToReflectometryQ.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidDataObjects/Workspace2D.h"
diff --git a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
index f08d607958349741cedbfb131289c930734e4449..85d0af7844fe4fe774bbe9617ad039a1dea2693a 100644
--- a/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/CreateMDHistoWorkspaceTest.h
@@ -6,6 +6,7 @@
 #include "MantidKernel/System.h"
 #include "MantidGeometry/MDGeometry/QSample.h"
 #include "MantidGeometry/MDGeometry/GeneralFrame.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidMDAlgorithms/CreateMDHistoWorkspace.h"
 
 using namespace Mantid;
diff --git a/Framework/MDAlgorithms/test/CreateMDTest.h b/Framework/MDAlgorithms/test/CreateMDTest.h
index aa9625455b3e360be9b3311be93b71914baeec9f..96a5d73e84a81f16e0d980b587554f28a2fde8fa 100644
--- a/Framework/MDAlgorithms/test/CreateMDTest.h
+++ b/Framework/MDAlgorithms/test/CreateMDTest.h
@@ -61,7 +61,7 @@ public:
   }
 
   void test_psi_right_size() {
-    auto sample_ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto sample_ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     Mantid::API::AnalysisDataService::Instance().add("__CreateMDTest_sample",
                                                      sample_ws);
 
@@ -87,7 +87,7 @@ public:
   }
 
   void test_gl_right_size() {
-    auto sample_ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto sample_ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     Mantid::API::AnalysisDataService::Instance().add("__CreateMDTest_sample",
                                                      sample_ws);
 
@@ -113,7 +113,7 @@ public:
   }
 
   void test_gs_right_size() {
-    auto sample_ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto sample_ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     Mantid::API::AnalysisDataService::Instance().add("__CreateMDTest_sample",
                                                      sample_ws);
 
@@ -251,4 +251,4 @@ public:
   }
 };
 
-#endif /* MANTID_MDALGORITHMS_CREATEMDTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_MDALGORITHMS_CREATEMDTEST_H_ */
diff --git a/Framework/MDAlgorithms/test/CreateMDWorkspaceTest.h b/Framework/MDAlgorithms/test/CreateMDWorkspaceTest.h
index 94effdd105ff973de8968181706567d10058bbb9..2c3eddaf229a169c4f8dd2936165df7832c30699 100644
--- a/Framework/MDAlgorithms/test/CreateMDWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/CreateMDWorkspaceTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_MDEVENTS_CREATEMDEVENTWORKSPACETEST_H_
 #define MANTID_MDEVENTS_CREATEMDEVENTWORKSPACETEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidMDAlgorithms/CreateMDWorkspace.h"
 #include "MantidGeometry/MDGeometry/QSample.h"
@@ -10,12 +11,6 @@
 
 #include <Poco/File.h>
 
-//#include "MantidAPI/AnalysisDataService.h"
-//#include "MantidAPI/IMDEventWorkspace.h"
-//#include "MantidKernel/System.h"
-//#include "MantidKernel/Timer.h"
-//#include "MantidDataObjects/MDEventFactory.h"
-
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 using namespace Mantid::Geometry;
diff --git a/Framework/MDAlgorithms/test/DisplayNormalizationSetterTest.h b/Framework/MDAlgorithms/test/DisplayNormalizationSetterTest.h
index a43bf6041bbba8f17e7e2a2f0f9b394c99ee32f9..afcf4618d272fdb98316e2f046dcedbe4fe5d42d 100644
--- a/Framework/MDAlgorithms/test/DisplayNormalizationSetterTest.h
+++ b/Framework/MDAlgorithms/test/DisplayNormalizationSetterTest.h
@@ -15,7 +15,7 @@ public:
     // Arrange
     auto isQ = true;
     auto eventWorkspace =
-        WorkspaceCreationHelper::CreateEventWorkspace2(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace2(10, 10);
     auto mdHistoWorkspace =
         Mantid::DataObjects::MDEventsTestHelper::makeFakeMDHistoWorkspace(
             1.0, 1, 10);
@@ -31,7 +31,7 @@ public:
     // Arrange
     auto isQ = true;
     auto eventWorkspace =
-        WorkspaceCreationHelper::CreateEventWorkspace2(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace2(10, 10);
     auto mdEventWorkspace =
         Mantid::DataObjects::MDEventsTestHelper::makeMDEW<3>(4, 0.0, 4.0, 1);
     auto emode = Mantid::Kernel::DeltaEMode::Elastic;
@@ -52,7 +52,7 @@ public:
     // Arrange
     auto isQ = true;
     auto eventWorkspace =
-        WorkspaceCreationHelper::CreateEventWorkspace2(10, 10);
+        WorkspaceCreationHelper::createEventWorkspace2(10, 10);
     auto mdEventWorkspace =
         Mantid::DataObjects::MDEventsTestHelper::makeMDEW<3>(4, 0.0, 4.0, 1);
     auto emode = Mantid::Kernel::DeltaEMode::Direct;
@@ -72,7 +72,7 @@ public:
   test_that_indirect_energy_mode_with_input_workspace2D_creates_num_event_normalization() {
     // Arrange
     auto isQ = true;
-    auto histoWorkspace = WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+    auto histoWorkspace = WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     auto mdEventWorkspace =
         Mantid::DataObjects::MDEventsTestHelper::makeMDEW<3>(4, 0.0, 4.0, 1);
     auto emode = Mantid::Kernel::DeltaEMode::Direct;
@@ -91,7 +91,7 @@ public:
   void test_that_non_Q_creates_volume_normalization() {
     // Arrange
     auto isQ = false;
-    auto histoWorkspace = WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+    auto histoWorkspace = WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     auto mdEventWorkspace =
         Mantid::DataObjects::MDEventsTestHelper::makeMDEW<3>(4, 0.0, 4.0, 1);
     auto emode = Mantid::Kernel::DeltaEMode::Direct;
@@ -108,4 +108,4 @@ public:
   }
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/Framework/MDAlgorithms/test/DivideMDTest.h b/Framework/MDAlgorithms/test/DivideMDTest.h
index da0c61996aca83f817369e0172b232aa33a99238..611b11c15421192bfe87cac895d7ccf8a322eb27 100644
--- a/Framework/MDAlgorithms/test/DivideMDTest.h
+++ b/Framework/MDAlgorithms/test/DivideMDTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/Timer.h"
 #include "MantidKernel/System.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 #include "MantidMDAlgorithms/DivideMD.h"
 #include "MantidTestHelpers/BinaryOperationMDTestHelper.h"
diff --git a/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h b/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h
index 27a13f9b49a714469f60966e7e1bd366158c01a9..12638da2054c185a5e46097cec6b935cb3a60106 100644
--- a/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h
+++ b/Framework/MDAlgorithms/test/EvaluateMDFunctionTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidMDAlgorithms/EvaluateMDFunction.h"
 #include "MantidMDAlgorithms/CreateMDHistoWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 
 using Mantid::MDAlgorithms::EvaluateMDFunction;
 using Mantid::MDAlgorithms::CreateMDHistoWorkspace;
diff --git a/Framework/MDAlgorithms/test/FitMDTest.h b/Framework/MDAlgorithms/test/FitMDTest.h
index aa68c83bdeb9091e821687d27a1470fe5949ad42..50dba755b4a8e64de06a094af7411d399c749cd4 100644
--- a/Framework/MDAlgorithms/test/FitMDTest.h
+++ b/Framework/MDAlgorithms/test/FitMDTest.h
@@ -2,6 +2,7 @@
 #define CURVEFITTING_FITMDTEST_H_
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/FitResolutionConvolvedModelTest.h b/Framework/MDAlgorithms/test/FitResolutionConvolvedModelTest.h
index a6f3f52f6f57c350cb49529107101dbcaa860f3b..4c3bd1e4dd36ca63f5e953ea18de74e8d828774c 100644
--- a/Framework/MDAlgorithms/test/FitResolutionConvolvedModelTest.h
+++ b/Framework/MDAlgorithms/test/FitResolutionConvolvedModelTest.h
@@ -32,7 +32,7 @@ public:
     using namespace Mantid::API;
     IAlgorithm_sptr alg = createAlgorithm();
     MatrixWorkspace_sptr testMatrixWS =
-        WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+        WorkspaceCreationHelper::create2DWorkspace(1, 10);
     Mantid::API::AnalysisDataService::Instance().addOrReplace(m_inputName,
                                                               testMatrixWS);
 
diff --git a/Framework/MDAlgorithms/test/GetSpiceDataRawCountsFromMDTest.h b/Framework/MDAlgorithms/test/GetSpiceDataRawCountsFromMDTest.h
index b54e27cf3328b81b8e4f8d246ed17df7c32ec0b7..73107d5007c54d88596c90b3c5107e78f142a825 100644
--- a/Framework/MDAlgorithms/test/GetSpiceDataRawCountsFromMDTest.h
+++ b/Framework/MDAlgorithms/test/GetSpiceDataRawCountsFromMDTest.h
@@ -6,6 +6,7 @@
 #include "MantidMDAlgorithms/GetSpiceDataRawCountsFromMD.h"
 #include "MantidDataHandling/LoadSpiceAscii.h"
 #include "MantidMDAlgorithms/ConvertSpiceDataToRealSpace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/ImportMDEventWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDEventWorkspaceTest.h
index f3fe10bf56d0d6c6f1ead411c99f6081855a6532..96a92ad40f3ff0454bc71e346b2e4b75d53d33f7 100644
--- a/Framework/MDAlgorithms/test/ImportMDEventWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/ImportMDEventWorkspaceTest.h
@@ -4,6 +4,7 @@
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidMDAlgorithms/ImportMDEventWorkspace.h"
 #include "MantidGeometry/MDGeometry/GeneralFrame.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/ConfigService.h"
 
 #include <cxxtest/TestSuite.h>
diff --git a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
index 234f4d166a8ab6bd7514ad446ab35c73214cc7cb..37c2318fa5352feee95277880e293b85f552eb71 100644
--- a/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
+++ b/Framework/MDAlgorithms/test/ImportMDHistoWorkspaceTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_MDEVENTS_IMPORTMDHISTOWORKSPACETEST_H_
 #define MANTID_MDEVENTS_IMPORTMDHISTOWORKSPACETEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidMDAlgorithms/ImportMDHistoWorkspace.h"
diff --git a/Framework/MDAlgorithms/test/IntegrateFluxTest.h b/Framework/MDAlgorithms/test/IntegrateFluxTest.h
index f3ec91a07a8420782a18b83fb7602ba0e1f4a284..488b3e155db693fd7af4e58df09615b1c39eb80f 100644
--- a/Framework/MDAlgorithms/test/IntegrateFluxTest.h
+++ b/Framework/MDAlgorithms/test/IntegrateFluxTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidMDAlgorithms/IntegrateFlux.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Framework/MDAlgorithms/test/LoadMDTest.h b/Framework/MDAlgorithms/test/LoadMDTest.h
index 16a3868a00e2b339b4f22e05155363272f8a4157..41cd937c81aa115c12b9a563e54659a04b4215c1 100644
--- a/Framework/MDAlgorithms/test/LoadMDTest.h
+++ b/Framework/MDAlgorithms/test/LoadMDTest.h
@@ -4,8 +4,10 @@
 #include "SaveMDTest.h"
 #include "SaveMD2Test.h"
 
+#include "MantidKernel/Strings.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/ExperimentInfo.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidDataObjects/MDBox.h"
 #include "MantidDataObjects/MDGridBox.h"
 #include "MantidDataObjects/MDEventFactory.h"
diff --git a/Framework/MDAlgorithms/test/LoadSQWTest.h b/Framework/MDAlgorithms/test/LoadSQWTest.h
index 6f0f7652e08fedeba998586e9c0b09f07072b306..0db94c63e4ec577ac14cf7ac82e19a1493ea3492 100644
--- a/Framework/MDAlgorithms/test/LoadSQWTest.h
+++ b/Framework/MDAlgorithms/test/LoadSQWTest.h
@@ -4,6 +4,7 @@
 #include "MantidMDAlgorithms/LoadSQW.h"
 #include "MantidGeometry/Crystal/OrientedLattice.h"
 #include "MantidDataObjects/MDBoxBase.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Sample.h"
 
 #include <cxxtest/TestSuite.h>
diff --git a/Framework/MDAlgorithms/test/MDTransfModQTest.h b/Framework/MDAlgorithms/test/MDTransfModQTest.h
index ebf41740f5dfafdee03778e5c20818cf9679eb6c..8d4abe7cf82e7fb93914711fd643705b8d906cbd 100644
--- a/Framework/MDAlgorithms/test/MDTransfModQTest.h
+++ b/Framework/MDAlgorithms/test/MDTransfModQTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidMDAlgorithms/MDTransfQ3D.h"
 #include "MantidKernel/DeltaEMode.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 
diff --git a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
index af94840ef931be835f1b5c0c05cff7a5141b36af..cfe87617ea444c234a16e28025bdee3ea56d4565 100644
--- a/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
+++ b/Framework/MDAlgorithms/test/MDTransfQ3DTest.h
@@ -2,6 +2,7 @@
 #define MANTID_MDALGORITHMS_MDTRANSFQ3D_H_
 
 #include "MantidKernel/DeltaEMode.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/MDTransfQ3D.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
diff --git a/Framework/MDAlgorithms/test/MDWSDescriptionTest.h b/Framework/MDAlgorithms/test/MDWSDescriptionTest.h
index 9fb059d6e736b0d8827ad398273a5e050cb5745a..2d7551bb66fe2dc2b919a2439c5304ca03d0c277 100644
--- a/Framework/MDAlgorithms/test/MDWSDescriptionTest.h
+++ b/Framework/MDAlgorithms/test/MDWSDescriptionTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/SpecialCoordinateSystem.h"
 #include "MantidKernel/Exception.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/MDWSDescription.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 
diff --git a/Framework/MDAlgorithms/test/MDWSTransfTest.h b/Framework/MDAlgorithms/test/MDWSTransfTest.h
index 3a2a7fb0a8250c1315631f856ef0c8c610a55f3a..ddf5e20a54a424ff579e466a57275dfdf1e7d397 100644
--- a/Framework/MDAlgorithms/test/MDWSTransfTest.h
+++ b/Framework/MDAlgorithms/test/MDWSTransfTest.h
@@ -2,6 +2,7 @@
 #define MANTID_MDWS_SLICE_H_
 
 #include "MantidGeometry/Crystal/OrientedLattice.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/MDTransfAxisNames.h"
 #include "MantidMDAlgorithms/MDWSDescription.h"
 #include "MantidMDAlgorithms/MDWSTransform.h"
@@ -48,7 +49,7 @@ public:
   void testFindTargetFrame() {
     MDWSDescription TargWSDescription;
     Mantid::API::MatrixWorkspace_sptr spws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 10);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10);
     // Mantid::API::MatrixWorkspace_sptr spws
     // =WorkspaceCreationHelper::createProcessedWorkspaceWithCylComplexInstrument(4,10,true);
     std::vector<double> minVal(4, -3), maxVal(4, 3);
@@ -60,7 +61,7 @@ public:
     TS_ASSERT_EQUALS(CnvrtToMD::LabFrame,
                      Transf.findTargetFrame(TargWSDescription));
 
-    WorkspaceCreationHelper::SetGoniometer(spws, 0, 0, 0);
+    WorkspaceCreationHelper::setGoniometer(spws, 0, 0, 0);
     // spws->mutableRun().mutableGoniometer().setRotationAngle(0,20);
 
     TS_ASSERT_EQUALS(CnvrtToMD::SampleFrame,
@@ -74,7 +75,7 @@ public:
     MDWSDescription TargWSDescription;
 
     Mantid::API::MatrixWorkspace_sptr spws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 10);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10);
     std::vector<double> minVal(4, -3), maxVal(4, 3);
     TargWSDescription.setMinMax(minVal, maxVal);
     spws->mutableSample().setOrientedLattice(NULL);
@@ -95,7 +96,7 @@ public:
                       std::invalid_argument);
     spws->mutableSample().setOrientedLattice(pLattice);
 
-    WorkspaceCreationHelper::SetGoniometer(spws, 20, 0, 0);
+    WorkspaceCreationHelper::setGoniometer(spws, 20, 0, 0);
 
     // spws->mutableRun().mutableGoniometer().setRotationAngle(0,20);
 
@@ -377,7 +378,7 @@ public:
     std::vector<double> rot, sample(9, 0);
 
     Mantid::API::MatrixWorkspace_sptr spws =
-        WorkspaceCreationHelper::Create2DWorkspaceBinned(10, 10);
+        WorkspaceCreationHelper::create2DWorkspaceBinned(10, 10);
     // Mantid::API::MatrixWorkspace_sptr spws
     // =WorkspaceCreationHelper::createProcessedWorkspaceWithCylComplexInstrument(4,10,true);
     std::vector<double> minVal(2, 0), maxVal(2, 3);
diff --git a/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Framework/MDAlgorithms/test/MergeMDFilesTest.h
index e7fb5c6f6b319e451a43bd890e744a6608ec2999..b62604f3fb8ccaa6f4a1884afd06fc64c33b2f69 100644
--- a/Framework/MDAlgorithms/test/MergeMDFilesTest.h
+++ b/Framework/MDAlgorithms/test/MergeMDFilesTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidMDAlgorithms/MergeMDFiles.h"
 #include "MantidDataObjects/MDEventFactory.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidTestHelpers/MDAlgorithmsTestHelper.h"
 #include "MantidGeometry/MDGeometry/QSample.h"
 
diff --git a/Framework/MDAlgorithms/test/MultiplyMDTest.h b/Framework/MDAlgorithms/test/MultiplyMDTest.h
index a28172002c3bc3cf2fa4bfce14265e93ca2e8f99..480a3576dff6bfa98ed06d8c863af1724f6d27bc 100644
--- a/Framework/MDAlgorithms/test/MultiplyMDTest.h
+++ b/Framework/MDAlgorithms/test/MultiplyMDTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidMDAlgorithms/MultiplyMD.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidTestHelpers/BinaryOperationMDTestHelper.h"
 
 #include <cxxtest/TestSuite.h>
diff --git a/Framework/MDAlgorithms/test/OneStepMDEWTest.h b/Framework/MDAlgorithms/test/OneStepMDEWTest.h
index 39232f2086b146ea4635d0d4508de511423ca8b8..5828764bfd7cfbddc10e2fc5e263c979ada62ab1 100644
--- a/Framework/MDAlgorithms/test/OneStepMDEWTest.h
+++ b/Framework/MDAlgorithms/test/OneStepMDEWTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidMDAlgorithms/OneStepMDEW.h"
diff --git a/Framework/MDAlgorithms/test/PreprocessDetectorsToMDTest.h b/Framework/MDAlgorithms/test/PreprocessDetectorsToMDTest.h
index d0dd6234c828c087c9732fd363e5e88b826b14e7..87d904b05fe2f1675c590dbc9d9b4140a1700848 100644
--- a/Framework/MDAlgorithms/test/PreprocessDetectorsToMDTest.h
+++ b/Framework/MDAlgorithms/test/PreprocessDetectorsToMDTest.h
@@ -2,8 +2,10 @@
 #define MDALGORITHMS_PREPROCESS_DETECTORS2MD_TEST_H_
 
 #include <cxxtest/TestSuite.h>
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidMDAlgorithms/PreprocessDetectorsToMD.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
+#include "MantidAPI/SpectrumInfo.h"
 
 using namespace Mantid;
 using namespace Mantid::MDAlgorithms;
@@ -257,9 +259,10 @@ public:
     }
 
     // Now mask all detectors in the workspace
-    std::vector<size_t>::const_iterator wit;
-    for (wit = indexLis.begin(); wit != indexLis.end(); ++wit) {
-      inputWS->maskWorkspaceIndex(*wit);
+    auto &spectrumInfo = inputWS->mutableSpectrumInfo();
+    for (const auto i : indexLis) {
+      inputWS->getSpectrum(i).clearData();
+      spectrumInfo.setMasked(i, true);
     }
     // let's retrieve masks now
 
diff --git a/Framework/MDAlgorithms/test/SaveMD2Test.h b/Framework/MDAlgorithms/test/SaveMD2Test.h
index 6a036d06ad8b44bc833416c3f7eef27eb83ffd92..85c4b9e2704648910ab7cdb2ae05d6d314bba571 100644
--- a/Framework/MDAlgorithms/test/SaveMD2Test.h
+++ b/Framework/MDAlgorithms/test/SaveMD2Test.h
@@ -4,6 +4,7 @@
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/Run.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidMDAlgorithms/BinMD.h"
 #include "MantidMDAlgorithms/SaveMD2.h"
diff --git a/Framework/MDAlgorithms/test/SaveMDTest.h b/Framework/MDAlgorithms/test/SaveMDTest.h
index 3c4612a404b78d926c5dca2419a84c538c046e7d..a53feb583d2d2207db28d66eba17f118690075ff 100644
--- a/Framework/MDAlgorithms/test/SaveMDTest.h
+++ b/Framework/MDAlgorithms/test/SaveMDTest.h
@@ -5,6 +5,7 @@
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Run.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidMDAlgorithms/BinMD.h"
 #include "MantidMDAlgorithms/SaveMD.h"
diff --git a/Framework/MDAlgorithms/test/SetMDFrameTest.h b/Framework/MDAlgorithms/test/SetMDFrameTest.h
index 19563b04a2832141dcb9d0869e4f8c6c365581aa..d03afaeea7e77f3ccc9dcbeaf193346e2018a0d2 100644
--- a/Framework/MDAlgorithms/test/SetMDFrameTest.h
+++ b/Framework/MDAlgorithms/test/SetMDFrameTest.h
@@ -30,7 +30,7 @@ public:
 
   void test_that_is_not_executed_when_non_mdevent_and_non_mdhisto() {
     // Arrange
-    auto inputWorkspace = WorkspaceCreationHelper::Create2DWorkspace(2, 5);
+    auto inputWorkspace = WorkspaceCreationHelper::create2DWorkspace(2, 5);
     SetMDFrame alg;
     alg.setChild(true);
     alg.setRethrows(true);
@@ -283,4 +283,4 @@ public:
   }
 };
 
-#endif /* MANTID_MDALGORITHMS_SetMDFrameTEST_H_ */
\ No newline at end of file
+#endif /* MANTID_MDALGORITHMS_SetMDFrameTEST_H_ */
diff --git a/Framework/MDAlgorithms/test/SliceMDTest.h b/Framework/MDAlgorithms/test/SliceMDTest.h
index aa243fa6925e8aa6e88fab28ed22998639b59462..b54159980af50b1032aae3d68ea8f5e3f82dc637 100644
--- a/Framework/MDAlgorithms/test/SliceMDTest.h
+++ b/Framework/MDAlgorithms/test/SliceMDTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_MDEVENTS_SLICEMDTEST_H_
 #define MANTID_MDEVENTS_SLICEMDTEST_H_
 
+#include "MantidKernel/IPropertySettings.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidMDAlgorithms/SliceMD.h"
 #include "MantidDataObjects/CoordTransformAffine.h"
diff --git a/Framework/MDAlgorithms/test/ThresholdMDTest.h b/Framework/MDAlgorithms/test/ThresholdMDTest.h
index 794e5d1d12a2af54619c30e14c90fa8e35ae4a39..68887d2ea1053a08ec1267ae601cfbdfc9ae8c0d 100644
--- a/Framework/MDAlgorithms/test/ThresholdMDTest.h
+++ b/Framework/MDAlgorithms/test/ThresholdMDTest.h
@@ -1,6 +1,7 @@
 #ifndef MANTID_MDALGORITHMS_THRESHOLDMDTEST_H_
 #define MANTID_MDALGORITHMS_THRESHOLDMDTEST_H_
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidGeometry/MDGeometry/MDTypes.h"
diff --git a/Framework/MDAlgorithms/test/UnaryOperationMDTest.h b/Framework/MDAlgorithms/test/UnaryOperationMDTest.h
index dd3d073b678a2d4a13059230259a1477c5b35aa0..a7ffd215560eb79a79e90ae1481a61243a5267d5 100644
--- a/Framework/MDAlgorithms/test/UnaryOperationMDTest.h
+++ b/Framework/MDAlgorithms/test/UnaryOperationMDTest.h
@@ -48,7 +48,7 @@ public:
   void setUp() override {
     histo = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2, 5, 10.0, 1.0);
     event = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
-    scalar = WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.5);
+    scalar = WorkspaceCreationHelper::createWorkspaceSingleValue(2.5);
     AnalysisDataService::Instance().addOrReplace("histo", histo);
     AnalysisDataService::Instance().addOrReplace("event", event);
     AnalysisDataService::Instance().addOrReplace("scalar", scalar);
diff --git a/Framework/Nexus/src/NexusFileIO.cpp b/Framework/Nexus/src/NexusFileIO.cpp
index 838acf5c641e336706c64267251ad250677574db..f14de0749c6f9bfa93f380e7517ca53f7017f006 100644
--- a/Framework/Nexus/src/NexusFileIO.cpp
+++ b/Framework/Nexus/src/NexusFileIO.cpp
@@ -1,8 +1,5 @@
 // NexusFileIO
 // @author Ronald Fowler
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include <vector>
 #include <sstream>
 
@@ -19,6 +16,7 @@
 #include "MantidKernel/UnitFactory.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidAPI/NumericAxis.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/VectorHelper.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
diff --git a/Framework/Properties/Mantid.properties.template b/Framework/Properties/Mantid.properties.template
index 7921eb64b5010772538bd1e3fb3fc98a43ecdf12..f8d66cc81e82fd7d09a90e203325ef6ca5e4a826 100644
--- a/Framework/Properties/Mantid.properties.template
+++ b/Framework/Properties/Mantid.properties.template
@@ -124,7 +124,6 @@ MultiThreaded.MaxCores = 0
 
 # Defines the area (in FWHM) on both sides of the peak centre within which peaks are calculated.
 # Outside this area peak functions return zero.
-curvefitting.peakRadius = 5
 curvefitting.defaultPeak=Gaussian
 curvefitting.findPeaksFWHM=7
 curvefitting.findPeaksTolerance=4
diff --git a/Framework/PythonInterface/mantid/api/CMakeLists.txt b/Framework/PythonInterface/mantid/api/CMakeLists.txt
index 3756e81923482d6df7b86fc1bc8ec07889fbd65d..17a8ea2024cd65837afdf288e0dc596590c4c50a 100644
--- a/Framework/PythonInterface/mantid/api/CMakeLists.txt
+++ b/Framework/PythonInterface/mantid/api/CMakeLists.txt
@@ -13,6 +13,7 @@ set ( EXPORT_FILES
   src/Exports/AlgorithmHistory.cpp
   src/Exports/CatalogManager.cpp
   src/Exports/CatalogSession.cpp
+  src/Exports/DetectorInfo.cpp
   src/Exports/DeprecatedAlgorithmChecker.cpp
   src/Exports/Algorithm.cpp
   src/Exports/DataProcessorAlgorithm.cpp
@@ -61,6 +62,7 @@ set ( EXPORT_FILES
   src/Exports/Sample.cpp
   src/Exports/ScriptRepository.cpp
   src/Exports/ScriptRepositoryFactory.cpp
+  src/Exports/SpectrumInfo.cpp
   src/Exports/Run.cpp
   src/Exports/WorkspaceFactory.cpp
   src/Exports/IFunction.cpp
diff --git a/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp b/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
index 547d3b1b32cb7b7c1d11830812e573ce7272c0b7..27680a1caeaa97485e2fec06d6342a2e118ebde8 100644
--- a/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Algorithms/RunPythonScript.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidPythonInterface/api/Algorithms/RunPythonScript.h"
 #include "MantidPythonInterface/api/ExtractWorkspace.h"
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
index a0d1c6b4323cfe112806964152f6ad9391053d64..2e45ae9772c8989ff3c18583da88fa834fd9b977 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/BinaryOperations.cpp
@@ -5,7 +5,7 @@
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 #include "MantidPythonInterface/kernel/Policies/AsType.h"
 
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fd6d8e0a7906fbb9d54850aa5a12af7f09325c99
--- /dev/null
+++ b/Framework/PythonInterface/mantid/api/src/Exports/DetectorInfo.cpp
@@ -0,0 +1,17 @@
+#include "MantidAPI/DetectorInfo.h"
+#include <boost/python/class.hpp>
+
+using Mantid::API::DetectorInfo;
+using namespace boost::python;
+
+void export_DetectorInfo() {
+  class_<DetectorInfo, boost::noncopyable>("DetectorInfo", no_init)
+      .def("__len__", &DetectorInfo::size, (arg("self")),
+           "Returns the size of the DetectorInfo, i.e., the number of "
+           "detectors in the instrument.")
+      .def("size", &DetectorInfo::size, (arg("self")),
+           "Returns the size of the DetectorInfo, i.e., the number of "
+           "detectors in the instrument.")
+      .def("isMasked", &DetectorInfo::isMasked, (arg("self"), arg("index")),
+           "Returns True if the detector is masked.");
+}
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp
index aa44a273b6f9b6bf1d67f20a8d2e2f5a76d157eb..ad8cbf506e2037d02f9c06d509d2ff79c999e244 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/ExperimentInfo.cpp
@@ -1,4 +1,5 @@
 #include "MantidGeometry/IDTypes.h"
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/Sample.h"
@@ -70,5 +71,9 @@ void export_ExperimentInfo() {
            args("self", "detId", "value"))
 
       .def("getEMode", &ExperimentInfo::getEMode, args("self"),
-           "Returns the energy mode.");
+           "Returns the energy mode.")
+
+      .def("detectorInfo", &ExperimentInfo::detectorInfo,
+           return_value_policy<reference_existing_object>(), args("self"),
+           "Return a const reference to the DetectorInfo object.");
 }
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
index 3615761a57fa746af55722e8eaf3a327298a7f65..cc92119a4c67aa89fc64093d332f1f88962e56f5 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
@@ -186,7 +186,7 @@ std::string createDocString(IAlgorithm &self) {
   // Put in the quick overview message
   std::stringstream buffer;
   std::string temp = self.summary();
-  if (temp.size() > 0)
+  if (!temp.empty())
     buffer << temp << EOL << EOL;
 
   // get a sorted copy of the properties
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
index a3744f7f4ec9ed9eacc5f29059fcc7e5e4de19c2..2a085a4a41b32ea1bc559e89bee5784a6308c1d4 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/IMDHistoWorkspace.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/IMDHistoWorkspace.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidPythonInterface/kernel/GetPointer.h"
 #include "MantidPythonInterface/kernel/NdArray.h"
 #include "MantidPythonInterface/kernel/Converters/NDArrayTypeIndex.h"
@@ -256,7 +257,13 @@ void export_IMDHistoWorkspace() {
       .def("getCenter", &IMDHistoWorkspace::getCenter,
            (arg("self"), arg("linear_index")),
            return_value_policy<return_by_value>(),
-           "Return the position of the center of a bin at a given position");
+           "Return the position of the center of a bin at a given position")
+
+      .def("setDisplayNormalization",
+           &IMDHistoWorkspace::setDisplayNormalization,
+           (arg("self"), arg("normalization")),
+           "Sets the visual normalization of"
+           " the workspace.");
 
   //-------------------------------------------------------------------------------------------------
 
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
index 83d57c115566483a54f6dfdc0121d93f54073495..367fb90a81ba9daf2576dc05cf671526ef850c01 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/MDGeometry.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/MDGeometry.h"
+#include "MantidAPI/Workspace.h"
 #include "MantidPythonInterface/kernel/Policies/RemoveConst.h"
 #include "MantidPythonInterface/kernel/Policies/VectorToNumpy.h"
 #include <boost/python/class.hpp>
@@ -7,7 +8,6 @@
 #include <boost/python/return_value_policy.hpp>
 
 using Mantid::API::MDGeometry;
-using Mantid::Geometry::IMDDimension_const_sptr;
 using Mantid::PythonInterface::Policies::RemoveConstSharedPtr;
 using Mantid::PythonInterface::Policies::VectorToNumpy;
 using namespace boost::python;
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
index 7de857936c62f46b12e6689c8b325cfbee77fc0e..8633f3568079fdb6403fd48710aa1191d1d101e6 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/MatrixWorkspace.cpp
@@ -1,6 +1,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceOpOverloads.h"
 
 #include "MantidPythonInterface/api/CloneMatrixWorkspace.h"
@@ -241,6 +242,10 @@ void export_MatrixWorkspace() {
       .def("YUnitLabel", &MatrixWorkspace::YUnitLabel, arg("self"),
            "Returns the caption for the Y axis")
 
+      .def("spectrumInfo", &MatrixWorkspace::spectrumInfo,
+           return_value_policy<reference_existing_object>(), args("self"),
+           "Return a const reference to the SpectrumInfo object.")
+
       // Deprecated
       .def("getNumberBins", &getNumberBinsDeprecated, arg("self"),
            "Returns size of the Y data array (deprecated, use blocksize "
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/SpectrumInfo.cpp b/Framework/PythonInterface/mantid/api/src/Exports/SpectrumInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cfc38022b8c5059fcd3cdd216860346943ff4eae
--- /dev/null
+++ b/Framework/PythonInterface/mantid/api/src/Exports/SpectrumInfo.cpp
@@ -0,0 +1,15 @@
+#include "MantidAPI/SpectrumInfo.h"
+#include <boost/python/class.hpp>
+
+using Mantid::API::SpectrumInfo;
+using namespace boost::python;
+
+void export_SpectrumInfo() {
+  class_<SpectrumInfo, boost::noncopyable>("SpectrumInfo", no_init)
+      .def("isMasked", &SpectrumInfo::isMasked, (arg("self"), arg("index")),
+           "Returns true if the detector(s) associated with the spectrum are "
+           "masked.")
+      .def("hasDetectors", &SpectrumInfo::hasDetectors, (arg("self")),
+           "Returns true if the spectrum is associated with detectors in the "
+           "instrument.");
+}
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp b/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
index 8419a41fa2966fac47df65dfbaa1a48566b1cb4d..61c273b91c10e93f8fa82572137205dc7a39fe61 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/Workspace.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 
 #include "MantidPythonInterface/kernel/GetPointer.h"
 #include "MantidPythonInterface/kernel/Registry/RegisterWorkspacePtrToPython.h"
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroupProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroupProperty.cpp
index 58834332b90e591fc2447ef868fe01ed48974dec..5522dfe1b2a2a39f10f6800988dcddd9b95709d0 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroupProperty.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceGroupProperty.cpp
@@ -1,6 +1,6 @@
 #include "MantidPythonInterface/api/WorkspacePropertyExporter.h"
 #include "MantidPythonInterface/kernel/GetPointer.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using Mantid::API::WorkspaceGroup;
 using Mantid::API::WorkspaceProperty;
diff --git a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceProperty.cpp b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceProperty.cpp
index 291079ff6a0594dc77bf4c318b60b74d81efaad1..53f5e602d291c7f3c2c5da307211066c445b1dec 100644
--- a/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceProperty.cpp
+++ b/Framework/PythonInterface/mantid/api/src/Exports/WorkspaceProperty.cpp
@@ -1,6 +1,6 @@
 #include "MantidPythonInterface/api/WorkspacePropertyExporter.h"
 #include "MantidPythonInterface/kernel/GetPointer.h"
-#include "MantidAPI/Workspace_fwd.h"
+#include "MantidAPI/Workspace.h"
 #include <boost/python/enum.hpp>
 
 using Mantid::API::Workspace;
diff --git a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index 18723bc4f63fbc1f47d1b4b311055bf5afb2d42b..4eefde94841e99753ceb812dd871ac650e3c02b4 100644
--- a/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -31,6 +31,7 @@ set ( EXPORT_FILES
   src/Exports/DateAndTime.cpp
   src/Exports/InstrumentInfo.cpp
   src/Exports/FacilityInfo.cpp
+  src/Exports/LiveListenerInfo.cpp
   src/Exports/NullValidator.cpp
   src/Exports/ListValidator.cpp
   src/Exports/ArrayLengthValidator.cpp
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
index 907c51778cf610aba31d1a672e6df9a6a320a04e..c1b175e05bef42ed2d80f7443cbb5a4965bdb22f 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/FacilityInfo.cpp
@@ -61,10 +61,6 @@ void export_FacilityInfo() {
            return_value_policy<copy_const_reference>(),
            "Returns the instrument with the given name")
 
-      .def("liveListener", &FacilityInfo::liveListener, arg("self"),
-           return_value_policy<copy_const_reference>(),
-           "Returns the name of the default live listener")
-
       .def("computeResources", &FacilityInfo::computeResources, arg("self"),
            "Returns a vector of the available compute resources");
 }
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp
index b9405b89eb507eb404d6fe833116e096ac4567fd..89ad48a464a106017c125eadb557e080a618ceb1 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/IPropertyManager.cpp
@@ -1,4 +1,5 @@
 #include "MantidKernel/IPropertyManager.h"
+#include "MantidKernel/IPropertySettings.h"
 #include "MantidPythonInterface/kernel/GetPointer.h"
 #include "MantidPythonInterface/kernel/Registry/TypeRegistry.h"
 #include "MantidPythonInterface/kernel/Registry/PropertyValueHandler.h"
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
index d72da5eea64e8dc3adddb0ec6e846008889996a8..d13456c623d141c2fbc2b6a94756be9f653cb8b4 100644
--- a/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/InstrumentInfo.cpp
@@ -1,8 +1,10 @@
 #include "MantidKernel/InstrumentInfo.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidPythonInterface/kernel/StlExportDefinitions.h"
+
 #include <boost/python/class.hpp>
 #include <boost/python/copy_const_reference.hpp>
+#include <boost/python/overloads.hpp>
 
 using Mantid::Kernel::InstrumentInfo;
 using namespace boost::python;
@@ -46,10 +48,36 @@ void export_InstrumentInfo() {
            return_value_policy<copy_const_reference>(),
            "Returns the facility that contains this instrument.")
 
+      .def("liveListener", &InstrumentInfo::liveListener,
+           (arg("self"), arg("name") = ""),
+           "Returns the name of the specific LiveListener class that is used "
+           "by the given connection name. If no name is provided, the default "
+           "connection is used.")
+
+      // Unclear why this is named "instdae", leaving in case legacy req'd
       .def("instdae", &InstrumentInfo::liveDataAddress, arg("self"),
-           return_value_policy<copy_const_reference>(),
            "Returns the host name and the port of the machine hosting DAE and "
            "providing port to connect to for a live data stream")
 
+      .def("liveDataAddress", &InstrumentInfo::liveDataAddress,
+           (arg("self"), arg("name") = ""),
+           "Returns the Address string of a live data connection on this "
+           "instrument. If no connection name is provided, the default "
+           "connection is used.")
+
+      .def("liveListenerInfo", &InstrumentInfo::liveListenerInfo,
+           (arg("self"), arg("name") = ""),
+           return_value_policy<copy_const_reference>(),
+           "Returns a LiveListenerInfo instance for this instrument. If "
+           "no connection name is specified, the default is used.")
+
+      .def("hasLiveListenerInfo", &InstrumentInfo::hasLiveListenerInfo,
+           arg("self"),
+           "Returns true if this instrument has at least one LiveListenerInfo")
+
+      .def("liveListenerInfoList", &InstrumentInfo::liveListenerInfoList,
+           arg("self"), return_value_policy<copy_const_reference>(),
+           "Returns all available LiveListenerInfo instances as a vector")
+
       ;
 }
diff --git a/Framework/PythonInterface/mantid/kernel/src/Exports/LiveListenerInfo.cpp b/Framework/PythonInterface/mantid/kernel/src/Exports/LiveListenerInfo.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c67c230caef303200ed335d1ec1d09d34f331e77
--- /dev/null
+++ b/Framework/PythonInterface/mantid/kernel/src/Exports/LiveListenerInfo.cpp
@@ -0,0 +1,27 @@
+#include "MantidKernel/LiveListenerInfo.h"
+#include "MantidKernel/InstrumentInfo.h"
+#include "MantidPythonInterface/kernel/StlExportDefinitions.h"
+
+#include <boost/python/class.hpp>
+#include <boost/python/copy_const_reference.hpp>
+
+using Mantid::Kernel::LiveListenerInfo;
+using namespace boost::python;
+
+void export_LiveListenerInfo() {
+  using namespace Mantid::PythonInterface;
+  std_vector_exporter<LiveListenerInfo>::wrap("std_vector_LiveListenerInfo");
+
+  class_<LiveListenerInfo>("LiveListenerInfo", no_init)
+      .def("name", &LiveListenerInfo::name, arg("self"),
+           return_value_policy<copy_const_reference>(),
+           "Returns the name of this LiveListener connection")
+
+      .def("address", &LiveListenerInfo::address, arg("self"),
+           return_value_policy<copy_const_reference>(),
+           "Returns the address of this LiveListener connection")
+
+      .def("listener", &LiveListenerInfo::listener, arg("self"),
+           return_value_policy<copy_const_reference>(),
+           "Returns the name of the specific LiveListener class used");
+}
diff --git a/Framework/PythonInterface/plugins/algorithms/CollectHB3AExperimentInfo.py b/Framework/PythonInterface/plugins/algorithms/CollectHB3AExperimentInfo.py
index 094213968ef0dcc86767a301bda4a619e5fd7f12..2ee26e43abc642dabc6acc4276bb8b6ae48d5b82 100644
--- a/Framework/PythonInterface/plugins/algorithms/CollectHB3AExperimentInfo.py
+++ b/Framework/PythonInterface/plugins/algorithms/CollectHB3AExperimentInfo.py
@@ -326,7 +326,7 @@ class CollectHB3AExperimentInfo(PythonAlgorithm):
                     dataws = self._loadHB3ADetCountFile(scannumber, ptnumber)
 
                     # write each detector's position and ID to table workspace
-                    maxdetid = 0
+                    maxdetid = -1
                     for iws in range(dataws.getNumberHistograms()):
                         detector = dataws.getDetector(iws)
                         detpos = detector.getPos()
diff --git a/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py b/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py
index 905ef1818e5378073963ac722f9fcbfa197b2df6..fa1954745bee5dc0bd24e15144ebdfa402067869 100644
--- a/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py
+++ b/Framework/PythonInterface/plugins/algorithms/ComputeCalibrationCoefVan.py
@@ -107,16 +107,14 @@ class ComputeCalibrationCoefVan(PythonAlgorithm):
         dataX = self.vanaws.readX(0)
         coefY = np.zeros(nhist)
         coefE = np.zeros(nhist)
-        instrument = self.vanaws.getInstrument()
-        detID_offset = self.get_detID_offset()
         peak_centre = eppws.column('PeakCentre')
         sigma = eppws.column('Sigma')
 
+        specInfo = self.vanaws.spectrumInfo()
         for idx in range(nhist):
             prog_reporter.report("Setting %dth spectrum" % idx)
             dataY = self.vanaws.readY(idx)
-            det = instrument.getDetector(idx + detID_offset)
-            if np.max(dataY) == 0 or det.isMasked():
+            if np.max(dataY) == 0 or specInfo.isMasked(idx):
                 coefY[idx] = 0.
                 coefE[idx] = 0.
             else:
diff --git a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
index 30d4332df42d0bd76b02231df9baf8452e3a233c..7041e5ed9d07f82b58b028a8a748548e1bde2519 100644
--- a/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
+++ b/Framework/PythonInterface/plugins/algorithms/DNSComputeDetEffCorrCoefs.py
@@ -168,11 +168,9 @@ class DNSComputeDetEffCorrCoefs(PythonAlgorithm):
         returns number of not masked detectors
         """
         num = 0
-        instrument = workspace.getInstrument()
-        offset = workspace.getSpectrum(0).getDetectorIDs()[0]
+        spectrumInfo = workspace.spectrumInfo()
         for idx in range(workspace.getNumberHistograms()):
-            det = instrument.getDetector(idx + offset)        # for DNS first det ID=1
-            if not det.isMasked():
+            if not spectrumInfo.isMasked(idx):
                 num += 1
         return num
 
diff --git a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
index 33c24ca00b31e842829198e2d9ea31e33166de4e..6c9d3e055591cbc7f735398691d63eadef077eb9 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExportSpectraMask.py
@@ -33,6 +33,7 @@ def export_masks(ws,fileName='',returnMasksOnly=False):
 
     no_detectors = 0
     masks = []
+    specInfo = pws.spectrumInfo()
     for i in range(nhist):
         # set provisional spectra ID
         ms = i+1
@@ -46,14 +47,13 @@ def export_masks(ws,fileName='',returnMasksOnly=False):
             masks.append(ms)
             continue
         try:
-            det = pws.getDetector(i)
+            if specInfo.isMasked(i):
+                masks.append(ms)
 #pylint: disable=W0703
         except Exception:
             no_detectors = no_detectors +1
             masks.append(ms)
             continue
-        if det.isMasked():
-            masks.append(ms)
 
     filename=''
     if len(fileName)==0 :
diff --git a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
index feb6cb70d5db1439c56caef78e9a2b9b0c5b7a40..a6de5b803264bde0ef009a87ac7d3c4d92513147 100644
--- a/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
+++ b/Framework/PythonInterface/plugins/algorithms/ExtractMonitors.py
@@ -64,26 +64,26 @@ class ExtractMonitors(DataProcessorAlgorithm):
 
         if detector_ws_name:
             if detectors:
-                detector_ws = ExtractSpectra(InputWorkspace=in_ws,
-                                             WorkspaceIndexList=detectors)
+                extract_alg = self.createChildAlgorithm("ExtractSpectra")
+                extract_alg.setProperty("InputWorkspace", in_ws)
+                extract_alg.setProperty("WorkspaceIndexList", detectors)
+                extract_alg.execute()
+                detector_ws = extract_alg.getProperty("OutputWorkspace").value
+                self.setProperty("DetectorWorkspace", detector_ws)
             else:
                 self.log().error("No detectors found in input workspace. No detector output workspace created.")
 
         if monitor_ws_name:
             if monitors:
-                monitor_ws = ExtractSpectra(InputWorkspace=in_ws,
-                                            WorkspaceIndexList=monitors)
+                extract_alg = self.createChildAlgorithm("ExtractSpectra")
+                extract_alg.setProperty("InputWorkspace", in_ws)
+                extract_alg.setProperty("WorkspaceIndexList", monitors)
+                extract_alg.execute()
+                monitor_ws = extract_alg.getProperty("OutputWorkspace").value
+                self.setProperty("MonitorWorkspace", monitor_ws)
             else:
                 self.log().error("No monitors found in input workspace. No monitor output workspace created.")
 
-        if detector_ws_name and detectors:
-            self.setProperty("DetectorWorkspace", detector_ws)
-            DeleteWorkspace(detector_ws)
-
-        if monitor_ws_name and monitors:
-            self.setProperty("MonitorWorkspace", monitor_ws)
-            DeleteWorkspace(monitor_ws)
-
         if detector_ws_name and detectors and monitor_ws_name and monitors:
             detector_ws.setMonitorWorkspace(monitor_ws)
 
diff --git a/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py b/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py
index 5a26872144296b5629d20580ca63b46780c2ad01..fb73444843cb41188ff71966a591921778977711 100644
--- a/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py
+++ b/Framework/PythonInterface/plugins/algorithms/IndirectTransmission.py
@@ -35,7 +35,7 @@ class IndirectTransmission(PythonAlgorithm):
 
     def PyInit(self):
         self.declareProperty(name='Instrument', defaultValue='IRIS',
-                             validator=StringListValidator(['IRIS', 'OSIRIS', 'TOSCA', 'BASIS', 'VISION']),
+                             validator=StringListValidator(['IRIS', 'OSIRIS', 'TOSCA', 'BASIS', 'VISION', 'IN16B']),
                              doc='Instrument')
 
         self.declareProperty(name='Analyser', defaultValue='graphite',
@@ -43,7 +43,7 @@ class IndirectTransmission(PythonAlgorithm):
                              doc='Analyser')
 
         self.declareProperty(name='Reflection', defaultValue='002',
-                             validator=StringListValidator(['002', '004', '006', '111']),
+                             validator=StringListValidator(['002', '004', '006', '111', '311']),
                              doc='Reflection')
 
         self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
diff --git a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
index 600a5d4a039e2a107f0c067f5b13e06ac568fb91..7e311bed9f7c5c74c1c1a084b574e2376f981eea 100644
--- a/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
+++ b/Framework/PythonInterface/plugins/algorithms/MaskWorkspaceToCalFile.py
@@ -8,14 +8,14 @@ from mantid.simpleapi import *
 
 
 class QueryFlag(object):
-    def isMasked(self, detector, dummy_yValue):
-        return detector.isMasked()
+    def isMasked(self, specInfo, index, dummy_yValue):
+        return specInfo.isMasked(index)
 
 #pylint: disable=too-few-public-methods
 
 
 class QueryValue(object):
-    def isMasked(self, dummy_detector, yValue):
+    def isMasked(self, dummy_specInfo, dummy_index, yValue):
         return yValue == 1
 
 
@@ -64,11 +64,12 @@ class MaskWorkspaceToCalFile(PythonAlgorithm):
         calFile.write('# '+instrumentName+' detector file\n')
         calFile.write('# Format: number      UDET       offset       select    group\n')
         #save the grouping
+        specInfo = inputWorkspace.spectrumInfo()
         for i in range(inputWorkspace.getNumberHistograms()):
             try:
                 det = inputWorkspace.getDetector(i)
                 y_value = inputWorkspace.readY(i)[0]
-                if mask_query.isMasked(det, y_value): #check if masked
+                if mask_query.isMasked(specInfo, i, y_value): #check if masked
                     group = masking_flag
                 else:
                     group = not_masking_flag
diff --git a/Framework/PythonInterface/plugins/algorithms/SNAPReduce.py b/Framework/PythonInterface/plugins/algorithms/SNAPReduce.py
new file mode 100644
index 0000000000000000000000000000000000000000..828cdfd60ea5d648334820305e263b4e1db393d5
--- /dev/null
+++ b/Framework/PythonInterface/plugins/algorithms/SNAPReduce.py
@@ -0,0 +1,444 @@
+# pylint: disable=invalid-name,no-init,too-many-lines
+from __future__ import (absolute_import, division, print_function)
+from mantid.kernel import Direction, FloatArrayProperty, IntArrayBoundedValidator, \
+    IntArrayProperty, StringListValidator
+from mantid.api import AlgorithmFactory, DataProcessorAlgorithm, FileAction, FileProperty, \
+    PropertyMode, WorkspaceProperty
+from mantid.simpleapi import AlignDetectors, CloneWorkspace, CompressEvents, \
+    ConvertUnits, CreateGroupingWorkspace, CropWorkspace, DeleteWorkspace, DiffractionFocussing, \
+    Divide, EditInstrumentGeometry, GetIPTS, Load, LoadDetectorsGroupingFile, LoadMask, \
+    LoadNexusProcessed, LoadPreNexusLive, MaskDetectors, NormaliseByCurrent, \
+    PreprocessDetectorsToMD, Rebin, RenameWorkspace, ReplaceSpecialValues, RemovePromptPulse, \
+    SaveAscii, SaveFocusedXYE, SaveGSS, SaveNexusProcessed, mtd
+import os
+import numpy as np
+
+
+class SNAPReduce(DataProcessorAlgorithm):
+    IPTS_dir = None
+
+    def get_IPTS_Local(self, run):
+        if self.IPTS_dir is None:
+            self.IPTS_dir = GetIPTS(Instrument='SNAP',
+                                    RunNumber=str(run))
+        return self.IPTS_dir
+
+    def smooth(self, data, order):
+        # This smooths data based on linear weigthed average around
+        # point i for example for an order of 7 the i point is
+        # weighted 4, i=/- 1 weighted 3, i+/-2 weighted 2 and i+/-3
+        # weighted 1 this input is only the y values
+        sm = np.zeros(len(data))
+        factor = order / 2 + 1
+
+        for i in range(len(data)):
+            temp = 0
+            ave = 0
+            for r in range(max(0, i - int(order / 2)),
+                           min(i + int(order / 2), len(data) - 1) + 1):
+                temp = temp + (factor - abs(r - i)) * data[r]
+                ave = ave + factor - abs(r - i)
+            sm[i] = temp / ave
+
+        return sm
+
+    def LLS_transformation(self, input):
+        # this transforms data to be more sensitive to weak peaks. The
+        # function is reversed by the Inv_LLS function below
+        out = np.log(np.log((input + 1)**0.5 + 1) + 1)
+
+        return out
+
+    def Inv_LLS_transformation(self, input):
+        # See Function LLS function above
+        out = (np.exp(np.exp(input) - 1) - 1)**2 - 1
+
+        return out
+
+    def peak_clip(self, data, win=30, decrese=True, LLS=True, smooth_window=0):
+        start_data = np.copy(data)
+
+        window = win
+        self.log().information(str(smooth_window))
+
+        if smooth_window > 0:
+            data = self.smooth(data, smooth_window)
+
+        if LLS:
+            data = self.LLS_transformation(data)
+
+        temp = data.copy()
+
+        if decrese:
+            scan = list(range(window + 1, 0, -1))
+        else:
+            scan = list(range(1, window + 1))
+
+        for w in scan:
+            for i in range(len(temp)):
+                if i < w or i > (len(temp) - w - 1):
+                    continue
+                else:
+                    win_array = temp[i - w:i + w + 1].copy()
+                    win_array_reversed = win_array[::-1]
+                    average = (win_array + win_array_reversed) / 2
+                    temp[i] = np.min(average[:len(average) / 2])
+
+        if LLS:
+            temp = self.Inv_LLS_transformation(temp)
+
+        self.log().information(str(min(start_data - temp)))
+
+        index = np.where((start_data - temp) == min(start_data - temp))[0][0]
+
+        output = temp * (start_data[index] / temp[index])
+
+        return output
+
+    def category(self):
+        return "Diffraction\\Reduction"
+
+    def PyInit(self):
+
+        validator = IntArrayBoundedValidator()
+        validator.setLower(0)
+        self.declareProperty(IntArrayProperty("RunNumbers", values=[0], direction=Direction.Input,
+                                              validator=validator),
+                             "Run numbers to process, comma separated")
+
+        self.declareProperty("LiveData", False,
+                             "Read live data - requires a saved run in the current IPTS "
+                             + "with the same Instrument configuration as the live run")
+
+        mask = ["None", "Horizontal", "Vertical",
+                "Masking Workspace", "Custom - xml masking file"]
+        self.declareProperty("Masking", "None", StringListValidator(mask),
+                             "Mask to be applied to the data")
+
+        self.declareProperty(WorkspaceProperty("MaskingWorkspace", "",
+                                               Direction.Input, PropertyMode.Optional),
+                             "The workspace containing the mask.")
+
+        self.declareProperty(FileProperty(name="MaskingFilename", defaultValue="",
+                                          direction=Direction.Input,
+                                          action=FileAction.OptionalLoad),
+                             doc="The file containing the xml mask.")
+
+        self.declareProperty(name="Calibration", defaultValue="Convert Units",
+                             validator=StringListValidator(
+                                 ["Convert Units", "Calibration File"]),
+                             direction=Direction.Input,
+                             doc="The type of conversion to d_spacing to be used.")
+
+        self.declareProperty(FileProperty(name="CalibrationFilename", defaultValue="",
+                                          direction=Direction.Input,
+                                          action=FileAction.OptionalLoad),
+                             doc="The calibration file to convert to d_spacing.")
+
+        self.declareProperty(FloatArrayProperty("Binning", [0.5, -0.004, 7.0]),
+                             "Min, Step, and Max of d-space bins.  Logarithmic binning is used if Step is negative.")
+
+        nor_corr = ["None", "From Workspace",
+                    "From Processed Nexus", "Extracted from Data"]
+        self.declareProperty("Normalization", "None", StringListValidator(nor_corr),
+                             "If needed what type of input to use as normalization, Extracted from "
+                             + "Data uses a background determination that is peak independent.This "
+                             + "implemantation can be tested in algorithm SNAP Peak Clipping Background")
+
+        self.declareProperty(FileProperty(name="NormalizationFilename", defaultValue="",
+                                          direction=Direction.Input,
+                                          action=FileAction.OptionalLoad),
+                             doc="The file containing the processed nexus for normalization.")
+
+        self.declareProperty(WorkspaceProperty("NormalizationWorkspace", "",
+                                               Direction.Input, PropertyMode.Optional),
+                             "The workspace containing the normalization data.")
+
+        self.declareProperty("PeakClippingWindowSize", 10,
+                             "Read live data - requires a saved run in the current "
+                             + "IPTS with the same Instrumnet configuration")
+
+        self.declareProperty("SmoothingRange", 10,
+                             "Read live data - requires a saved run in the "
+                             + "current IPTS with the same Instrumnet configuration")
+
+        grouping = ["All", "Column", "Banks", "Modules", "2_4 Grouping"]
+        self.declareProperty("GroupDetectorsBy", "All", StringListValidator(grouping),
+                             "Detector groups to use for future focussing: "
+                             + "All detectors as one group, Groups (East,West for "
+                             + "SNAP), Columns for SNAP, detector banks")
+
+        mode = ["Set-Up", "Production"]
+        self.declareProperty("ProcessingMode", "Production", StringListValidator(mode),
+                             "Set-Up Mode is used for establishing correct parameters. Production "
+                             + "Mode only Normalized workspace is kept for each run.")
+
+        self.declareProperty(name="OptionalPrefix", defaultValue="",
+                             direction=Direction.Input,
+                             doc="Optional Prefix to be added to workspaces and output filenames")
+
+        self.declareProperty("SaveData", False,
+                             "Save data in the following formats: Ascii- "
+                             + "d-spacing ,Nexus Processed,GSAS and Fullprof")
+
+        self.declareProperty(FileProperty(name="OutputDirectory", defaultValue="",
+                                          action=FileAction.OptionalDirectory),
+                             doc='Default value is proposal shared directory')
+
+    def validateInputs(self):
+        issues = dict()
+
+        # cross check masking
+        masking = self.getProperty("Masking").value
+        if masking in ("None", "Horizontal", "Vertical"):
+            pass
+        elif masking in ("Custom - xml masking file"):
+            filename = self.getProperty("MaskingFilename").value
+            if len(filename) <= 0:
+                issues[
+                    "MaskingFilename"] = "Masking=\"%s\" requires a filename" % masking
+        elif masking == "Masking Workspace":
+            mask_workspace = self.getPropertyValue("MaskingWorkspace")
+            if mask_workspace is None or len(mask_workspace) <= 0:
+                issues["MaskingWorkspace"] = "Must supply masking workspace"
+        else:
+            raise RuntimeError("Masking value \"%s\" not supported" % masking)
+
+        # cross check normalization
+        normalization = self.getProperty("Normalization").value
+        if normalization in ("None", "Extracted from Data"):
+            pass
+        elif normalization == "From Workspace":
+            norm_workspace = self.getPropertyValue("NormalizationWorkspace")
+            if norm_workspace is None:
+                issues['NormalizationWorkspace'] = 'Cannot be unset'
+        elif normalization == "From Processed Nexus":
+            filename = self.getProperty("NormalizationFilename").value
+            if len(filename) <= 0:
+                issues["NormalizationFilename"] = "Normalization=\"%s\" requires a filename" \
+                                                  % normalization
+        else:
+            raise RuntimeError(
+                "Normalization value \"%s\" not supported" % normalization)
+
+        return issues
+
+    def _getMaskWSname(self):
+        masking = self.getProperty("Masking").value
+        maskWSname = None
+        if masking == 'Custom - xml masking file':
+            maskWSname = 'CustomMask'
+            LoadMask(InputFile=self.getProperty('MaskingFilename').value,
+                     Instrument='SNAP', OutputWorkspace=maskWSname)
+        elif masking == 'Horizontal':
+            maskWSname = 'HorizontalMask'
+            if not mtd.doesExist('HorizontalMask'):
+                LoadMask(InputFile='/SNS/SNAP/shared/libs/Horizontal_Mask.xml',
+                         Instrument='SNAP', OutputWorkspace=maskWSname)
+        elif masking == 'Vertical':
+            maskWSname = 'VerticalMask'
+            if not mtd.doesExist('VerticalMask'):
+                LoadMask(InputFile='/SNS/SNAP/shared/libs/Vertical_Mask.xml',
+                         Instrument='SNAP', OutputWorkspace=maskWSname)
+        elif masking == "Masking Workspace":
+            maskWSname = str(self.getProperty("MaskingWorkspace").value)
+
+        return maskWSname
+
+    def _generateNormalization(self, WS, normType, normWS):
+        if normType == 'None':
+            return None
+        elif normType == "Extracted from Data":
+            window = self.getProperty("PeakClippingWindowSize").value
+
+            smooth_range = self.getProperty("SmoothingRange").value
+
+            peak_clip_WS = CloneWorkspace(WS)
+            n_histo = peak_clip_WS.getNumberHistograms()
+
+            x = peak_clip_WS.extractX()
+            y = peak_clip_WS.extractY()
+            e = peak_clip_WS.extractE()
+
+            for h in range(n_histo):
+                peak_clip_WS.setX(h, x[h])
+                peak_clip_WS.setY(h, self.peak_clip(y[h], win=window, decrese=True,
+                                                    LLS=True, smooth_window=smooth_range))
+                peak_clip_WS.setE(h, e[h])
+            return peak_clip_WS
+        else: # other values are already held in normWS
+            return normWS
+
+    def _save(self, runnumber, basename, norm):
+        if not self.getProperty("SaveData").value:
+            return
+
+        saveDir = self.getProperty("OutputDirectory").value.strip()
+        if len(saveDir) <= 0:
+            self.log().notice('Using default save location')
+            saveDir = os.path.join(
+                self.get_IPTS_Local(runnumber), 'shared', 'data')
+        self.log().notice('Writing to \'' + saveDir + '\'')
+
+        if norm == 'None':
+            SaveNexusProcessed(InputWorkspace='WS_red',
+                               Filename=os.path.join(saveDir, 'nexus', basename + '.nxs'))
+            SaveAscii(InputWorkspace='WS_red',
+                      Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat'))
+            ConvertUnits(InputWorkspace='WS_red', OutputWorkspace='WS_tof',
+                         Target="TOF", AlignBins=False)
+        else:
+            SaveNexusProcessed(InputWorkspace='WS_nor',
+                               Filename=os.path.join(saveDir, 'nexus', basename + '.nxs'))
+            SaveAscii(InputWorkspace='WS_nor',
+                      Filename=os.path.join(saveDir, 'd_spacing', basename + '.dat'))
+            ConvertUnits(InputWorkspace='WS_nor', OutputWorkspace='WS_tof',
+                         Target="TOF", AlignBins=False)
+
+        SaveGSS(InputWorkspace='WS_tof',
+                Filename=os.path.join(saveDir, 'gsas', basename + '.gsa'),
+                Format='SLOG', SplitFiles=False, Append=False, ExtendedHeader=True)
+        SaveFocusedXYE(InputWorkspace='WS_tof',
+                       Filename=os.path.join(
+                           saveDir, 'fullprof', basename + '.dat'),
+                       SplitFiles=True, Append=False)
+        DeleteWorkspace(Workspace='WS_tof')
+
+    def PyExec(self):
+        # Retrieve all relevant notice
+
+        in_Runs = self.getProperty("RunNumbers").value
+
+        maskWSname = self._getMaskWSname()
+
+        calib = self.getProperty("Calibration").value
+        if calib == "Calibration File":
+            cal_File = self.getProperty("CalibrationFilename").value
+
+        params = self.getProperty("Binning").value
+        norm = self.getProperty("Normalization").value
+
+        if norm == "From Processed Nexus":
+            norm_File = self.getProperty("Normalization filename").value
+            normWS = LoadNexusProcessed(Filename=norm_File)
+        elif norm == "From Workspace":
+            normWS = self.getProperty("NormalizationWorkspace").value
+        else:
+            normWS = None
+
+        group_to_real = {'Banks':'Group', 'Modules':'bank', '2_4 Grouping':'2_4_Grouping'}
+        group = self.getProperty("GroupDetectorsBy").value
+        real_name = group_to_real.get(group, group)
+
+        if not mtd.doesExist(group):
+            if group == "2_4 Grouping":
+                group = real_name
+                LoadDetectorsGroupingFile(InputFile=r'/SNS/SNAP/shared/libs/SNAP_group_2_4.xml',
+                                          OutputWorkspace=group)
+            else:
+                CreateGroupingWorkspace(InstrumentName='SNAP', GroupDetectorsBy=real_name,
+                                        OutputWorkspace=group)
+
+        Process_Mode = self.getProperty("ProcessingMode").value
+
+        prefix = self.getProperty("OptionalPrefix").value
+
+        # --------------------------- REDUCE DATA -----------------------------
+
+        Tag = 'SNAP'
+        for r in in_Runs:
+            self.log().notice("processing run %s" % r)
+            self.log().information(str(self.get_IPTS_Local(r)))
+            if self.getProperty("LiveData").value:
+                Tag = 'Live'
+                WS = LoadPreNexusLive(Instrument='SNAP')
+            else:
+                WS = Load(Filename='SNAP' + str(r), Outputworkspace='WS')
+                WS = NormaliseByCurrent(InputWorkspace=WS,
+                                        Outputworkspace='WS')
+
+            WS = CompressEvents(InputWorkspace=WS, Outputworkspace='WS')
+            WS = CropWorkspace(InputWorkspace='WS',
+                               OutputWorkspace='WS', XMax=50000)
+            WS = RemovePromptPulse(InputWorkspace=WS, OutputWorkspace='WS',
+                                   Width='1600', Frequency='60.4')
+
+            if maskWSname is not None:
+                WS = MaskDetectors(Workspace=WS, MaskedWorkspace=maskWSname)
+
+            if calib == "Convert Units":
+                WS_d = ConvertUnits(InputWorkspace='WS',
+                                    Target='dSpacing', Outputworkspace='WS_d')
+            else:
+                self.log().notice("\n calibration file : %s" % cal_File)
+                WS_d = AlignDetectors(
+                    InputWorkspace='WS', CalibrationFile=cal_File, Outputworkspace='WS_d')
+
+            WS_d = Rebin(InputWorkspace=WS_d, Params=params,
+                         Outputworkspace='WS_d')
+
+            WS_red = DiffractionFocussing(InputWorkspace=WS_d, GroupingWorkspace=group,
+                                          PreserveEvents=False)
+
+            normWS = self._generateNormalization(WS_red, norm, normWS)
+            WS_nor = None
+            if normWS is not None:
+                WS_nor = Divide(LHSWorkspace=WS_red, RHSWorkspace=normWS)
+                WS_nor = ReplaceSpecialValues(Inputworkspace=WS_nor,
+                                              NaNValue='0', NaNError='0',
+                                              InfinityValue='0', InfinityError='0')
+
+            new_Tag = Tag
+            if len(prefix) > 0:
+                new_Tag += '_' + prefix
+
+            # Edit instrument geomety to make final workspace smaller on disk
+            det_table = PreprocessDetectorsToMD(Inputworkspace='WS_red',
+                                                OutputWorkspace='__SNAP_det_table')
+            polar = np.degrees(det_table.column('TwoTheta'))
+            azi = np.degrees(det_table.column('Azimuthal'))
+            EditInstrumentGeometry(Workspace="WS_red", L2=det_table.column('L2'),
+                                   Polar=polar, Azimuthal=azi)
+            if WS_nor is not None:
+                EditInstrumentGeometry(Workspace="WS_nor", L2=det_table.column('L2'),
+                                       Polar=polar, Azimuthal=azi)
+            mtd.remove('__SNAP_det_table')
+
+            # Save requested formats
+            basename = '%s_%s_%s' % (new_Tag, r, group)
+            self._save(r, basename, norm)
+
+            # temporary workspace no longer needed
+            DeleteWorkspace(Workspace='WS')
+
+            # rename everything as appropriate and determine output workspace name
+            RenameWorkspace(Inputworkspace='WS_d',
+                            OutputWorkspace='%s_%s_d' % (new_Tag, r))
+            RenameWorkspace(Inputworkspace='WS_red',
+                            OutputWorkspace=basename + '_red')
+            if norm == 'None':
+                outputWksp = basename + '_red'
+            else:
+                outputWksp = basename + '_nor'
+                RenameWorkspace(Inputworkspace='WS_nor',
+                                OutputWorkspace=basename + '_nor')
+            if norm == "Extracted from Data":
+                RenameWorkspace(Inputworkspace='peak_clip_WS',
+                                OutputWorkspace='%s_%s_normalizer' % (new_Tag, r))
+
+            # delte some things in production
+            if Process_Mode == "Production":
+                DeleteWorkspace(Workspace='%s_%s_d' % (new_Tag, r)) # was 'WS_d'
+
+                if norm != "None":
+                    DeleteWorkspace(Workspace=basename + '_red') # was 'WS_red'
+
+                if norm == "Extracted from Data":
+                    DeleteWorkspace(Workspace='%s_%s_normalizer' % (new_Tag, r)) # was 'peak_clip_WS'
+
+            propertyName = 'OutputWorkspace'
+            self.declareProperty(WorkspaceProperty(
+                propertyName, outputWksp, Direction.Output))
+            self.setProperty(propertyName, outputWksp)
+
+AlgorithmFactory.subscribe(SNAPReduce)
diff --git a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
index 838e13e6c3f6ef76f663d0aeb865d0d51f844720..376a9d879ae6551219b96aeb8a30d95f90c5149c 100644
--- a/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
+++ b/Framework/PythonInterface/plugins/algorithms/SNSPowderReduction.py
@@ -95,6 +95,8 @@ def allEventWorkspaces(*args):
 
 
 def getBasename(filename):
+    if type(filename) == list:
+        filename = filename[0]
     name = os.path.split(filename)[-1]
     for extension in EXTENSIONS_NXS:
         name = name.replace(extension, '')
@@ -268,6 +270,11 @@ class SNSPowderReduction(DataProcessorAlgorithm):
         self._outTypes = self.getProperty("SaveAs").value.lower()
 
         samRuns = self.getProperty("Filename").value
+        if type(samRuns[0]) == list:
+            linearizedRuns = []
+            for item in samRuns:
+                linearizedRuns.extend(item)
+            samRuns = linearizedRuns[:] # deep copy
         self._determineInstrument(samRuns[0])
 
         preserveEvents = self.getProperty("PreserveEvents").value
@@ -973,24 +980,22 @@ class SNSPowderReduction(DataProcessorAlgorithm):
         # Determine characterization
         if mtd.doesExist("characterizations"):
             # get the correct row of the table if table workspace 'charactersizations' exists
-
-            #pylint: disable=unused-variable
-            charac = api.PDDetermineCharacterizations(InputWorkspace=wksp_name,
-                                                      Characterizations="characterizations",
-                                                      ReductionProperties="__snspowderreduction",
-                                                      BackRun=self.getProperty("BackgroundNumber").value,
-                                                      NormRun=self.getProperty("VanadiumNumber").value,
-                                                      NormBackRun=self.getProperty("VanadiumBackgroundNumber").value,
-                                                      FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
-                                                      WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value)
+            api.PDDetermineCharacterizations(InputWorkspace=wksp_name,
+                                             Characterizations="characterizations",
+                                             ReductionProperties="__snspowderreduction",
+                                             BackRun=self.getProperty("BackgroundNumber").value,
+                                             NormRun=self.getProperty("VanadiumNumber").value,
+                                             NormBackRun=self.getProperty("VanadiumBackgroundNumber").value,
+                                             FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
+                                             WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value)
         else:
-            charac = api.PDDetermineCharacterizations(InputWorkspace=wksp_name,
-                                                      ReductionProperties="__snspowderreduction",
-                                                      BackRun=self.getProperty("BackgroundNumber").value,
-                                                      NormRun=self.getProperty("VanadiumNumber").value,
-                                                      NormBackRun=self.getProperty("VanadiumBackgroundNumber").value,
-                                                      FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
-                                                      WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value)
+            api.PDDetermineCharacterizations(InputWorkspace=wksp_name,
+                                             ReductionProperties="__snspowderreduction",
+                                             BackRun=self.getProperty("BackgroundNumber").value,
+                                             NormRun=self.getProperty("VanadiumNumber").value,
+                                             NormBackRun=self.getProperty("VanadiumBackgroundNumber").value,
+                                             FrequencyLogNames=self.getProperty("FrequencyLogNames").value,
+                                             WaveLengthLogNames=self.getProperty("WaveLengthLogNames").value)
 
         # convert the result into a dict
         return PropertyManagerDataService.retrieve("__snspowderreduction")
diff --git a/Framework/PythonInterface/plugins/algorithms/VisionLoadDetectorTable.py b/Framework/PythonInterface/plugins/algorithms/VisionLoadDetectorTable.py
deleted file mode 100644
index c637316e76acb79dc236e3aa6440fafce838c5da..0000000000000000000000000000000000000000
--- a/Framework/PythonInterface/plugins/algorithms/VisionLoadDetectorTable.py
+++ /dev/null
@@ -1,49 +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 numpy as np
-
-
-class VisionLoadDetectorTable(PythonAlgorithm):
-
-    def category(self):
-        return "Utility\\Development"
-
-    def summary(self):
-        return "Warning - This is under development - Algorithm to load detector parameters for VISION."
-
-    def PyInit(self):
-        self.declareProperty(WorkspaceProperty("OutputWorkspace", "", Direction.Output),
-                             doc="Name of Output Workspace")
-
-        self.declareProperty(FileProperty("DetectorFile", "", action=FileAction.Load, extensions=['csv']),
-                             doc="Name of detector file to load.")
-
-    def PyExec(self):
-        filename = self.getPropertyValue("DetectorFile")
-        output_ws_name = self.getPropertyValue("OutputWorkspace")
-
-        # Open File and read parameters
-        spectra,l1,l2,twotheta,efixed,emode = np.genfromtxt(filename, delimiter=',', unpack=True)
-
-        # Setup the output table
-        output_workspace = CreateEmptyTableWorkspace(OutputWorkspace=output_ws_name)
-        output_workspace.addColumn("int", "spectra")
-        output_workspace.addColumn("double", "l1")
-        output_workspace.addColumn("double", "l2")
-        output_workspace.addColumn("double", "twotheta")
-        output_workspace.addColumn("double", "efixed")
-        output_workspace.addColumn("int", "emode")
-
-        # Write the values
-        for i in range(len(spectra)):
-            output_workspace.addRow([int(spectra[i]),float(l1[i]),float(l2[i]),
-                                     float(twotheta[i]),float(efixed[i]),int(emode[i])])
-
-        # Set the output workspace
-        self.setProperty("OutputWorkspace", output_workspace)
-
-AlgorithmFactory.subscribe(VisionLoadDetectorTable)
diff --git a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSPatchSensitivity.py b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSPatchSensitivity.py
index 4ea35add8b688aa50e718da6c70d220d65d825e2..79b8267025011dd3d8ab77b9f4e19e8cc058ebfc 100644
--- a/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSPatchSensitivity.py
+++ b/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/SANSPatchSensitivity.py
@@ -97,15 +97,17 @@ class SANSPatchSensitivity(PythonAlgorithm):
         # Array that will be fit
         id_to_fit =[]
 
+        patchDetInfo = patch_ws.detectorInfo()
+        inputDetInfo = in_ws.detectorInfo()
         for pixel_idx in range(tube_in_input_ws.nelements()):
             pixel_in_input_ws = tube_in_input_ws[pixel_idx]
             # ID will be the same in both WS
             detector_id = pixel_in_input_ws.getID()
-            pixel_in_patch_ws  = patch_ws.getInstrument().getDetector(detector_id)
+            detector_idx = detector_id - 1 # See note on hack below
 
-            if pixel_in_patch_ws.isMasked():
+            if patchDetInfo.isMasked(detector_idx):
                 id_to_fit.append(detector_id)
-            elif not pixel_in_input_ws.isMasked():
+            elif not inputDetInfo.isMasked(detector_idx):
                 id_to_calculate_fit.append(detector_id)
                 y_to_calculate_fit.append(in_ws.readY(detector_id).sum())
                 e_to_calculate_fit.append(in_ws.readE(detector_id).sum())
diff --git a/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt
index 32ef42ce2a60ae3ffb2fd25f8afdf5604a9d1a59..ec02457d0a012869f20e9968d680309b78c97a06 100644
--- a/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/mantid/api/CMakeLists.txt
@@ -14,6 +14,7 @@ set ( TEST_PY_FILES
   CompositeFunctionTest.py
   DataProcessorAlgorithmTest.py
   DeprecatedAlgorithmCheckerTest.py
+  DetectorInfoTest.py
   ExperimentInfoTest.py
   FilePropertyTest.py
   FileFinderTest.py
@@ -42,6 +43,7 @@ set ( TEST_PY_FILES
   RunPythonScriptTest.py
   RunTest.py
   SampleTest.py
+  SpectrumInfoTest.py
   WorkspaceFactoryTest.py
   WorkspaceTest.py
   WorkspaceGroupTest.py
diff --git a/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py b/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..efac03965c6f05761ee13ee2361994f4eec67f16
--- /dev/null
+++ b/Framework/PythonInterface/test/python/mantid/api/DetectorInfoTest.py
@@ -0,0 +1,29 @@
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+from testhelpers import WorkspaceCreationHelper
+
+class DetectorInfoTest(unittest.TestCase):
+
+    _ws = None
+
+    def setUp(self):
+        if self.__class__._ws is None:
+            self.__class__._ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(2, 1, False) # no monitors
+            self.__class__._ws.getSpectrum(0).clearDetectorIDs()
+
+    def test_len(self):
+        info = self._ws.detectorInfo()
+        self.assertEquals(len(info), 2)
+
+    def test_size(self):
+        info = self._ws.detectorInfo()
+        self.assertEquals(info.size(), 2)
+
+    def test_isMasked(self):
+        info = self._ws.detectorInfo()
+        self.assertEquals(info.isMasked(0), False)
+        self.assertEquals(info.isMasked(1), False)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Framework/PythonInterface/test/python/mantid/api/ExperimentInfoTest.py b/Framework/PythonInterface/test/python/mantid/api/ExperimentInfoTest.py
index a3dcb89eebae4a2a4dde7a75f72f03ebb23d9ea2..2a6a947c94c6d316f9568aaed39957c77d1d4448 100644
--- a/Framework/PythonInterface/test/python/mantid/api/ExperimentInfoTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/ExperimentInfoTest.py
@@ -38,6 +38,11 @@ class ExperimentInfoTest(unittest.TestCase):
         emode = self._expt_ws.getEMode()
         self.assertEquals(emode, 0)
 
+    def test_detectorInfo(self):
+        detInfo = self._expt_ws.detectorInfo()
+        # No instrument in test workspace, so size is 0.
+        self.assertEquals(detInfo.size(), 0)
+
 #    def test_set_and_get_efixed(self):
 #      ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(1, 5, False, False)
 #        ws.setEFixed(1, pi)
diff --git a/Framework/PythonInterface/test/python/mantid/api/IEventWorkspaceTest.py b/Framework/PythonInterface/test/python/mantid/api/IEventWorkspaceTest.py
index 3d15adc37df27b4af48a8e8bff91aa6cad719c39..e50cfbb3dbe49f5ca12593b5b499a5f8c0004e64 100644
--- a/Framework/PythonInterface/test/python/mantid/api/IEventWorkspaceTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/IEventWorkspaceTest.py
@@ -16,7 +16,7 @@ class IEventWorkspaceTest(unittest.TestCase):
     def setUp(self):
         if self._test_ws is None:
             self.__class__._test_ws = \
-              WorkspaceCreationHelper.CreateEventWorkspace2(self._npixels, self._nbins)
+              WorkspaceCreationHelper.createEventWorkspace2(self._npixels, self._nbins)
 
     def test_that_it_cannot_be_directly_instantiated(self):
         self.assertFalse(can_be_instantiated(IEventWorkspace))
diff --git a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
index 4cb7a3ef526e11f10f0ed24b62eb770747c7ceaa..79315fc51cbe48b60ee0a27ee97110f76b5a4812 100644
--- a/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
+++ b/Framework/PythonInterface/test/python/mantid/api/MatrixWorkspaceTest.py
@@ -68,7 +68,6 @@ class MatrixWorkspaceTest(unittest.TestCase):
         det = self._test_ws.getDetector(0)
         self.assertTrue(isinstance(det, Detector))
         self.assertEquals(det.getID(), 1)
-        self.assertFalse(det.isMasked())
         self.assertAlmostEqual(math.pi, det.getTwoTheta(V3D(0,0,11), V3D(0,0,1)))
 
     def test_spectrum_retrieval(self):
@@ -385,6 +384,11 @@ class MatrixWorkspaceTest(unittest.TestCase):
             pass
         self.assertTrue(allFine)
 
+    def test_spectrumInfo(self):
+        specInfo = self._test_ws.spectrumInfo()
+        self.assertEquals(specInfo.isMasked(0), False)
+        self.assertEquals(specInfo.isMasked(1), False)
+
 if __name__ == '__main__':
     unittest.main()
     #Testing particular test from Mantid
diff --git a/Framework/PythonInterface/test/python/mantid/api/SpectrumInfoTest.py b/Framework/PythonInterface/test/python/mantid/api/SpectrumInfoTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..920386145e0c2366b3d724c2b16ac535edd81575
--- /dev/null
+++ b/Framework/PythonInterface/test/python/mantid/api/SpectrumInfoTest.py
@@ -0,0 +1,25 @@
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+from testhelpers import WorkspaceCreationHelper
+
+class SpectrumInfoTest(unittest.TestCase):
+
+    _ws = None
+
+    def setUp(self):
+        if self.__class__._ws is None:
+            self.__class__._ws = WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(2, 1, False) # no monitors
+            self.__class__._ws.getSpectrum(0).clearDetectorIDs()
+
+    def test_hasDetectors(self):
+        info = self._ws.spectrumInfo()
+        self.assertEquals(info.hasDetectors(0), False)
+        self.assertEquals(info.hasDetectors(1), True)
+
+    def test_isMasked(self):
+        info = self._ws.spectrumInfo()
+        self.assertEquals(info.isMasked(1), False)
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt b/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
index 09f142957477ef35b5d8365b119fbb793785691d..d0928e72b0e0391548856c27f66ab25179bcf123 100644
--- a/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
+++ b/Framework/PythonInterface/test/python/mantid/kernel/CMakeLists.txt
@@ -16,6 +16,7 @@ set ( TEST_PY_FILES
   InstrumentInfoTest.py
   IPropertySettingsTest.py
   ListValidatorTest.py
+  LiveListenerInfoTest.py
   LogFilterTest.py
   LoggerTest.py
   MandatoryValidatorTest.py
diff --git a/Framework/PythonInterface/test/python/mantid/kernel/FacilityInfoTest.py b/Framework/PythonInterface/test/python/mantid/kernel/FacilityInfoTest.py
index 92295a915efd4dc03c02d04883eb6d130c398231..c26dc1d6941a33dfa76e997d14e1509681777ce7 100644
--- a/Framework/PythonInterface/test/python/mantid/kernel/FacilityInfoTest.py
+++ b/Framework/PythonInterface/test/python/mantid/kernel/FacilityInfoTest.py
@@ -3,6 +3,7 @@ from __future__ import (absolute_import, division, print_function)
 import unittest
 from mantid.kernel import FacilityInfo, InstrumentInfo, ConfigService
 
+
 class FacilityInfoTest(unittest.TestCase):
 
     def test_construction_raies_an_error(self):
@@ -23,7 +24,8 @@ class FacilityInfoTest(unittest.TestCase):
         self.assertTrue(len(test_facility.instruments()) > 30)
         self.assertTrue(len(test_facility.instruments("Neutron Diffraction"))> 10)
         self.assertTrue(isinstance(test_facility.instrument("WISH"), InstrumentInfo))
-        self.assertEquals(test_facility.liveListener(), "ISISHistoDataListener")
+
 
 if __name__ == '__main__':
     unittest.main()
+
diff --git a/Framework/PythonInterface/test/python/mantid/kernel/InstrumentInfoTest.py b/Framework/PythonInterface/test/python/mantid/kernel/InstrumentInfoTest.py
index cb840530d5bce21c7a39807c1d6c4ecc4dfadbe8..dbd30304e1d59791da9950bd864a2bad418e52f0 100644
--- a/Framework/PythonInterface/test/python/mantid/kernel/InstrumentInfoTest.py
+++ b/Framework/PythonInterface/test/python/mantid/kernel/InstrumentInfoTest.py
@@ -3,16 +3,39 @@ from __future__ import (absolute_import, division, print_function)
 import unittest
 from mantid.kernel import InstrumentInfo, ConfigService
 
-class InstrumentInfoTest(object):
+
+class InstrumentInfoTest(unittest.TestCase):
+    def _get_test_instrument(self):
+        facility = ConfigService.getFacility("ISIS")
+        return facility.instrument("CRISP")
 
     def test_construction_raies_an_error(self):
         self.assertRaises(RuntimeError, InstrumentInfo)
 
-    def test_instrument_name(self):
-        pass
+    def test_instrument_attributes(self):
+        inst = self._get_test_instrument()
+
+        # Just testing functionality; values can be updated if needed
+        self.assertEquals(inst.name(), "CRISP")
+        self.assertEquals(inst.shortName(), "CSP")
+        self.assertEquals(str(inst), "CSP")
+        self.assertEquals(inst.zeroPadding(99777), 5)
+        self.assertEquals(inst.zeroPadding(99778), 8)
+        self.assertEquals(inst.filePrefix(99777), "CSP")
+        self.assertEquals(inst.filePrefix(99778), "CRISP")
+        self.assertEquals(inst.delimiter(), "")
+        self.assertEquals(str(inst.techniques()), "set('Reflectometry')")
+        self.assertEquals(inst.facility().name(), "ISIS")
+        self.assertEquals(inst.liveListener(), "ISISHistoDataListener")
+        self.assertEquals(inst.liveListener("histo"), "ISISHistoDataListener")
+        self.assertRaises(RuntimeError, inst.liveListener, "invalid_name")
+        self.assertEquals(inst.liveDataAddress(), "NDXCRISP:6789")
+        self.assertEquals(inst.liveDataAddress("histo"), "NDXCRISP:6789")
+        self.assertRaises(RuntimeError, inst.liveDataAddress, "invalid_name")
+        self.assertTrue(inst.hasLiveListenerInfo())
+        self.assertEqual(len(inst.liveListenerInfoList()), 1)
 
-    def test_instrument_shortName(self):
-        pass
 
 if __name__ == '__main__':
     unittest.main()
+
diff --git a/Framework/PythonInterface/test/python/mantid/kernel/LiveListenerInfoTest.py b/Framework/PythonInterface/test/python/mantid/kernel/LiveListenerInfoTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..9511132114bd5360707f812e5056d6acc81d7d09
--- /dev/null
+++ b/Framework/PythonInterface/test/python/mantid/kernel/LiveListenerInfoTest.py
@@ -0,0 +1,26 @@
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+from mantid.kernel import LiveListenerInfo, ConfigService
+
+
+class LiveListenerInfoTest(unittest.TestCase):
+    def _get_test_listener(self):
+        facility = ConfigService.getFacility("ISIS")
+        return facility.instrument("CRISP").liveListenerInfo()
+
+    def test_construction_raies_an_error(self):
+        self.assertRaises(RuntimeError, LiveListenerInfo)
+
+    def test_listener_attributes(self):
+        info = self._get_test_listener()
+
+        # Just testing functionality; values can be updated if needed
+        self.assertEquals(info.name(), "histo")
+        self.assertEquals(info.listener(), "ISISHistoDataListener")
+        self.assertEquals(info.address(), "NDXCRISP:6789")
+
+
+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 44b7eaa7b13d5fdc3bef0c64db687ae8403d7688..8056afe9f1896b09491af8bd870f903ec67b6f45 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/MaskAngleTest.py
@@ -12,11 +12,12 @@ class MaskAngleTest(unittest.TestCase):
         w=WorkspaceCreationHelper.create2DWorkspaceWithFullInstrument(30,5,False,False)
         AnalysisDataService.add('w',w)
         masklist = MaskAngle(w,10,20)
-        for i in arange(w.getNumberHistograms())+1:
-            if (i<10) or (i>19):
-                self.assertTrue(not w.getInstrument().getDetector(int(i)).isMasked())
+        detInfo = w.detectorInfo()
+        for i in arange(w.getNumberHistograms()):
+            if (i<9) or (i>18):
+                self.assertFalse(detInfo.isMasked(int(i)))
             else:
-                self.assertTrue(w.getInstrument().getDetector(int(i)).isMasked())
+                self.assertTrue(detInfo.isMasked(int(i)))
         DeleteWorkspace(w)
         self.assertTrue(array_equal(masklist,arange(10)+10))
 
@@ -30,11 +31,12 @@ class MaskAngleTest(unittest.TestCase):
         MaskAngle(group, 10, 20)
 
         for w in group:
-            for i in arange(w.getNumberHistograms())+1:
-                if(i<10) or (i>19):
-                    self.assertTrue(not w.getInstrument().getDetector(int(i)).isMasked())
+            detInfo = w.detectorInfo()
+            for i in arange(w.getNumberHistograms()):
+                if(i<9) or (i>18):
+                    self.assertFalse(detInfo.isMasked(int(i)))
                 else:
-                    self.assertTrue(w.getInstrument().getDetector(int(i)).isMasked())
+                    self.assertTrue(detInfo.isMasked(int(i)))
 
         DeleteWorkspace(group)
 
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/MaskBTPTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/MaskBTPTest.py
index d6d0fe7248fe44f4fa134e571fb80b19554e7181..05f9f0bf60b1ff61ab7849818b5a23ad91fd079b 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/MaskBTPTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/MaskBTPTest.py
@@ -51,16 +51,17 @@ class MaskBTPTest(unittest.TestCase):
         self.assertTrue(array_equal(m3,concatenate((b5t3,b5t3+1024,b5t3+2048))))
         #check whether some pixels are masked when they should
         w=mtd['CNCSMaskBTP']
-        self.assertTrue(w.getInstrument().getDetector(29696).isMasked()) #pixel1
-        self.assertTrue(w.getInstrument().getDetector(29697).isMasked()) #pixel2
-        self.assertTrue(w.getInstrument().getDetector(29698).isMasked()) #pixel3
-        self.assertTrue(not w.getInstrument().getDetector(29699).isMasked()) #pixel4
-        self.assertTrue(w.getInstrument().getDetector(29700).isMasked()) #pixel5
+        detInfo = w.detectorInfo()
+        self.assertTrue(detInfo.isMasked(29699)) #pixel1 (detID 29696)
+        self.assertTrue(detInfo.isMasked(29700)) #pixel2 (detID 29697)
+        self.assertTrue(detInfo.isMasked(29701)) #pixel3 (detID 29698)
+        self.assertFalse(detInfo.isMasked(29702)) #pixel4 (detID 29699)
+        self.assertTrue(detInfo.isMasked(29703)) #pixel5 (detID 29700)
 
-        self.assertTrue(w.getInstrument().getDetector(1020).isMasked()) #bank 1
-        self.assertTrue(not w.getInstrument().getDetector(3068).isMasked()) #bank3, tube 8
+        self.assertTrue(detInfo.isMasked(1023)) #bank1 (detID 1020)
+        self.assertFalse(detInfo.isMasked(3071)) #bank3, tube 8 (detID 3068)
 
-        self.assertTrue(w.getInstrument().getDetector(4400).isMasked()) #bank5, tube 3
+        self.assertTrue(detInfo.isMasked(4403)) #bank5, tube 3 (detID 4400)
         DeleteWorkspace(w)
 
 if __name__ == '__main__':
diff --git a/Framework/PythonInterface/test/python/plugins/algorithms/TOSCABankCorrectionTest.py b/Framework/PythonInterface/test/python/plugins/algorithms/TOSCABankCorrectionTest.py
index 0200db03404bbe9aa5dca72e758bd0e47af4ebf3..a445a4efbed93a7264e1d05ec884941238b49f7a 100644
--- a/Framework/PythonInterface/test/python/plugins/algorithms/TOSCABankCorrectionTest.py
+++ b/Framework/PythonInterface/test/python/plugins/algorithms/TOSCABankCorrectionTest.py
@@ -34,9 +34,9 @@ class TOSCABankCorrectionTest(unittest.TestCase):
         corrected_reduction, peak_position, scale_factor_1, scale_factor_2 = \
           TOSCABankCorrection(InputWorkspace=self._original)
 
-        self.assertAlmostEqual(peak_position, 1077.47222328)
-        self.assertAlmostEqual(scale_factor_1, 1.0059271)
-        self.assertAlmostEqual(scale_factor_2, 0.9941423)
+        self.assertAlmostEqual(peak_position, 1079.84991188)
+        self.assertAlmostEqual(scale_factor_1, 1.0060389)
+        self.assertAlmostEqual(scale_factor_2, 0.9940331)
 
 
     def test_automatic_peak_in_range(self):
@@ -48,9 +48,9 @@ class TOSCABankCorrectionTest(unittest.TestCase):
           TOSCABankCorrection(InputWorkspace=self._original,
                               SearchRange=[200, 800])
 
-        self.assertAlmostEqual(peak_position, 713.20080359)
-        self.assertAlmostEqual(scale_factor_1, 1.006076146)
-        self.assertAlmostEqual(scale_factor_2, 0.993996806)
+        self.assertAlmostEqual(peak_position, 714.008962427)
+        self.assertAlmostEqual(scale_factor_1, 1.004949468)
+        self.assertAlmostEqual(scale_factor_2, 0.995099045)
 
 
     def test_manual_peak_selection(self):
@@ -62,9 +62,9 @@ class TOSCABankCorrectionTest(unittest.TestCase):
           TOSCABankCorrection(InputWorkspace=self._original,
                               PeakPosition='715')
 
-        self.assertAlmostEqual(peak_position, 713.4430671)
-        self.assertAlmostEqual(scale_factor_1, 1.00611439)
-        self.assertAlmostEqual(scale_factor_2, 0.99395947)
+        self.assertAlmostEqual(peak_position, 714.29114157)
+        self.assertAlmostEqual(scale_factor_1, 1.00491105)
+        self.assertAlmostEqual(scale_factor_2, 0.99513671)
 
 
     def test_manual_peak_not_found(self):
diff --git a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
index 88d084d250d3ac088a667713e15cda63c73c97c2..7b7a6953d819ad4cc4f707b118e72e6638035a1c 100644
--- a/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
+++ b/Framework/PythonInterface/test/testhelpers/WorkspaceCreationHelperModule.cpp
@@ -66,9 +66,9 @@ BOOST_PYTHON_MODULE(WorkspaceCreationHelper) {
   //=================================== Event Workspaces
   //===================================
 
-  def("CreateEventWorkspace", (EventWorkspace_sptr (*)())CreateEventWorkspace,
+  def("createEventWorkspace", (EventWorkspace_sptr (*)())createEventWorkspace,
       return_value_policy<AsType<Workspace_sptr>>());
-  def("CreateEventWorkspace2", &CreateEventWorkspace2,
+  def("createEventWorkspace2", &createEventWorkspace2,
       return_value_policy<AsType<Workspace_sptr>>());
 
   //=================================== Peak Workspaces
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h
index b29855cca9b3f23f50ababad0eeee5e4a75bf004..1649fc0a178655f177cb862f9792ac40a75b494e 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/AbortRemoteJob.h
@@ -2,12 +2,17 @@
 #define ABORTREMOTEJOB_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport AbortRemoteJob : public Mantid::API::Algorithm {
+class DLLExport AbortRemoteJob : public Mantid::API::Algorithm,
+                                 public API::DeprecatedAlgorithm {
 public:
+  /// Default constructor
+  AbortRemoteJob();
+
   /// Algorithm's name
   const std::string name() const override { return "AbortRemoteJob"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h
index 36214bd12c83e1b48005d33ec1e4fed9ba1b22b9..28a39de187a7e0b5e3c482a7d579f0f14b5643e3 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/Authenticate.h
@@ -2,6 +2,7 @@
 #define AUTHENTICATE_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
@@ -46,8 +47,12 @@ namespace RemoteAlgorithms {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
     */
 
-class DLLExport Authenticate : public Mantid::API::Algorithm {
+class DLLExport Authenticate : public Mantid::API::Algorithm,
+                               public API::DeprecatedAlgorithm {
 public:
+  /// Default constructor
+  Authenticate();
+
   /// Algorithm's name
   const std::string name() const override { return "Authenticate"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h
index 5ec945e6ac14810e01977c705f4fe337783f2420..b0729796f47a00fd79df00f9faa65ed71075ba07 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/DownloadRemoteFile.h
@@ -2,12 +2,17 @@
 #define DOWNLOADREMOTEFILE_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport DownloadRemoteFile : public Mantid::API::Algorithm {
+class DLLExport DownloadRemoteFile : public Mantid::API::Algorithm,
+                                     public API::DeprecatedAlgorithm {
 public:
+  /// constructor
+  DownloadRemoteFile();
+
   /// Algorithm's name
   const std::string name() const override { return "DownloadRemoteFile"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h
index 9bbbde5a8e18a364cd4c03ba15fef4988a256627..12c93d12278d53ad3800342a7cf14338ec33885e 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryAllRemoteJobs.h
@@ -2,12 +2,17 @@
 #define QUERYALLREMOTEJOBS_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport QueryAllRemoteJobs : public Mantid::API::Algorithm {
+class DLLExport QueryAllRemoteJobs : public Mantid::API::Algorithm,
+                                     public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  QueryAllRemoteJobs() { this->useAlgorithm("QueryAllRemoteJobs", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "QueryAllRemoteJobs"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h
index 934ba5523da89ae45f3772a7970bcdbb802b9a7a..a1f3a79ae28da21868d5b9a26cb411c19ff60dc8 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteFile.h
@@ -2,12 +2,17 @@
 #define QUERYREMOTEFILE_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport QueryRemoteFile : public Mantid::API::Algorithm {
+class DLLExport QueryRemoteFile : public Mantid::API::Algorithm,
+                                  public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  QueryRemoteFile() { this->useAlgorithm("QueryRemoteFile", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "QueryRemoteFile"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h
index 512f3779fcb5de1d19d42d4a013abdf111a3464c..a0fa1fd23e1856a36c367202c2c3602a71e0ddba 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/QueryRemoteJob.h
@@ -2,12 +2,17 @@
 #define QUERYREMOTEJOB_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport QueryRemoteJob : public Mantid::API::Algorithm {
+class DLLExport QueryRemoteJob : public Mantid::API::Algorithm,
+                                 public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  QueryRemoteJob() { this->useAlgorithm("QueryRemoteJob", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "QueryRemoteJob"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h
index d9fa5e7114572286d8ae87dc8da64f946941a103..617da32c37395daa9b89c561b0b5db4b49256bdf 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StartRemoteTransaction.h
@@ -2,12 +2,17 @@
 #define STARTREMOTETRANSACTION_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport StartRemoteTransaction : public Mantid::API::Algorithm {
+class DLLExport StartRemoteTransaction : public Mantid::API::Algorithm,
+                                         public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  StartRemoteTransaction() { this->useAlgorithm("StartRemoteTransaction", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "StartRemoteTransaction"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h
index 2880b63cd12e96ce8ede9c69faac3967564ea50c..4b0bc049300139a7dabc7ededa4c731b7b556c7b 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/StopRemoteTransaction.h
@@ -2,12 +2,17 @@
 #define STOPREMOTETRANSACTION_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
 
-class DLLExport StopRemoteTransaction : public Mantid::API::Algorithm {
+class DLLExport StopRemoteTransaction : public Mantid::API::Algorithm,
+                                        public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  StopRemoteTransaction() { this->useAlgorithm("StopRemoteTransaction", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "StopRemoteTransaction"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h
index fa885fa430bd3a03e82980e287a7039e3f7f7de1..f68fc274de37b820a3a9b166dc4ac08c3f8aa067 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/SubmitRemoteJob.h
@@ -2,6 +2,7 @@
 #define SUBMITREMOTEJOB_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 
 namespace Mantid {
 namespace RemoteAlgorithms {
@@ -54,8 +55,12 @@ namespace RemoteAlgorithms {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
     */
 
-class DLLExport SubmitRemoteJob : public Mantid::API::Algorithm {
+class DLLExport SubmitRemoteJob : public Mantid::API::Algorithm,
+                                  public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  SubmitRemoteJob() { this->useAlgorithm("SubmitRemoteJob", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "SubmitRemoteJob"; }
   /// Summary of algorithms purpose
diff --git a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/UploadRemoteFile.h b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/UploadRemoteFile.h
index 715ab726a8fbed248228afc90c1a0132e3598cca..aad5a199479e2eacffdc3e2370343d5f2cf7deba 100644
--- a/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/UploadRemoteFile.h
+++ b/Framework/RemoteAlgorithms/inc/MantidRemoteAlgorithms/UploadRemoteFile.h
@@ -2,6 +2,8 @@
 #define UPLOADREMOTEFILE_H_
 
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
+
 namespace Mantid {
 namespace RemoteAlgorithms {
 /*** Upload a file to a remote compute resource
@@ -49,10 +51,15 @@ namespace RemoteAlgorithms {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
     */
 
-class DLLExport UploadRemoteFile : public API::Algorithm {
+class DLLExport UploadRemoteFile : public API::Algorithm,
+                                   public API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  UploadRemoteFile() { this->useAlgorithm("UploadRemoteFile", 2); }
+
   /// Algorithm's name
   const std::string name() const override { return "UploadRemoteFile"; }
+
   /// Summary of algorithms purpose
   const std::string summary() const override {
     return "Uploads a file to the specified compute resource.";
diff --git a/Framework/RemoteAlgorithms/src/AbortRemoteJob.cpp b/Framework/RemoteAlgorithms/src/AbortRemoteJob.cpp
index 22b798d54d3fa5f80caf0a0e2d7c950cc8b16efb..4f6b07e27460ba0d07a887f7a587a8ca7937545d 100644
--- a/Framework/RemoteAlgorithms/src/AbortRemoteJob.cpp
+++ b/Framework/RemoteAlgorithms/src/AbortRemoteJob.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/AbortRemoteJob.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/NullValidator.h"
 #include "MantidKernel/FacilityInfo.h"
@@ -19,6 +20,9 @@ using namespace Mantid::API;
 
 // A reference to the logger is provided by the base class, it is called g_log.
 
+/// Empty constructor
+AbortRemoteJob::AbortRemoteJob() { this->useAlgorithm("AbortRemoteJob", 2); }
+
 void AbortRemoteJob::init() {
   // Unlike most algorithms, this one doesn't deal with workspaces....
 
diff --git a/Framework/RemoteAlgorithms/src/AbortRemoteJob2.cpp b/Framework/RemoteAlgorithms/src/AbortRemoteJob2.cpp
index 21495674d8ccdbc83ed7f65195cf77dd74eb1a79..b6db986ecc744fa525d812addd74e16980190718 100644
--- a/Framework/RemoteAlgorithms/src/AbortRemoteJob2.cpp
+++ b/Framework/RemoteAlgorithms/src/AbortRemoteJob2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/Authenticate.cpp b/Framework/RemoteAlgorithms/src/Authenticate.cpp
index b02d1f1a5ba497093d9d34538541d8c16079a5b1..30b203e830f41fccb3f053c3afcb9ab7853d9687 100644
--- a/Framework/RemoteAlgorithms/src/Authenticate.cpp
+++ b/Framework/RemoteAlgorithms/src/Authenticate.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/Authenticate.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/Exception.h"
@@ -23,6 +24,8 @@ using namespace Mantid::Kernel;
 
 // A reference to the logger is provided by the base class, it is called g_log.
 
+Authenticate::Authenticate() { this->useAlgorithm("Authenticate", 2); }
+
 void Authenticate::init() {
   // Unlike most algorithms, this wone doesn't deal with workspaces....
 
diff --git a/Framework/RemoteAlgorithms/src/Authenticate2.cpp b/Framework/RemoteAlgorithms/src/Authenticate2.cpp
index 7dffd71f3e2dd4526155a10de7304c4f32d28b2d..70ae5c13fe557e333bb9cf9472380a6af41fa850 100644
--- a/Framework/RemoteAlgorithms/src/Authenticate2.cpp
+++ b/Framework/RemoteAlgorithms/src/Authenticate2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/DownloadRemoteFile.cpp b/Framework/RemoteAlgorithms/src/DownloadRemoteFile.cpp
index 2ba710096fb7ac1278ad0d04dada1cdfce26b8a1..d40f8825c399c3892f806ca9f78d6846a00979cf 100644
--- a/Framework/RemoteAlgorithms/src/DownloadRemoteFile.cpp
+++ b/Framework/RemoteAlgorithms/src/DownloadRemoteFile.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/DownloadRemoteFile.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/MaskedProperty.h"
@@ -21,6 +22,10 @@ using namespace Mantid::API;
 
 // A reference to the logger is provided by the base class, it is called g_log.
 
+DownloadRemoteFile::DownloadRemoteFile() {
+  this->useAlgorithm("DownloadRemoteFile", 2);
+}
+
 void DownloadRemoteFile::init() {
   // Unlike most algorithms, this one doesn't deal with workspaces....
 
diff --git a/Framework/RemoteAlgorithms/src/DownloadRemoteFile2.cpp b/Framework/RemoteAlgorithms/src/DownloadRemoteFile2.cpp
index 2ad5e560315e99fac8d9b820b6f359d61ba2a288..c62d6acf8b315d77ce3f7508912b089e8a2eeca1 100644
--- a/Framework/RemoteAlgorithms/src/DownloadRemoteFile2.cpp
+++ b/Framework/RemoteAlgorithms/src/DownloadRemoteFile2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/Logout2.cpp b/Framework/RemoteAlgorithms/src/Logout2.cpp
index d658077fd582eaabe03a6c02a4e6d9dbe33bacf3..186b01140ba6107230abae98614c8a54b1010eb6 100644
--- a/Framework/RemoteAlgorithms/src/Logout2.cpp
+++ b/Framework/RemoteAlgorithms/src/Logout2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs.cpp b/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs.cpp
index 8b42ffa356d1dbce625638aeb0c72d484975d8cd..31add85d6c27f199b1983b9384629caf224e4042 100644
--- a/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/QueryAllRemoteJobs.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/NullValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/FacilityInfo.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs2.cpp b/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs2.cpp
index 0f44b47bfa0c24fbfdb2f212d2852eca785d865a..fb98f50efb9f8b9565b3329c9b218bebd7e96c74 100644
--- a/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs2.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryAllRemoteJobs2.cpp
@@ -1,5 +1,6 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/NullValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryRemoteFile.cpp b/Framework/RemoteAlgorithms/src/QueryRemoteFile.cpp
index bfee5091379de00936ea3de8e4403ab600cd9e77..2534932143d3b02198b292aa85c9356ef52902ed 100644
--- a/Framework/RemoteAlgorithms/src/QueryRemoteFile.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryRemoteFile.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/QueryRemoteFile.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/FacilityInfo.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryRemoteFile2.cpp b/Framework/RemoteAlgorithms/src/QueryRemoteFile2.cpp
index 22517b7f0acab54c47c9a1f96e05aaef1b8184e4..a416b3676f66a79173fb8071120a8dc8792c192a 100644
--- a/Framework/RemoteAlgorithms/src/QueryRemoteFile2.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryRemoteFile2.cpp
@@ -1,5 +1,6 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryRemoteJob.cpp b/Framework/RemoteAlgorithms/src/QueryRemoteJob.cpp
index 29a8a3253cf11f1bbc4a7c0d5df6b78011a8d53b..1f0812c08885075f3f6561187ad5ec08cea20b4a 100644
--- a/Framework/RemoteAlgorithms/src/QueryRemoteJob.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryRemoteJob.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/QueryRemoteJob.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/NullValidator.h"
 #include "MantidKernel/FacilityInfo.h"
diff --git a/Framework/RemoteAlgorithms/src/QueryRemoteJob2.cpp b/Framework/RemoteAlgorithms/src/QueryRemoteJob2.cpp
index efb0fa30101bd1c1e383db3e3fcdee5080f725d8..d94a74ae2b13ca0a9c59f7a046a6450063bb5865 100644
--- a/Framework/RemoteAlgorithms/src/QueryRemoteJob2.cpp
+++ b/Framework/RemoteAlgorithms/src/QueryRemoteJob2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/NullValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp b/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp
index 4b95f5de96ab2c5eaae91d49f66b3ce977df06e8..78c7e4df5728289b624e9083ad6aafb7137298d0 100644
--- a/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp
+++ b/Framework/RemoteAlgorithms/src/SCARFTomoReconstruction.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/InternetHelper.h"
 #include "MantidKernel/ListValidator.h"
@@ -22,6 +23,8 @@
 #include <Poco/Net/HTTPRequest.h>
 #include <Poco/StreamCopier.h>
 
+#include <boost/algorithm/string/replace.hpp>
+
 namespace Mantid {
 namespace RemoteAlgorithms {
 
@@ -1348,12 +1351,11 @@ void SCARFTomoReconstruction::getOneJobFile(const std::string &jobId,
       {"Content-Type", "application/xml"},
       {"Cookie", token},
       {"Accept", m_acceptType}};
-  std::string body = remotePath;
   int code;
   std::stringstream ss;
   try {
-    code = doSendRequestGetResponse(httpsURL, ss, headers,
-                                    Poco::Net::HTTPRequest::HTTP_GET, body);
+    code = doSendRequestGetResponse(
+        httpsURL, ss, headers, Poco::Net::HTTPRequest::HTTP_GET, remotePath);
   } catch (Kernel::Exception::InternetError &ie) {
     throw std::runtime_error(
         "Error while sending HTTP request to download a file: " +
diff --git a/Framework/RemoteAlgorithms/src/SimpleJSON.cpp b/Framework/RemoteAlgorithms/src/SimpleJSON.cpp
index 717da9b0cc1be054b38639d0c049872f401e03c1..61cd6ece6193a85cff1347af1bc5bb873c7dd5df 100644
--- a/Framework/RemoteAlgorithms/src/SimpleJSON.cpp
+++ b/Framework/RemoteAlgorithms/src/SimpleJSON.cpp
@@ -662,11 +662,8 @@ string readUntilCloseChar(istream &istr) {
       throw JSONParseException(
           "Stream unexpectedly ended without a closing char.");
     }
-
-    if ((value.size() > 0) ||
-        (!isspace(
-             next))) // don't add white space to the start of the value string
-    {
+    if (!value.empty() || !isspace(next)) {
+      // don't add white space to the start of the value string
       value += next;
     }
     istr.get(); // consume the char from the stream
diff --git a/Framework/RemoteAlgorithms/src/StartRemoteTransaction.cpp b/Framework/RemoteAlgorithms/src/StartRemoteTransaction.cpp
index d806aaafc15397b9bbeb47c621f9533083bcf165..1aa30c27e69a6aee9c039caf2eb299797790965f 100644
--- a/Framework/RemoteAlgorithms/src/StartRemoteTransaction.cpp
+++ b/Framework/RemoteAlgorithms/src/StartRemoteTransaction.cpp
@@ -1,5 +1,6 @@
 #include "MantidRemoteAlgorithms/StartRemoteTransaction.h"
 #include "MantidRemoteAlgorithms/SimpleJSON.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 
diff --git a/Framework/RemoteAlgorithms/src/StartRemoteTransaction2.cpp b/Framework/RemoteAlgorithms/src/StartRemoteTransaction2.cpp
index 35ff73b6c8630488a6041126051dc178a58bab07..dc539883f27389a7372a021c3eba21a171a145ce 100644
--- a/Framework/RemoteAlgorithms/src/StartRemoteTransaction2.cpp
+++ b/Framework/RemoteAlgorithms/src/StartRemoteTransaction2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidRemoteAlgorithms/StartRemoteTransaction2.h"
diff --git a/Framework/RemoteAlgorithms/src/StopRemoteTransaction.cpp b/Framework/RemoteAlgorithms/src/StopRemoteTransaction.cpp
index 1311ece17b59be4de5e2e5ad77bc076dd91891a2..2a67d8cfb9edc2478fa7697b358c96281eb65150 100644
--- a/Framework/RemoteAlgorithms/src/StopRemoteTransaction.cpp
+++ b/Framework/RemoteAlgorithms/src/StopRemoteTransaction.cpp
@@ -1,5 +1,6 @@
 #include "MantidRemoteAlgorithms/StopRemoteTransaction.h"
 #include "MantidRemoteAlgorithms/SimpleJSON.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/StopRemoteTransaction2.cpp b/Framework/RemoteAlgorithms/src/StopRemoteTransaction2.cpp
index b64e27c911f90ab8b0cc711ca48b3157b6a8430b..48eadefe72497ad3a3c0f0f08997898b2bb6a58f 100644
--- a/Framework/RemoteAlgorithms/src/StopRemoteTransaction2.cpp
+++ b/Framework/RemoteAlgorithms/src/StopRemoteTransaction2.cpp
@@ -1,5 +1,6 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
 #include "MantidRemoteAlgorithms/SimpleJSON.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/SubmitRemoteJob.cpp b/Framework/RemoteAlgorithms/src/SubmitRemoteJob.cpp
index a7611e27f9c7a180ee6b4aa79b778343e2683e78..ef2ad0b76641315d940630897d7ae9892035e9bb 100644
--- a/Framework/RemoteAlgorithms/src/SubmitRemoteJob.cpp
+++ b/Framework/RemoteAlgorithms/src/SubmitRemoteJob.cpp
@@ -1,5 +1,6 @@
 #include "MantidRemoteAlgorithms/SubmitRemoteJob.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/Exception.h"
diff --git a/Framework/RemoteAlgorithms/src/SubmitRemoteJob2.cpp b/Framework/RemoteAlgorithms/src/SubmitRemoteJob2.cpp
index 0180d31f7197e73ff3217d83ad71029a99749c77..e8715d05976e5b7c31e1c13863de3b864ef1d1fd 100644
--- a/Framework/RemoteAlgorithms/src/SubmitRemoteJob2.cpp
+++ b/Framework/RemoteAlgorithms/src/SubmitRemoteJob2.cpp
@@ -1,5 +1,6 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
 #include "MantidKernel/BoundedValidator.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
diff --git a/Framework/RemoteAlgorithms/src/UploadRemoteFile.cpp b/Framework/RemoteAlgorithms/src/UploadRemoteFile.cpp
index c716a512c5f6c3334249985441e86b4803743fc3..f8e1e8d15b4d9e7f21d018ec638ffd7029a6f5be 100644
--- a/Framework/RemoteAlgorithms/src/UploadRemoteFile.cpp
+++ b/Framework/RemoteAlgorithms/src/UploadRemoteFile.cpp
@@ -1,4 +1,5 @@
 #include "MantidRemoteAlgorithms/UploadRemoteFile.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/MandatoryValidator.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/RemoteJobManager.h"
diff --git a/Framework/RemoteAlgorithms/src/UploadRemoteFile2.cpp b/Framework/RemoteAlgorithms/src/UploadRemoteFile2.cpp
index 6081847bb9ceb1fbc808869411501bae74bc2b8c..df3324377bfef0d686a0a1b9cd9f88b27fa015b6 100644
--- a/Framework/RemoteAlgorithms/src/UploadRemoteFile2.cpp
+++ b/Framework/RemoteAlgorithms/src/UploadRemoteFile2.cpp
@@ -1,4 +1,5 @@
 #include "MantidAPI/RemoteJobManagerFactory.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
diff --git a/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h b/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h
index 45c9c9a36cf44a6ce6aaf96b49c1329e6f675f10..207592a1dcd5007785c54d3115ba14262dd0dc78 100644
--- a/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h
+++ b/Framework/RemoteAlgorithms/test/SCARFTomoReconstructionTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAPI/ITableWorkspace.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidRemoteAlgorithms/SCARFTomoReconstruction.h"
 
diff --git a/Framework/RemoteJobManagers/src/LSFJobManager.cpp b/Framework/RemoteJobManagers/src/LSFJobManager.cpp
index d2b137a95de34929eb619ea5d018f4b343584063..cbedc1178227127ed7743d2b046e89e471345128 100644
--- a/Framework/RemoteJobManagers/src/LSFJobManager.cpp
+++ b/Framework/RemoteJobManagers/src/LSFJobManager.cpp
@@ -1125,12 +1125,11 @@ void LSFJobManager::getOneJobFile(const std::string &jobId,
   const Poco::URI fullURL = makeFullURI(t.m_url, g_downloadOneBasePath, jobId);
   const StringToStringMap headers =
       makeHeaders(std::string("application/xml"), token, g_acceptType);
-  const std::string body = remotePath;
   int code = 0;
   std::stringstream ss;
   try {
-    code = doSendRequestGetResponse(fullURL, ss, headers,
-                                    Poco::Net::HTTPRequest::HTTP_GET, body);
+    code = doSendRequestGetResponse(
+        fullURL, ss, headers, Poco::Net::HTTPRequest::HTTP_GET, remotePath);
   } catch (Kernel::Exception::InternetError &ie) {
     throw std::runtime_error(
         "Error while sending HTTP request to download a file: " +
diff --git a/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp b/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
index 48a4c64186a2109292f7071e59d8b4025bf1130f..cc887c1618b4b161f70e12c79b31ef8e060e487d 100644
--- a/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
+++ b/Framework/RemoteJobManagers/src/MantidWebServiceAPIHelper.cpp
@@ -211,7 +211,7 @@ void MantidWebServiceAPIHelper::initHTTPRequest(Poco::Net::HTTPRequest &req,
   path += extraPath;
 
   uri.setPath(path);
-  if (method == Poco::Net::HTTPRequest::HTTP_GET && queryString.size() > 0) {
+  if (method == Poco::Net::HTTPRequest::HTTP_GET && !queryString.empty()) {
     uri.setQuery(queryString);
   }
 
diff --git a/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp b/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp
index ba53b73cd36280c297152f15dd2cf9273d9f6487..beb5de2fe487c257d36d7f2de6d0dc2562670300 100644
--- a/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp
+++ b/Framework/RemoteJobManagers/src/MantidWebServiceAPIJobManager.cpp
@@ -369,8 +369,7 @@ std::string MantidWebServiceAPIJobManager::startRemoteTransaction() {
  * (remote) compute resource.
  */
 void MantidWebServiceAPIJobManager::stopRemoteTransaction(
-    const std::string &transactionID) {
-  std::string transId = transactionID;
+    const std::string &transId) {
   std::istream &respStream =
       httpGet("/transaction", std::string("Action=Stop&TransID=") + transId);
 
@@ -420,9 +419,8 @@ std::string MantidWebServiceAPIJobManager::submitRemoteJob(
   postData[runnable] = param;
 
   // Job name is optional
-  std::string jobName = taskName;
-  if (jobName.length() > 0) {
-    postData["JobName"] = jobName;
+  if (taskName.length() > 0) {
+    postData["JobName"] = taskName;
   }
 
   std::istream &respStream = httpPost("/submit", postData);
diff --git a/Framework/RemoteJobManagers/src/SimpleJSON.cpp b/Framework/RemoteJobManagers/src/SimpleJSON.cpp
index 0e422f961ee2754ca843962c183b1b38000f17a6..01c76fd203ed15331b7bed8a90e2015a679ac060 100644
--- a/Framework/RemoteJobManagers/src/SimpleJSON.cpp
+++ b/Framework/RemoteJobManagers/src/SimpleJSON.cpp
@@ -663,10 +663,8 @@ string readUntilCloseChar(istream &istr) {
           "Stream unexpectedly ended without a closing char.");
     }
 
-    if ((value.size() > 0) ||
-        (!isspace(
-             next))) // don't add white space to the start of the value string
-    {
+    if (!value.empty() || !isspace(next)) {
+      // don't add white space to the start of the value string
       value += next;
     }
     istr.get(); // consume the char from the stream
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
index f8587bd7d3b894e5b24f813ed1078d5e30df9138..f9dc4155e5d1c9ba448bdf111f7c208756a17ffc 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiFitPeaks1D2.h
@@ -10,6 +10,7 @@
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 
 namespace Mantid {
 namespace Poldi {
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h
index 34593fc70c2a18da4dd438b3f3abca92d5c16332..4c6abeb74f98b067b38179c6b973e0e57ccdae3c 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h
@@ -3,12 +3,13 @@
 
 #include "MantidKernel/System.h"
 
-#include "MantidGeometry/Instrument.h"
-
 #include "MantidSINQ/DllConfig.h"
 #include "MantidSINQ/PoldiUtilities/PoldiDetectorDecorator.h"
 
 namespace Mantid {
+namespace API {
+class DetectorInfo;
+}
 namespace Poldi {
 
 /** PoldiDeadWireDecorator :
@@ -47,7 +48,7 @@ public:
   PoldiDeadWireDecorator(std::set<int> deadWires,
                          boost::shared_ptr<PoldiAbstractDetector> detector =
                              boost::shared_ptr<PoldiAbstractDetector>());
-  PoldiDeadWireDecorator(Geometry::Instrument_const_sptr poldiInstrument,
+  PoldiDeadWireDecorator(const API::DetectorInfo &poldiDetectorInfo,
                          boost::shared_ptr<PoldiAbstractDetector> detector =
                              boost::shared_ptr<PoldiAbstractDetector>());
 
@@ -61,8 +62,6 @@ protected:
   void detectorSetHook() override;
   std::vector<int> getGoodElements(std::vector<int> rawElements);
 
-  static bool detectorIsNotMasked(Geometry::Instrument_const_sptr instrument,
-                                  detid_t detectorId);
   bool isDeadElement(int index);
 
   std::set<int> m_deadWireSet;
diff --git a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/UncertainValueIO.h b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/UncertainValueIO.h
index 7b049d62bfa1853b344bdde96953a175a30039c5..86e4431667632c06c404df078de5c7791b47a6eb 100644
--- a/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/UncertainValueIO.h
+++ b/Framework/SINQ/inc/MantidSINQ/PoldiUtilities/UncertainValueIO.h
@@ -50,7 +50,7 @@ public:
   }
 
   static UncertainValue fromString(const std::string &uncertainValueString) {
-    if (uncertainValueString.size() == 0) {
+    if (uncertainValueString.empty()) {
       return UncertainValue();
     }
 
diff --git a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
index 15dd0a61632420e8855ef96d887966c5bb7af291..52d9b8611a60b992c547b6fb3254059e52e8d34b 100644
--- a/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
+++ b/Framework/SINQ/inc/MantidSINQ/SINQTranspose3D.h
@@ -37,10 +37,15 @@
 
 #include "MantidSINQ/DllConfig.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidAPI/IMDHistoWorkspace_fwd.h"
 
-class MANTID_SINQ_DLL SINQTranspose3D : public Mantid::API::Algorithm {
+class MANTID_SINQ_DLL SINQTranspose3D
+    : public Mantid::API::Algorithm,
+      public Mantid::API::DeprecatedAlgorithm {
 public:
+  /// Constructor
+  SINQTranspose3D() { this->useAlgorithm("TransposeMD", 1); }
   /// Algorithm's name
   const std::string name() const override { return "Transpose3D"; }
   /// Summary of algorithms purpose
diff --git a/Framework/SINQ/src/MDHistoToWorkspace2D.cpp b/Framework/SINQ/src/MDHistoToWorkspace2D.cpp
index ab000d19c5432b076990d9b1199dbbcd43392fbf..9a0d1068c8512d4c8a2658c2bb720aaaa2430bbd 100644
--- a/Framework/SINQ/src/MDHistoToWorkspace2D.cpp
+++ b/Framework/SINQ/src/MDHistoToWorkspace2D.cpp
@@ -13,8 +13,10 @@
 
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 
 #include <cmath>
+#include <iostream>
 
 // Register the algorithm into the AlgorithmFactory
 DECLARE_ALGORITHM(MDHistoToWorkspace2D)
diff --git a/Framework/SINQ/src/PoldiAnalyseResiduals.cpp b/Framework/SINQ/src/PoldiAnalyseResiduals.cpp
index 70670b14988ec38e333a23a88497ff79c2808d73..50f3f6143d8109f9afd6453f35601805df7ff34e 100644
--- a/Framework/SINQ/src/PoldiAnalyseResiduals.cpp
+++ b/Framework/SINQ/src/PoldiAnalyseResiduals.cpp
@@ -199,7 +199,7 @@ void PoldiAnalyseResiduals::exec() {
       boost::make_shared<PoldiInstrumentAdapter>(measured);
   // Dead wires need to be taken into account
   PoldiAbstractDetector_sptr deadWireDetector =
-      boost::make_shared<PoldiDeadWireDecorator>(measured->getInstrument(),
+      boost::make_shared<PoldiDeadWireDecorator>(measured->detectorInfo(),
                                                  poldiInstrument->detector());
 
   // Since the valid workspace indices are required for some calculations, we
diff --git a/Framework/SINQ/src/PoldiAutoCorrelation5.cpp b/Framework/SINQ/src/PoldiAutoCorrelation5.cpp
index c43f02d4c9c9802e03e8e821bdf7ee86e2e910c7..ba2c2c4954343cb8609384764f3fefc7087cab22 100644
--- a/Framework/SINQ/src/PoldiAutoCorrelation5.cpp
+++ b/Framework/SINQ/src/PoldiAutoCorrelation5.cpp
@@ -83,7 +83,7 @@ void PoldiAutoCorrelation5::exec() {
 
   PoldiAbstractDetector_sptr detector = instrumentAdapter.detector();
   boost::shared_ptr<PoldiDeadWireDecorator> cleanDetector(
-      new PoldiDeadWireDecorator(localWorkspace->getInstrument(), detector));
+      new PoldiDeadWireDecorator(localWorkspace->detectorInfo(), detector));
 
   // log configuration information
   logConfigurationInformation(cleanDetector, chopper);
diff --git a/Framework/SINQ/src/PoldiFitPeaks2D.cpp b/Framework/SINQ/src/PoldiFitPeaks2D.cpp
index 6f91161bcbf10be04aa9c1079581b97ad4af9aa8..2996cdf60e1d0b1906cfac437a9b7c8febabde7d 100644
--- a/Framework/SINQ/src/PoldiFitPeaks2D.cpp
+++ b/Framework/SINQ/src/PoldiFitPeaks2D.cpp
@@ -9,6 +9,7 @@
 #include "MantidAPI/MultiDomainFunction.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidGeometry/Crystal/UnitCell.h"
@@ -857,7 +858,7 @@ MatrixWorkspace_sptr PoldiFitPeaks2D::get1DSpectrum(
   }
 
   PoldiAbstractDetector_sptr detector(new PoldiDeadWireDecorator(
-      workspace->getInstrument(), m_poldiInstrument->detector()));
+      workspace->detectorInfo(), m_poldiInstrument->detector()));
   std::vector<int> indices = detector->availableElements();
 
   // Create the grid for the diffractogram and corresponding domain/values
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
index 4911e091580115b3a7cbdac6c93d2c07bfaad3e1..a7565e4e10211adfb88a7ba4f114dac630b65f24 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiAutoCorrelationCore.cpp
@@ -6,6 +6,7 @@
 #include "boost/bind.hpp"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidKernel/Logger.h"
 #include "MantidKernel/MultiThreaded.h"
 
 #include "MantidSINQ/PoldiUtilities/PoldiDGrid.h"
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
index 566f7e0b72aaa036bf792e2c739bc5dc8daef37a..440c0f75248f3f0fe58f0438f894f967ad3327e5 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiDeadWireDecorator.cpp
@@ -1,3 +1,4 @@
+#include "MantidAPI/DetectorInfo.h"
 #include "MantidSINQ/PoldiUtilities/PoldiDeadWireDecorator.h"
 
 #include <algorithm>
@@ -17,18 +18,19 @@ PoldiDeadWireDecorator::PoldiDeadWireDecorator(
 }
 
 PoldiDeadWireDecorator::PoldiDeadWireDecorator(
-    Instrument_const_sptr poldiInstrument,
+    const API::DetectorInfo &poldiDetectorInfo,
     boost::shared_ptr<PoldiAbstractDetector> detector)
     : PoldiDetectorDecorator(detector), m_deadWireSet(), m_goodElements() {
   setDecoratedDetector(detector);
 
-  std::vector<detid_t> allDetectorIds = poldiInstrument->getDetectorIDs();
+  std::vector<detid_t> allDetectorIds = poldiDetectorInfo.detectorIDs();
   std::vector<detid_t> deadDetectorIds(allDetectorIds.size());
 
   auto endIterator = std::remove_copy_if(
       allDetectorIds.begin(), allDetectorIds.end(), deadDetectorIds.begin(),
-      boost::bind<bool>(&PoldiDeadWireDecorator::detectorIsNotMasked,
-                        poldiInstrument, _1));
+      [&](const detid_t detID) -> bool {
+        return !poldiDetectorInfo.isMasked(poldiDetectorInfo.indexOf(detID));
+      });
   deadDetectorIds.resize(std::distance(deadDetectorIds.begin(), endIterator));
 
   setDeadWires(std::set<int>(deadDetectorIds.begin(), deadDetectorIds.end()));
@@ -76,11 +78,6 @@ PoldiDeadWireDecorator::getGoodElements(std::vector<int> rawElements) {
   return rawElements;
 }
 
-bool PoldiDeadWireDecorator::detectorIsNotMasked(
-    Instrument_const_sptr instrument, detid_t detectorId) {
-  return !instrument->isDetectorMasked(detectorId);
-}
-
 bool PoldiDeadWireDecorator::isDeadElement(int index) {
   return m_deadWireSet.count(index) != 0;
 }
diff --git a/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp b/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp
index 08e4c82fdc7c58dedf1d4ffe42c8c78eac105c14..5fa777bf2511044f8a9bbdd60962ce3a83cdb995 100644
--- a/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp
+++ b/Framework/SINQ/src/PoldiUtilities/PoldiResidualCorrelationCore.cpp
@@ -1,4 +1,5 @@
 #include "MantidSINQ/PoldiUtilities/PoldiResidualCorrelationCore.h"
+#include "MantidKernel/Logger.h"
 #include <algorithm>
 #include <numeric>
 
diff --git a/Framework/SINQ/src/SINQHMListener.cpp b/Framework/SINQ/src/SINQHMListener.cpp
index 6f3af35f32452b52edc3789add83ce9e0b8177ed..ec05ce5a808407a428784333c373241ce7fa2528 100644
--- a/Framework/SINQ/src/SINQHMListener.cpp
+++ b/Framework/SINQ/src/SINQHMListener.cpp
@@ -18,6 +18,8 @@
 #include <Poco/Net/HTTPBasicCredentials.h>
 #include <Poco/StreamCopier.h>
 
+#include <boost/algorithm/string/trim.hpp>
+
 using namespace Mantid::API;
 using namespace Mantid::DataObjects;
 using namespace Mantid::Geometry;
diff --git a/Framework/SINQ/test/PoldiAnalyseResidualsTest.h b/Framework/SINQ/test/PoldiAnalyseResidualsTest.h
index bc828c685f004ac5feb35cc1f9c3c119512ea7d9..e935e38e54a12b3d6188478c599418196f6b1e51 100644
--- a/Framework/SINQ/test/PoldiAnalyseResidualsTest.h
+++ b/Framework/SINQ/test/PoldiAnalyseResidualsTest.h
@@ -32,7 +32,7 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     TS_ASSERT_EQUALS(alg.sumCounts(testWorkspace, std::vector<int>(1, 1)), 2.0);
     TS_ASSERT_EQUALS(alg.sumCounts(testWorkspace, std::vector<int>(1, 0)), 0.0);
 
@@ -44,7 +44,7 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     TS_ASSERT_EQUALS(alg.numberOfPoints(testWorkspace, std::vector<int>(1, 1)),
                      2);
     TS_ASSERT_EQUALS(alg.numberOfPoints(testWorkspace, std::vector<int>(1, 0)),
@@ -58,7 +58,7 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     TS_ASSERT_THROWS_NOTHING(
         alg.addValue(testWorkspace, 3.0, std::vector<int>(1, 1)));
     TS_ASSERT_THROWS_NOTHING(
@@ -77,9 +77,9 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr measured =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     Workspace2D_sptr calculated =
-        WorkspaceCreationHelper::Create2DWorkspace154(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace154(2, 2);
 
     TS_ASSERT_THROWS_NOTHING(
         alg.calculateResidualWorkspace(measured, calculated));
@@ -103,7 +103,7 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspace123(2, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(2, 2);
     TS_ASSERT_THROWS_NOTHING(
         alg.normalizeResiduals(testWorkspace, std::vector<int>(1, 1)));
 
@@ -120,7 +120,7 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     TS_ASSERT_EQUALS(alg.relativeCountChange(testWorkspace, 10.0), 0.0);
 
     alg.addValue(testWorkspace, 10.0, std::vector<int>(1, 0));
@@ -132,9 +132,9 @@ public:
     TestablePoldiAnalyseResiduals alg;
 
     Workspace2D_sptr lhs =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     Workspace2D_sptr rhs =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
 
     Workspace2D_sptr sum = alg.addWorkspaces(lhs, rhs);
 
diff --git a/Framework/SINQ/test/PoldiAutoCorrelationCoreTest.h b/Framework/SINQ/test/PoldiAutoCorrelationCoreTest.h
index 032b397b089c9a02a40df2e444f02e4406fa3844..e42039031d523c569a22b7e207869f8a9dfcfedd 100644
--- a/Framework/SINQ/test/PoldiAutoCorrelationCoreTest.h
+++ b/Framework/SINQ/test/PoldiAutoCorrelationCoreTest.h
@@ -219,7 +219,7 @@ public:
 
   void testgetCounts() {
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
 
     TestablePoldiAutoCorrelationCore autoCorrelationCore(m_log);
     autoCorrelationCore.setCountData(testWorkspace);
@@ -234,7 +234,7 @@ public:
 
   void testgetNormCounts() {
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
 
     TestablePoldiAutoCorrelationCore autoCorrelationCore(m_log);
     autoCorrelationCore.setNormCountData(testWorkspace);
@@ -247,7 +247,7 @@ public:
 
   void testgetSumOfCounts() {
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
 
     TestablePoldiAutoCorrelationCore autoCorrelationCore(m_log);
     autoCorrelationCore.setCountData(testWorkspace);
@@ -265,7 +265,7 @@ public:
         boost::dynamic_pointer_cast<MockChopper>(autoCorrelationCore.m_chopper);
 
     Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     autoCorrelationCore.setCountData(testWorkspace);
     autoCorrelationCore.setNormCountData(testWorkspace);
 
diff --git a/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h b/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h
index 9aa3471403b7ed31c895a9488a1921c9c02011b8..f63d7b76a495122e458801fc046a330ef4abb3ce 100644
--- a/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h
+++ b/Framework/SINQ/test/PoldiCreatePeaksFromCellTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidSINQ/PoldiCreatePeaksFromCell.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 
 using Mantid::Poldi::PoldiCreatePeaksFromCell;
diff --git a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
index 6d57b9ca2099e0d544105d58430377909bc4f2f2..febeb266721c0bedfa8556b8b0119a8360ee2d9c 100644
--- a/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
+++ b/Framework/SINQ/test/PoldiFitPeaks1D2Test.h
@@ -309,7 +309,7 @@ private:
 
     // put it into a workspace
     Workspace2D_sptr ws =
-        WorkspaceCreationHelper::Create1DWorkspaceConstant(50, 0.0, 1.0);
+        WorkspaceCreationHelper::create1DWorkspaceConstant(50, 0.0, 1.0);
     std::vector<double> &x = ws->dataX(0);
     std::vector<double> &y = ws->dataY(0);
 
diff --git a/Framework/SINQ/test/PoldiFitPeaks2DTest.h b/Framework/SINQ/test/PoldiFitPeaks2DTest.h
index eaad0b225685d6cfb73078127b9a50347550382f..7d8ae7847115a19590b94ed985d9a5b8f1c542d3 100644
--- a/Framework/SINQ/test/PoldiFitPeaks2DTest.h
+++ b/Framework/SINQ/test/PoldiFitPeaks2DTest.h
@@ -59,7 +59,7 @@ public:
   }
 
   void testSetDeltaTFromWorkspace() {
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(1, 10);
     for (size_t i = 0; i <= 10; ++i) {
       ws->dataX(0)[i] = static_cast<double>(i);
     }
@@ -69,7 +69,7 @@ public:
     TS_ASSERT_EQUALS(spectrumCalculator.m_deltaT, 1.0);
 
     MatrixWorkspace_sptr invalidWs =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 1);
     TS_ASSERT_THROWS(spectrumCalculator.setDeltaTFromWorkspace(invalidWs),
                      std::invalid_argument);
   }
diff --git a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
index 4154e7fd2241b1bce4e200ecc29b74ebea023c7c..9541840e11ce5775cd96f518491c187edb28b2c5 100644
--- a/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
+++ b/Framework/SINQ/test/PoldiIndexKnownCompoundsTest.h
@@ -5,6 +5,7 @@
 
 #include "MantidSINQ/PoldiIndexKnownCompounds.h"
 #include "MantidAPI/FrameworkManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidSINQ/PoldiUtilities/PoldiMockInstrumentHelpers.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
 #include "MantidKernel/V3D.h"
@@ -238,7 +239,7 @@ public:
     std::vector<Workspace_sptr> badWorkspaces;
     badWorkspaces.push_back(
         PoldiPeakCollectionHelpers::createPoldiPeakTableWorkspace());
-    badWorkspaces.push_back(WorkspaceCreationHelper::Create1DWorkspaceRand(10));
+    badWorkspaces.push_back(WorkspaceCreationHelper::create1DWorkspaceRand(10));
 
     TS_ASSERT_THROWS(alg.getPeakCollections(badWorkspaces),
                      std::invalid_argument);
@@ -669,7 +670,7 @@ private:
   void storeRandomWorkspaces(const std::vector<std::string> &wsNames) {
     for (auto it = wsNames.begin(); it != wsNames.end(); ++it) {
       WorkspaceCreationHelper::storeWS(
-          *it, WorkspaceCreationHelper::Create1DWorkspaceRand(10));
+          *it, WorkspaceCreationHelper::create1DWorkspaceRand(10));
     }
   }
 
diff --git a/Framework/SINQ/test/PoldiPeakCollectionTest.h b/Framework/SINQ/test/PoldiPeakCollectionTest.h
index e2a309f48fad566a21c0c2373504f67a40e9fb25..5f91b3dd074c82498e01c6d166a53d0f2e802f8f 100644
--- a/Framework/SINQ/test/PoldiPeakCollectionTest.h
+++ b/Framework/SINQ/test/PoldiPeakCollectionTest.h
@@ -15,6 +15,7 @@
 #include "MantidGeometry/Crystal/BraggScattererFactory.h"
 #include "MantidGeometry/Crystal/ReflectionGenerator.h"
 
+#include <boost/bind.hpp>
 #include <stdexcept>
 
 using namespace Mantid::Poldi;
diff --git a/Framework/SINQ/test/PoldiResidualCorrelationCoreTest.h b/Framework/SINQ/test/PoldiResidualCorrelationCoreTest.h
index 8f12f7167c296db98122eebaaed60d959b48277c..bfefe641186bd9b64342979b15c9a865de32520c 100644
--- a/Framework/SINQ/test/PoldiResidualCorrelationCoreTest.h
+++ b/Framework/SINQ/test/PoldiResidualCorrelationCoreTest.h
@@ -39,7 +39,7 @@ public:
 
     // test data with all 0s except (0, 0) - it's -1.0
     Mantid::DataObjects::Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     testWorkspace->dataY(0)[0] = -1.0;
 
     core.setNormCountData(testWorkspace);
@@ -63,7 +63,7 @@ public:
     TestablePoldiResidualCorrelationCore core(m_log);
 
     Mantid::DataObjects::Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     core.setCountData(testWorkspace);
 
     TS_ASSERT_EQUALS(testWorkspace->dataY(0)[0], 0.0);
@@ -98,7 +98,7 @@ public:
     TestablePoldiResidualCorrelationCore core(m_log);
 
     Mantid::DataObjects::Workspace2D_sptr testWorkspace =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(2, 2);
     core.setCountData(testWorkspace);
     core.m_timeBinCount = 2;
     core.m_detectorElements = {0, 1};
diff --git a/Framework/SINQ/test/PoldiSpectrumConstantBackgroundTest.h b/Framework/SINQ/test/PoldiSpectrumConstantBackgroundTest.h
index 03cd8399f10a2bfb68c5c4d0be1ee79aa4e83dab..099dc86190fd48005e95136bcbf061c1825fb4f9 100644
--- a/Framework/SINQ/test/PoldiSpectrumConstantBackgroundTest.h
+++ b/Framework/SINQ/test/PoldiSpectrumConstantBackgroundTest.h
@@ -37,7 +37,7 @@ public:
         "PoldiSpectrumConstantBackground");
     TS_ASSERT(function);
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(20, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(20, 2);
 
     TS_ASSERT_THROWS_NOTHING(function->setWorkspace(ws));
     function->setParameter(0, 10.0);
@@ -56,7 +56,7 @@ public:
         "PoldiSpectrumConstantBackground");
     TS_ASSERT(function);
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(20, 2);
+        WorkspaceCreationHelper::create2DWorkspace123(20, 2);
 
     TS_ASSERT_THROWS_NOTHING(function->setWorkspace(ws));
     function->setParameter(0, 10.0);
diff --git a/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h b/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
index d3b29c1bd97e1710726fce9226fddd5703d8e117..71120c01cec2eda4f37ceea05983abd52f553caa 100644
--- a/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
+++ b/Framework/SINQ/test/PoldiSpectrumLinearBackgroundTest.h
@@ -66,7 +66,7 @@ public:
 
     // valid workspace with 10 bins
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 10);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 10);
     TS_ASSERT_THROWS_NOTHING(castedFunction->setWorkspace(ws));
     TS_ASSERT_EQUALS(castedFunction->getTimeBinCount(), 10);
   }
@@ -116,7 +116,7 @@ public:
     /* Luckily, these are exactly the data described by this function,
      * using A1 = 1.0, so this is used as a test */
     MatrixWorkspace_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(20, 2);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(20, 2);
 
     IFunction_sptr function = FunctionFactory::Instance().createFunction(
         "PoldiSpectrumLinearBackground");
diff --git a/Framework/SINQ/test/PoldiSpectrumPawleyFunctionTest.h b/Framework/SINQ/test/PoldiSpectrumPawleyFunctionTest.h
index 0efdb4737a8e50569c9bfbdfb12c3efcf81e94c5..e12511644860ddeda60f632cea15e982bc22ce50 100644
--- a/Framework/SINQ/test/PoldiSpectrumPawleyFunctionTest.h
+++ b/Framework/SINQ/test/PoldiSpectrumPawleyFunctionTest.h
@@ -109,7 +109,7 @@ public:
     fn.setDecoratedFunction("MockPawleyFunction");
 
     MatrixWorkspace_const_sptr ws =
-        WorkspaceCreationHelper::Create2DWorkspace123(4, 10);
+        WorkspaceCreationHelper::create2DWorkspace123(4, 10);
 
     // Make sure the setMatrixWorkspace method can be called directly.
     IPawleyFunction_sptr pFn = fn.getPawleyFunction();
diff --git a/Framework/SINQ/test/PoldiTruncateDataTest.h b/Framework/SINQ/test/PoldiTruncateDataTest.h
index fd304040c424971abefeb2580c237233f9e55c75..6a4fe84a6ce60d11bc10e37b62c7412f409d880d 100644
--- a/Framework/SINQ/test/PoldiTruncateDataTest.h
+++ b/Framework/SINQ/test/PoldiTruncateDataTest.h
@@ -70,7 +70,7 @@ public:
   void testSetTimeBinWidthFromWorkspace() {
     // workspace with delta x = 1.0, 3 bins (= 4 boundaries)
     MatrixWorkspace_sptr matrixWs =
-        WorkspaceCreationHelper::Create2DWorkspaceWhereYIsWorkspaceIndex(1, 3);
+        WorkspaceCreationHelper::create2DWorkspaceWhereYIsWorkspaceIndex(1, 3);
 
     TestablePoldiTruncateData truncate;
     TS_ASSERT_THROWS_NOTHING(truncate.setTimeBinWidthFromWorkspace(matrixWs));
@@ -83,7 +83,7 @@ public:
 
     // matrix workspace with one bin
     MatrixWorkspace_sptr invalidBins =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 1);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 1);
 
     TS_ASSERT_THROWS(truncate.setTimeBinWidthFromWorkspace(invalidBins),
                      std::invalid_argument);
@@ -293,7 +293,7 @@ private:
     }
 
     MatrixWorkspace_sptr workspace =
-        WorkspaceCreationHelper::Create2DWorkspace123(histograms, binCount);
+        WorkspaceCreationHelper::create2DWorkspace123(histograms, binCount);
 
     for (size_t i = 0; i < histograms; ++i) {
       std::vector<double> &xData = workspace->dataX(i);
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
index cfeac531fc68e6cc0ce3b28a990b29a25caf88ee..0ff3dbd316a8cd2aa217714737be61e12d619538 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/FakeObjects.h
@@ -32,7 +32,6 @@
 #include "MantidKernel/cow_ptr.h"
 
 using namespace Mantid::API;
-using namespace Mantid::Kernel;
 using namespace Mantid;
 
 //===================================================================================================================
@@ -52,13 +51,13 @@ public:
     m_histogram.setCountStandardDeviations(0);
   }
 
-  void setX(const cow_ptr<HistogramData::HistogramX> &X) override {
+  void setX(const Kernel::cow_ptr<HistogramData::HistogramX> &X) override {
     m_histogram.setX(X);
   }
   MantidVec &dataX() override { return m_histogram.dataX(); }
   const MantidVec &dataX() const override { return m_histogram.dataX(); }
   const MantidVec &readX() const override { return m_histogram.readX(); }
-  cow_ptr<HistogramData::HistogramX> ptrX() const override {
+  Kernel::cow_ptr<HistogramData::HistogramX> ptrX() const override {
     return m_histogram.ptrX();
   }
 
@@ -261,7 +260,7 @@ public:
     throw std::runtime_error("find not implemented");
   }
 
-  void find(V3D, size_t &, const size_t &) override {
+  void find(Kernel::V3D, size_t &, const size_t &) override {
     throw std::runtime_error("find not implemented");
   }
 
diff --git a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
index f0144963c8e90db0ab192c33c9009d81b0f0b492..445044428e38c386481d7448ed865c0b6b351488 100644
--- a/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
+++ b/Framework/TestHelpers/inc/MantidTestHelpers/WorkspaceCreationHelper.h
@@ -10,15 +10,14 @@
  *********************************************************************************/
 #ifndef WORKSPACECREATIONHELPER_H_
 #define WORKSPACECREATIONHELPER_H_
-//------------------------------------------------------------------------------
-// Includes
-//------------------------------------------------------------------------------
+
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/RebinnedOutput.h"
 #include "MantidDataObjects/Workspace2D.h"
 #include "MantidDataObjects/WorkspaceSingleValue.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAPI/WorkspaceFactory.h"
@@ -52,9 +51,9 @@ class MockAlgorithm : public Mantid::API::Algorithm {
 public:
   MockAlgorithm(size_t nSteps = 100);
   /// Algorithm's name for identification
-  const std::string name() const override { return "MockAlgorithm"; };
+  const std::string name() const override { return "MockAlgorithm"; }
   /// Algorithm's version for identification
-  int version() const override { return 1; };
+  int version() const override { return 1; }
   /// Algorithm's category for identification
   const std::string category() const override { return "Test"; }
   /// Algorithm's summary.
@@ -69,8 +68,8 @@ public:
   }
 
 private:
-  void init() override{};
-  void exec() override{};
+  void init() override {}
+  void exec() override {}
 
   std::unique_ptr<Mantid::API::Progress> m_Progress;
   /// logger -> to provide logging,
@@ -86,25 +85,24 @@ template <typename T> boost::shared_ptr<T> getWS(const std::string &name) {
   return Mantid::API::AnalysisDataService::Instance().retrieveWS<T>(name);
 }
 
-Mantid::DataObjects::Workspace2D_sptr Create1DWorkspaceRand(int size);
+Mantid::DataObjects::Workspace2D_sptr create1DWorkspaceRand(int size);
 Mantid::DataObjects::Workspace2D_sptr
-Create1DWorkspaceConstant(int size, double value, double error);
-Mantid::DataObjects::Workspace2D_sptr Create1DWorkspaceFib(int size);
+create1DWorkspaceConstant(int size, double value, double error);
+Mantid::DataObjects::Workspace2D_sptr create1DWorkspaceFib(int size);
 Mantid::DataObjects::Workspace2D_sptr
-Create1DWorkspaceConstantWithXerror(int size, double value, double error,
+create1DWorkspaceConstantWithXerror(int size, double value, double error,
                                     double xError);
-Mantid::DataObjects::Workspace2D_sptr Create2DWorkspace(
-    int nhist,
-    int numBoundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundaries);
+Mantid::DataObjects::Workspace2D_sptr create2DWorkspace(int nhist,
+                                                        int numBoundaries);
 Mantid::DataObjects::Workspace2D_sptr
-Create2DWorkspaceWhereYIsWorkspaceIndex(int nhist, int numBoundaries);
-Mantid::DataObjects::Workspace2D_sptr Create2DWorkspace123(
-    int64_t nHist, int64_t nBinsssssssssssss, bool isHist = false,
+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>());
-Mantid::DataObjects::Workspace2D_sptr Create2DWorkspace154(
+Mantid::DataObjects::Workspace2D_sptr create2DWorkspace154(
     int64_t nHist, int64_t nBins, bool isHist = false,
     const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>());
-Mantid::DataObjects::Workspace2D_sptr Create2DWorkspaceWithValuesAndXerror(
+Mantid::DataObjects::Workspace2D_sptr create2DWorkspaceWithValuesAndXerror(
     int64_t nHist, int64_t nBins, bool isHist, double xVal, double yVal,
     double eVal, double dxVal,
     const std::set<int64_t> &maskedWorkspaceIndices = std::set<int64_t>());
@@ -114,25 +112,23 @@ maskSpectra(Mantid::DataObjects::Workspace2D_sptr workspace,
 /**
  * Create a WorkspaceGroup with N workspaces and the specified parameters
  */
-Mantid::API::WorkspaceGroup_sptr CreateWorkspaceGroup(int nEntries, int nHist,
+Mantid::API::WorkspaceGroup_sptr createWorkspaceGroup(int nEntries, int nHist,
                                                       int nBins,
                                                       const std::string &stem);
 /** Create a 2D workspace with this many histograms and bins.
  * Filled with Y = 2.0 and E = sqrt(2.0)w
  */
 Mantid::DataObjects::Workspace2D_sptr
-Create2DWorkspaceBinned(int nhist, int nbins, double x0 = 0.0,
+create2DWorkspaceBinned(int nhist, int nbins, double x0 = 0.0,
                         double deltax = 1.0);
 
 /** 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 = sqrt(2.0)w
  */
-Mantid::DataObjects::Workspace2D_sptr Create2DWorkspaceBinned(
-    int nhist,
-    const int
-        numBoundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundariesundaries,
-    const double xBoundaries[]);
+Mantid::DataObjects::Workspace2D_sptr
+create2DWorkspaceBinned(int nhist, const int numBoundaries,
+                        const double xBoundaries[]);
 
 /**
  * Creates a 2D workspace from taking the function values from the input
@@ -147,7 +143,7 @@ Mantid::DataObjects::Workspace2D_sptr Create2DWorkspaceBinned(
  */
 template <typename Func>
 Mantid::DataObjects::Workspace2D_sptr
-Create2DWorkspaceFromFunction(Func f, int nSpec, double x0, double x1,
+create2DWorkspaceFromFunction(Func f, int nSpec, double x0, double x1,
                               double dx, bool isHist = false) {
   int nX = int((x1 - x0) / dx) + 1;
   int nY = nX - (isHist ? 1 : 0);
@@ -225,16 +221,16 @@ Mantid::DataObjects::EventWorkspace_sptr
 createEventWorkspaceWithNonUniformInstrument(int numBanks, bool clearEvents);
 
 Mantid::DataObjects::WorkspaceSingleValue_sptr
-CreateWorkspaceSingleValue(double value);
+createWorkspaceSingleValue(double value);
 Mantid::DataObjects::WorkspaceSingleValue_sptr
-CreateWorkspaceSingleValueWithError(double value, double error);
+createWorkspaceSingleValueWithError(double value, double error);
 /** Perform some finalization on event workspace stuff */
-void EventWorkspace_Finalize(Mantid::DataObjects::EventWorkspace_sptr ew);
+void eventWorkspace_Finalize(Mantid::DataObjects::EventWorkspace_sptr ew);
 /** Create event workspace with:
  * 500 pixels
  * 1000 histogrammed bins.
  */
-Mantid::DataObjects::EventWorkspace_sptr CreateEventWorkspace();
+Mantid::DataObjects::EventWorkspace_sptr createEventWorkspace();
 
 /** Create event workspace with:
  * 50 pixels
@@ -243,50 +239,50 @@ Mantid::DataObjects::EventWorkspace_sptr CreateEventWorkspace();
  * PulseTime = 1 second, 2 seconds, etc.
  */
 Mantid::DataObjects::EventWorkspace_sptr
-CreateEventWorkspace2(int numPixels = 50, int numBins = 100);
+createEventWorkspace2(int numPixels = 50, int numBins = 100);
 
 Mantid::DataObjects::EventWorkspace_sptr
-CreateEventWorkspace(int numPixels, int numBins, int numEvents = 100,
+createEventWorkspace(int numPixels, int numBins, int numEvents = 100,
                      double x0 = 0.0, double binDelta = 1.0,
                      int eventPattern = 1, int start_at_pixelID = 0);
 
-Mantid::DataObjects::EventWorkspace_sptr CreateEventWorkspaceWithStartTime(
+Mantid::DataObjects::EventWorkspace_sptr createEventWorkspaceWithStartTime(
     int numPixels, int numBins, int numEvents = 100, double x0 = 0.0,
     double binDelta = 1.0, int eventPattern = 1, int start_at_pixelID = 0,
     Mantid::Kernel::DateAndTime run_start =
         Mantid::Kernel::DateAndTime("2010-01-01T00:00:00"));
 
 Mantid::DataObjects::EventWorkspace_sptr
-CreateGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
+createGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
                             double binDelta = 1., double xOffset = 0.);
 
 Mantid::DataObjects::EventWorkspace_sptr
-CreateRandomEventWorkspace(size_t numbins, size_t numpixels,
+createRandomEventWorkspace(size_t numbins, size_t numpixels,
                            double bin_delta = 1.0);
 
 Mantid::API::MatrixWorkspace_sptr
-CreateGroupedWorkspace2D(size_t numHist, int numBins, double binDelta);
+createGroupedWorkspace2D(size_t numHist, int numBins, double binDelta);
 // grouped workspace with detectors arranges in rings in center and into boxes
 // outside
-Mantid::API::MatrixWorkspace_sptr CreateGroupedWorkspace2DWithRingsAndBoxes(
+Mantid::API::MatrixWorkspace_sptr createGroupedWorkspace2DWithRingsAndBoxes(
     size_t RootOfNumHist = 10, int numBins = 10, double binDelta = 1.0);
 // not strictly creating a workspace, but really helpful to see what one
 // contains
-void DisplayDataY(const Mantid::API::MatrixWorkspace_sptr ws);
+void displayDataY(const Mantid::API::MatrixWorkspace_sptr ws);
 // not strictly creating a workspace, but really helpful to see what one
 // contains
-void DisplayData(const Mantid::API::MatrixWorkspace_sptr ws);
+void displayData(const Mantid::API::MatrixWorkspace_sptr ws);
 // not strictly creating a workspace, but really helpful to see what one
 // contains
-void DisplayDataX(const Mantid::API::MatrixWorkspace_sptr ws);
+void displayDataX(const Mantid::API::MatrixWorkspace_sptr ws);
 // not strictly creating a workspace, but really helpful to see what one
 // contains
-void DisplayDataE(const Mantid::API::MatrixWorkspace_sptr ws);
+void displayDataE(const Mantid::API::MatrixWorkspace_sptr ws);
 
-void AddTSPEntry(Mantid::API::Run &runInfo, std::string name, double val);
-void SetOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
+void addTSPEntry(Mantid::API::Run &runInfo, std::string name, double val);
+void setOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
                         double b, double c);
-void SetGoniometer(Mantid::API::MatrixWorkspace_sptr ws, double phi, double chi,
+void setGoniometer(Mantid::API::MatrixWorkspace_sptr ws, double phi, double chi,
                    double omega);
 
 // create workspace which should be result of homering (transform to energy in
@@ -307,7 +303,7 @@ createEventWorkspace3(Mantid::DataObjects::EventWorkspace_const_sptr sourceWS,
                       std::string wsname, Mantid::API::Algorithm *alg);
 
 /// Function to create a fixed RebinnedOutput workspace
-Mantid::DataObjects::RebinnedOutput_sptr CreateRebinnedOutputWorkspace();
+Mantid::DataObjects::RebinnedOutput_sptr createRebinnedOutputWorkspace();
 
 /// Create a simple peaks workspace containing the given number of peaks
 boost::shared_ptr<Mantid::DataObjects::PeaksWorkspace>
diff --git a/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp b/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp
index 9ad38437ee3b99078478bb735d90c9e1c0e7127f..fbb8e2a80f232976c569a7af0b767c817f603277 100644
--- a/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp
+++ b/Framework/TestHelpers/src/BinaryOperationMDTestHelper.cpp
@@ -38,7 +38,7 @@ void setUpBinaryOperationMDTestHelper() {
       MDEventsTestHelper::makeFakeMDHistoWorkspace(0.0, 2, 5, 10.0, 0.0);
   event_A = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
   event_B = MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
-  scalar = WorkspaceCreationHelper::CreateWorkspaceSingleValue(3.0);
+  scalar = WorkspaceCreationHelper::createWorkspaceSingleValue(3.0);
   AnalysisDataService::Instance().addOrReplace("histo_A", histo_A);
   AnalysisDataService::Instance().addOrReplace("histo_B", histo_B);
   AnalysisDataService::Instance().addOrReplace("histo_masked", histo_masked);
@@ -97,7 +97,7 @@ MDHistoWorkspace_sptr doTest(std::string algoName, std::string inName,
   IMDEventWorkspace_sptr event =
       MDEventsTestHelper::makeMDEW<2>(3, 0.0, 10.0, 1);
   WorkspaceSingleValue_sptr scalar =
-      WorkspaceCreationHelper::CreateWorkspaceSingleValue(2.5);
+      WorkspaceCreationHelper::createWorkspaceSingleValue(2.5);
   AnalysisDataService::Instance().addOrReplace("histo", histo);
   AnalysisDataService::Instance().addOrReplace("event", event);
   AnalysisDataService::Instance().addOrReplace("scalar", scalar);
diff --git a/Framework/TestHelpers/src/FakeObjects.cpp b/Framework/TestHelpers/src/FakeObjects.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dfcf040c0092231bc8dd61b5ef6e1129e22bced5
--- /dev/null
+++ b/Framework/TestHelpers/src/FakeObjects.cpp
@@ -0,0 +1,21 @@
+#include "MantidTestHelpers/FakeObjects.h"
+
+// Property implementations
+#include "MantidKernel/PropertyWithValue.tcc"
+#include "MantidAPI/WorkspaceProperty.tcc"
+
+namespace Mantid {
+namespace Kernel {
+///@cond TEMPLATE
+template class DLLExport PropertyWithValue<boost::shared_ptr<WorkspaceTester>>;
+template class DLLExport
+    PropertyWithValue<boost::shared_ptr<TableWorkspaceTester>>;
+///@endcond TEMPLATE
+} // namespace Kernel
+namespace API {
+///@cond TEMPLATE
+template class DLLExport Mantid::API::WorkspaceProperty<WorkspaceTester>;
+template class DLLExport Mantid::API::WorkspaceProperty<TableWorkspaceTester>;
+///@endcond TEMPLATE
+} // namespace API
+} // namespace Mantid
diff --git a/Framework/TestHelpers/src/InstrumentCreationHelper.cpp b/Framework/TestHelpers/src/InstrumentCreationHelper.cpp
index cdf9f76f888d2133deb80fce1a0d899f7b027d20..6b90c7f69fdd6121cf0c4bf103da34fbdc99db38 100644
--- a/Framework/TestHelpers/src/InstrumentCreationHelper.cpp
+++ b/Framework/TestHelpers/src/InstrumentCreationHelper.cpp
@@ -18,7 +18,6 @@ void addFullInstrumentToWorkspace(MatrixWorkspace &workspace,
   auto instrument = boost::make_shared<Instrument>(instrumentName);
   instrument->setReferenceFrame(
       boost::make_shared<ReferenceFrame>(Y, Z, Right, ""));
-  workspace.setInstrument(instrument);
 
   const double pixelRadius(0.05);
   Object_sptr pixelShape = ComponentCreationHelper::createCappedCylinder(
@@ -87,5 +86,6 @@ void addFullInstrumentToWorkspace(MatrixWorkspace &workspace,
   Component *chop_pos = new Component("chopper-position",
                                       Kernel::V3D(0, 0, -10), instrument.get());
   instrument->add(chop_pos);
+  workspace.setInstrument(instrument);
 }
 }
diff --git a/Framework/TestHelpers/src/MDEventsTestHelper.cpp b/Framework/TestHelpers/src/MDEventsTestHelper.cpp
index 63d708ccfbe2652f6933c4f5d8607e0d3ac0b25a..0011f7534351588a6440ad51344af7ebccd3688c 100644
--- a/Framework/TestHelpers/src/MDEventsTestHelper.cpp
+++ b/Framework/TestHelpers/src/MDEventsTestHelper.cpp
@@ -100,8 +100,8 @@ createDiffractionEventWorkspace(int numEvents, int numPixels, int numBins) {
   retVal->getAxis(0)->setUnit("TOF");
 
   // Give it a crystal and goniometer
-  WorkspaceCreationHelper::SetGoniometer(retVal, 0., 0., 0.);
-  WorkspaceCreationHelper::SetOrientedLattice(retVal, 1., 1., 1.);
+  WorkspaceCreationHelper::setGoniometer(retVal, 0., 0., 0.);
+  WorkspaceCreationHelper::setOrientedLattice(retVal, 1., 1., 1.);
 
   // Some sanity checks
   if (retVal->getInstrument()->getName() != "MINITOPAZ")
diff --git a/Framework/TestHelpers/src/SANSInstrumentCreationHelper.cpp b/Framework/TestHelpers/src/SANSInstrumentCreationHelper.cpp
index e367ec58f3609ae10c83512e401ba2dc2ff48254..d761925f43fb7755d5839f53f9e920e294511d53 100644
--- a/Framework/TestHelpers/src/SANSInstrumentCreationHelper.cpp
+++ b/Framework/TestHelpers/src/SANSInstrumentCreationHelper.cpp
@@ -40,7 +40,7 @@ Workspace2D_sptr SANSInstrumentCreationHelper::createSANSInstrumentWorkspace(
     std::string workspace) {
   // Create a test workspace with test data with a well defined peak
   // The test instrument has two monitor channels
-  Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace123(
+  Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace123(
       nBins * nBins + nMonitors, 1, 1);
   AnalysisDataService::Instance().addOrReplace(workspace, ws);
   ws->getAxis(0)->unit() =
diff --git a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
index 0ea9ef83badb5e07d2e60b93ef199e088799f6ed..e920ddc0b9f4651d4bd9310afc3d9764da2ea079 100644
--- a/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
+++ b/Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
@@ -18,9 +18,12 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/Sample.h"
 #include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidGeometry/Instrument/Detector.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidGeometry/Instrument/ReferenceFrame.h"
 #include "MantidGeometry/Instrument/Component.h"
@@ -65,7 +68,7 @@ void removeWS(const std::string &name) {
   Mantid::API::AnalysisDataService::Instance().remove(name);
 }
 
-Workspace2D_sptr Create1DWorkspaceRand(int size) {
+Workspace2D_sptr create1DWorkspaceRand(int size) {
   MantidVec y1(size);
   MantidVec e1(size);
 
@@ -83,7 +86,7 @@ Workspace2D_sptr Create1DWorkspaceRand(int size) {
   return retVal;
 }
 
-Workspace2D_sptr Create1DWorkspaceConstant(int size, double value,
+Workspace2D_sptr create1DWorkspaceConstant(int size, double value,
                                            double error) {
   MantidVec y1(size, value);
   MantidVec e1(size, error);
@@ -95,16 +98,16 @@ Workspace2D_sptr Create1DWorkspaceConstant(int size, double value,
   return retVal;
 }
 
-Workspace2D_sptr Create1DWorkspaceConstantWithXerror(int size, double value,
+Workspace2D_sptr create1DWorkspaceConstantWithXerror(int size, double value,
                                                      double error,
                                                      double xError) {
-  auto ws = Create1DWorkspaceConstant(size, value, error);
+  auto ws = create1DWorkspaceConstant(size, value, error);
   auto dx1 = Kernel::make_cow<HistogramData::HistogramDx>(size, xError);
   ws->setSharedDx(0, dx1);
   return ws;
 }
 
-Workspace2D_sptr Create1DWorkspaceFib(int size) {
+Workspace2D_sptr create1DWorkspaceFib(int size) {
   MantidVec y1(size);
   MantidVec e1(size);
   std::generate(y1.begin(), y1.end(), FibSeries<double>());
@@ -116,8 +119,8 @@ Workspace2D_sptr Create1DWorkspaceFib(int size) {
   return retVal;
 }
 
-Workspace2D_sptr Create2DWorkspace(int nhist, int numBoundaries) {
-  return Create2DWorkspaceBinned(nhist, numBoundaries);
+Workspace2D_sptr create2DWorkspace(int nhist, int numBoundaries) {
+  return create2DWorkspaceBinned(nhist, numBoundaries);
 }
 
 /** Create a Workspace2D where the Y value at each bin is
@@ -126,9 +129,9 @@ Workspace2D_sptr Create2DWorkspace(int nhist, int numBoundaries) {
  * @param numBoundaries :: # of bins
  * @return Workspace2D
  */
-Workspace2D_sptr Create2DWorkspaceWhereYIsWorkspaceIndex(int nhist,
+Workspace2D_sptr create2DWorkspaceWhereYIsWorkspaceIndex(int nhist,
                                                          int numBoundaries) {
-  Workspace2D_sptr out = Create2DWorkspaceBinned(nhist, numBoundaries);
+  Workspace2D_sptr out = create2DWorkspaceBinned(nhist, numBoundaries);
   for (int wi = 0; wi < nhist; wi++)
     for (int x = 0; x < numBoundaries; x++)
       out->dataY(wi)[x] = wi * 1.0;
@@ -137,7 +140,7 @@ Workspace2D_sptr Create2DWorkspaceWhereYIsWorkspaceIndex(int nhist,
 
 Workspace2D_sptr create2DWorkspaceThetaVsTOF(int nHist, int nBins) {
 
-  Workspace2D_sptr outputWS = Create2DWorkspaceBinned(nHist, nBins);
+  Workspace2D_sptr outputWS = create2DWorkspaceBinned(nHist, nBins);
   auto const newAxis = new NumericAxis(nHist);
   outputWS->replaceAxis(1, newAxis);
   newAxis->unit() = boost::make_shared<Units::Degrees>();
@@ -149,7 +152,7 @@ Workspace2D_sptr create2DWorkspaceThetaVsTOF(int nHist, int nBins) {
 }
 
 Workspace2D_sptr
-Create2DWorkspaceWithValues(int64_t nHist, int64_t nBins, bool isHist,
+create2DWorkspaceWithValues(int64_t nHist, int64_t nBins, bool isHist,
                             const std::set<int64_t> &maskedWorkspaceIndices,
                             double xVal, double yVal, double eVal) {
   auto x1 = Kernel::make_cow<HistogramData::HistogramX>(
@@ -169,11 +172,11 @@ Create2DWorkspaceWithValues(int64_t nHist, int64_t nBins, bool isHist,
   return retVal;
 }
 
-Workspace2D_sptr Create2DWorkspaceWithValuesAndXerror(
+Workspace2D_sptr create2DWorkspaceWithValuesAndXerror(
     int64_t nHist, int64_t nBins, bool isHist, double xVal, double yVal,
     double eVal, double dxVal,
     const std::set<int64_t> &maskedWorkspaceIndices) {
-  auto ws = Create2DWorkspaceWithValues(
+  auto ws = create2DWorkspaceWithValues(
       nHist, nBins, isHist, maskedWorkspaceIndices, xVal, yVal, eVal);
   PointStandardDeviations dx1(nBins, dxVal);
   for (int i = 0; i < nHist; i++) {
@@ -183,16 +186,16 @@ Workspace2D_sptr Create2DWorkspaceWithValuesAndXerror(
 }
 
 Workspace2D_sptr
-Create2DWorkspace123(int64_t nHist, int64_t nBins, bool isHist,
+create2DWorkspace123(int64_t nHist, int64_t nBins, bool isHist,
                      const std::set<int64_t> &maskedWorkspaceIndices) {
-  return Create2DWorkspaceWithValues(nHist, nBins, isHist,
+  return create2DWorkspaceWithValues(nHist, nBins, isHist,
                                      maskedWorkspaceIndices, 1.0, 2.0, 3.0);
 }
 
 Workspace2D_sptr
-Create2DWorkspace154(int64_t nHist, int64_t nBins, bool isHist,
+create2DWorkspace154(int64_t nHist, int64_t nBins, bool isHist,
                      const std::set<int64_t> &maskedWorkspaceIndices) {
-  return Create2DWorkspaceWithValues(nHist, nBins, isHist,
+  return create2DWorkspaceWithValues(nHist, nBins, isHist,
                                      maskedWorkspaceIndices, 1.0, 5.0, 4.0);
 }
 
@@ -221,25 +224,21 @@ Workspace2D_sptr maskSpectra(Workspace2D_sptr workspace,
     workspace->setInstrument(instrument);
   }
 
-  ParameterMap &pmap = workspace->instrumentParameters();
-  for (int i = 0; i < nhist; ++i) {
-    if (maskedWorkspaceIndices.find(i) != maskedWorkspaceIndices.end()) {
-      IDetector_const_sptr det = workspace->getDetector(i);
-      pmap.addBool(det.get(), "masked", true);
-    }
-  }
+  auto &spectrumInfo = workspace->mutableSpectrumInfo();
+  for (const auto index : maskedWorkspaceIndices)
+    spectrumInfo.setMasked(index, true);
   return workspace;
 }
 
 /**
  * Create a group with nEntries. It is added to the ADS with the given stem
  */
-WorkspaceGroup_sptr CreateWorkspaceGroup(int nEntries, int nHist, int nBins,
+WorkspaceGroup_sptr createWorkspaceGroup(int nEntries, int nHist, int nBins,
                                          const std::string &stem) {
   auto group = boost::make_shared<WorkspaceGroup>();
   AnalysisDataService::Instance().add(stem, group);
   for (int i = 0; i < nEntries; ++i) {
-    Workspace2D_sptr ws = Create2DWorkspace(nHist, nBins);
+    Workspace2D_sptr ws = create2DWorkspace(nHist, nBins);
     std::ostringstream os;
     os << stem << "_" << i;
     AnalysisDataService::Instance().add(os.str(), ws);
@@ -251,7 +250,7 @@ WorkspaceGroup_sptr CreateWorkspaceGroup(int nEntries, int nHist, int nBins,
 /** Create a 2D workspace with this many histograms and bins.
  * Filled with Y = 2.0 and E = M_SQRT2w
  */
-Workspace2D_sptr Create2DWorkspaceBinned(int nhist, int nbins, double x0,
+Workspace2D_sptr create2DWorkspaceBinned(int nhist, int nbins, double x0,
                                          double deltax) {
   BinEdges x(nbins + 1, LinearGenerator(x0, deltax));
   Counts y(nbins, 2);
@@ -270,7 +269,7 @@ Workspace2D_sptr Create2DWorkspaceBinned(int nhist, int nbins, double x0,
  * assumed to be non-uniform and given by the input array
  * Filled with Y = 2.0 and E = M_SQRT2w
  */
-Workspace2D_sptr Create2DWorkspaceBinned(int nhist, const int numBoundaries,
+Workspace2D_sptr create2DWorkspaceBinned(int nhist, const int numBoundaries,
                                          const double xBoundaries[]) {
   BinEdges x(xBoundaries, xBoundaries + numBoundaries);
   const int numBins = numBoundaries - 1;
@@ -326,10 +325,10 @@ create2DWorkspaceWithFullInstrument(int nhist, int nbins, bool includeMonitors,
 
   Workspace2D_sptr space;
   if (isHistogram)
-    space = Create2DWorkspaceBinned(
+    space = create2DWorkspaceBinned(
         nhist, nbins); // A 1:1 spectra is created by default
   else
-    space = Create2DWorkspace123(nhist, nbins, false);
+    space = create2DWorkspace123(nhist, nbins, false);
   space->setTitle(
       "Test histogram"); // actually adds a property call run_title to the logs
   space->getAxis(0)->setUnit("TOF");
@@ -358,7 +357,7 @@ create2DWorkspaceWithRectangularInstrument(int numBanks, int numPixels,
       ComponentCreationHelper::createTestInstrumentRectangular(numBanks,
                                                                numPixels);
   Workspace2D_sptr ws =
-      Create2DWorkspaceBinned(numBanks * numPixels * numPixels, numBins);
+      create2DWorkspaceBinned(numBanks * numPixels * numPixels, numBins);
   ws->setInstrument(inst);
   ws->getAxis(0)->setUnit("dSpacing");
   for (size_t wi = 0; wi < ws->getNumberHistograms(); wi++) {
@@ -387,7 +386,7 @@ createEventWorkspaceWithFullInstrument(int numBanks, int numPixels,
       ComponentCreationHelper::createTestInstrumentRectangular(numBanks,
                                                                numPixels);
   EventWorkspace_sptr ws =
-      CreateEventWorkspace2(numBanks * numPixels * numPixels, 100);
+      createEventWorkspace2(numBanks * numPixels * numPixels, 100);
   ws->setInstrument(inst);
 
   // Set the X axes
@@ -421,7 +420,7 @@ createEventWorkspaceWithNonUniformInstrument(int numBanks, bool clearEvents) {
       ComponentCreationHelper::createTestInstrumentCylindrical(
           numBanks, srcPos, samplePos, 0.0025, 0.005);
   EventWorkspace_sptr ws =
-      CreateEventWorkspace2(numBanks * DETECTORS_PER_BANK, 100);
+      createEventWorkspace2(numBanks * DETECTORS_PER_BANK, 100);
   ws->setInstrument(inst);
 
   std::vector<detid_t> detectorIds = inst->getDetectorIDs();
@@ -477,7 +476,7 @@ create2DWorkspaceWithReflectometryInstrument(double startX) {
   const int nSpectra = 2;
   const int nBins = 100;
   const double deltaX = 2000; // TOF
-  auto workspace = Create2DWorkspaceBinned(nSpectra, nBins, startX, deltaX);
+  auto workspace = create2DWorkspaceBinned(nSpectra, nBins, startX, deltaX);
 
   workspace->setTitle(
       "Test histogram"); // actually adds a property call run_title to the logs
@@ -507,8 +506,6 @@ void createInstrumentForWorkspaceWithDistances(
   instrument->add(sample);
   instrument->markAsSamplePos(sample);
 
-  workspace->setInstrument(instrument);
-
   for (int i = 0; i < static_cast<int>(detectorPositions.size()); ++i) {
     std::stringstream buffer;
     buffer << "detector_" << i;
@@ -521,20 +518,21 @@ void createInstrumentForWorkspaceWithDistances(
     workspace->getSpectrum(i).clearDetectorIDs();
     workspace->getSpectrum(i).addDetectorID(det->getID());
   }
+  workspace->setInstrument(instrument);
 }
 
 //================================================================================================================
-WorkspaceSingleValue_sptr CreateWorkspaceSingleValue(double value) {
+WorkspaceSingleValue_sptr createWorkspaceSingleValue(double value) {
   return boost::make_shared<WorkspaceSingleValue>(value, sqrt(value));
 }
 
-WorkspaceSingleValue_sptr CreateWorkspaceSingleValueWithError(double value,
+WorkspaceSingleValue_sptr createWorkspaceSingleValueWithError(double value,
                                                               double error) {
   return boost::make_shared<WorkspaceSingleValue>(value, error);
 }
 
 /** Perform some finalization on event workspace stuff */
-void EventWorkspace_Finalize(EventWorkspace_sptr ew) {
+void eventWorkspace_Finalize(EventWorkspace_sptr ew) {
   // get a proton charge
   ew->mutableRun().integrateProtonCharge();
 }
@@ -543,8 +541,8 @@ void EventWorkspace_Finalize(EventWorkspace_sptr ew) {
  * 500 pixels
  * 1000 histogrammed bins.
  */
-EventWorkspace_sptr CreateEventWorkspace() {
-  return CreateEventWorkspace(500, 1001, 100, 1000);
+EventWorkspace_sptr createEventWorkspace() {
+  return createEventWorkspace(500, 1001, 100, 1000);
 }
 
 /** Create event workspace with:
@@ -553,17 +551,17 @@ EventWorkspace_sptr CreateEventWorkspace() {
  * 200 events; two in each bin, at time 0.5, 1.5, etc.
  * PulseTime = 0 second x2, 1 second x2, 2 seconds x2, etc. after 2010-01-01
  */
-EventWorkspace_sptr CreateEventWorkspace2(int numPixels, int numBins) {
-  return CreateEventWorkspace(numPixels, numBins, 100, 0.0, 1.0, 2);
+EventWorkspace_sptr createEventWorkspace2(int numPixels, int numBins) {
+  return createEventWorkspace(numPixels, numBins, 100, 0.0, 1.0, 2);
 }
 
 /** Create event workspace
  */
-EventWorkspace_sptr CreateEventWorkspace(int numPixels, int numBins,
+EventWorkspace_sptr createEventWorkspace(int numPixels, int numBins,
                                          int numEvents, double x0,
                                          double binDelta, int eventPattern,
                                          int start_at_pixelID) {
-  return CreateEventWorkspaceWithStartTime(
+  return createEventWorkspaceWithStartTime(
       numPixels, numBins, numEvents, x0, binDelta, eventPattern,
       start_at_pixelID, DateAndTime("2010-01-01T00:00:00"));
 }
@@ -572,7 +570,7 @@ EventWorkspace_sptr CreateEventWorkspace(int numPixels, int numBins,
  * Create event workspace with defined start date time
  */
 EventWorkspace_sptr
-CreateEventWorkspaceWithStartTime(int numPixels, int numBins, int numEvents,
+createEventWorkspaceWithStartTime(int numPixels, int numBins, int numEvents,
                                   double x0, double binDelta, int eventPattern,
                                   int start_at_pixelID, DateAndTime run_start) {
 
@@ -622,7 +620,7 @@ CreateEventWorkspaceWithStartTime(int numPixels, int numBins, int numEvents,
 /** Create event workspace, with several detector IDs in one event list.
  */
 EventWorkspace_sptr
-CreateGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
+createGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
                             double binDelta, double xOffset) {
 
   auto retVal = boost::make_shared<EventWorkspace>();
@@ -660,7 +658,7 @@ CreateGroupedEventWorkspace(std::vector<std::vector<int>> groups, int numBins,
  * @param bin_delta :: a constant offset to shift the bin bounds by
  * @return EventWorkspace
  */
-EventWorkspace_sptr CreateRandomEventWorkspace(size_t numbins, size_t numpixels,
+EventWorkspace_sptr createRandomEventWorkspace(size_t numbins, size_t numpixels,
                                                double bin_delta) {
   auto retVal = boost::make_shared<EventWorkspace>();
   retVal->initialize(numpixels, numbins, numbins - 1);
@@ -698,9 +696,9 @@ EventWorkspace_sptr CreateRandomEventWorkspace(size_t numbins, size_t numpixels,
 /** Create Workspace2d, with numHist spectra, each with 9 detectors,
  * with IDs 1-9, 10-18, 19-27
  */
-MatrixWorkspace_sptr CreateGroupedWorkspace2D(size_t numHist, int numBins,
+MatrixWorkspace_sptr createGroupedWorkspace2D(size_t numHist, int numBins,
                                               double binDelta) {
-  Workspace2D_sptr retVal = Create2DWorkspaceBinned(static_cast<int>(numHist),
+  Workspace2D_sptr retVal = create2DWorkspaceBinned(static_cast<int>(numHist),
                                                     numBins, 0.0, binDelta);
   retVal->setInstrument(
       ComponentCreationHelper::createTestInstrumentCylindrical(
@@ -718,10 +716,10 @@ MatrixWorkspace_sptr CreateGroupedWorkspace2D(size_t numHist, int numBins,
 // =====================================================================================
 // RootOfNumHist == square root of hystohram number;
 MatrixWorkspace_sptr
-CreateGroupedWorkspace2DWithRingsAndBoxes(size_t RootOfNumHist, int numBins,
+createGroupedWorkspace2DWithRingsAndBoxes(size_t RootOfNumHist, int numBins,
                                           double binDelta) {
   size_t numHist = RootOfNumHist * RootOfNumHist;
-  Workspace2D_sptr retVal = Create2DWorkspaceBinned(static_cast<int>(numHist),
+  Workspace2D_sptr retVal = create2DWorkspaceBinned(static_cast<int>(numHist),
                                                     numBins, 0.0, binDelta);
   retVal->setInstrument(
       ComponentCreationHelper::createTestInstrumentCylindrical(
@@ -737,7 +735,7 @@ CreateGroupedWorkspace2DWithRingsAndBoxes(size_t RootOfNumHist, int numBins,
 
 // not strictly creating a workspace, but really helpfull to see what one
 // contains
-void DisplayDataY(const MatrixWorkspace_sptr ws) {
+void displayDataY(const MatrixWorkspace_sptr ws) {
   const size_t numHists = ws->getNumberHistograms();
   for (size_t i = 0; i < numHists; ++i) {
     std::cout << "Histogram " << i << " = ";
@@ -747,11 +745,11 @@ void DisplayDataY(const MatrixWorkspace_sptr ws) {
     std::cout << '\n';
   }
 }
-void DisplayData(const MatrixWorkspace_sptr ws) { DisplayDataX(ws); }
+void displayData(const MatrixWorkspace_sptr ws) { displayDataX(ws); }
 
 // not strictly creating a workspace, but really helpfull to see what one
 // contains
-void DisplayDataX(const MatrixWorkspace_sptr ws) {
+void displayDataX(const MatrixWorkspace_sptr ws) {
   const size_t numHists = ws->getNumberHistograms();
   for (size_t i = 0; i < numHists; ++i) {
     std::cout << "Histogram " << i << " = ";
@@ -764,7 +762,7 @@ void DisplayDataX(const MatrixWorkspace_sptr ws) {
 
 // not strictly creating a workspace, but really helpfull to see what one
 // contains
-void DisplayDataE(const MatrixWorkspace_sptr ws) {
+void displayDataE(const MatrixWorkspace_sptr ws) {
   const size_t numHists = ws->getNumberHistograms();
   for (size_t i = 0; i < numHists; ++i) {
     std::cout << "Histogram " << i << " = ";
@@ -782,7 +780,7 @@ void DisplayDataE(const MatrixWorkspace_sptr ws) {
  * @param name :: property name
  * @param val :: value
  */
-void AddTSPEntry(Run &runInfo, std::string name, double val) {
+void addTSPEntry(Run &runInfo, std::string name, double val) {
   TimeSeriesProperty<double> *tsp;
   tsp = new TimeSeriesProperty<double>(name);
   tsp->addValue("2011-05-24T00:00:00", val);
@@ -798,7 +796,7 @@ void AddTSPEntry(Run &runInfo, std::string name, double val) {
  * @param b :: lattice length
  * @param c :: lattice length
  */
-void SetOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
+void setOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
                         double b, double c) {
   auto latt =
       Mantid::Kernel::make_unique<OrientedLattice>(a, b, c, 90., 90., 90.);
@@ -813,11 +811,11 @@ void SetOrientedLattice(Mantid::API::MatrixWorkspace_sptr ws, double a,
  * @param chi :: +X rotation angle (deg)
  * @param omega :: +Y rotation angle (deg)
  */
-void SetGoniometer(Mantid::API::MatrixWorkspace_sptr ws, double phi, double chi,
+void setGoniometer(Mantid::API::MatrixWorkspace_sptr ws, double phi, double chi,
                    double omega) {
-  AddTSPEntry(ws->mutableRun(), "phi", phi);
-  AddTSPEntry(ws->mutableRun(), "chi", chi);
-  AddTSPEntry(ws->mutableRun(), "omega", omega);
+  addTSPEntry(ws->mutableRun(), "phi", phi);
+  addTSPEntry(ws->mutableRun(), "chi", chi);
+  addTSPEntry(ws->mutableRun(), "omega", omega);
   Mantid::Geometry::Goniometer gm;
   gm.makeUniversalGoniometer();
   ws->mutableRun().setGoniometer(gm, true);
@@ -833,7 +831,7 @@ createProcessedWorkspaceWithCylComplexInstrument(size_t numPixels,
     rHist++;
 
   Mantid::API::MatrixWorkspace_sptr ws =
-      CreateGroupedWorkspace2DWithRingsAndBoxes(rHist, 10, 0.1);
+      createGroupedWorkspace2DWithRingsAndBoxes(rHist, 10, 0.1);
   auto pAxis0 = new NumericAxis(numBins);
   for (size_t i = 0; i < numBins; i++) {
     double dE = -1.0 + static_cast<double>(i) * 0.8;
@@ -846,9 +844,9 @@ createProcessedWorkspaceWithCylComplexInstrument(size_t numPixels,
         Mantid::Kernel::make_unique<OrientedLattice>(1, 1, 1, 90., 90., 90.);
     ws->mutableSample().setOrientedLattice(latt.release());
 
-    AddTSPEntry(ws->mutableRun(), "phi", 0);
-    AddTSPEntry(ws->mutableRun(), "chi", 0);
-    AddTSPEntry(ws->mutableRun(), "omega", 0);
+    addTSPEntry(ws->mutableRun(), "phi", 0);
+    addTSPEntry(ws->mutableRun(), "chi", 0);
+    addTSPEntry(ws->mutableRun(), "omega", 0);
     Mantid::Geometry::Goniometer gm;
     gm.makeUniversalGoniometer();
     ws->mutableRun().setGoniometer(gm, true);
@@ -876,7 +874,7 @@ createProcessedInelasticWS(const std::vector<double> &L2,
   size_t numPixels = L2.size();
 
   Mantid::API::MatrixWorkspace_sptr ws =
-      Create2DWorkspaceWithValues(uint64_t(numPixels), uint64_t(numBins), true,
+      create2DWorkspaceWithValues(uint64_t(numPixels), uint64_t(numBins), true,
                                   maskedWorkspaceIndices, 0, 1, 0.1);
 
   // detectors at L2, sample at 0 and source at -L2_min
@@ -928,9 +926,9 @@ createProcessedInelasticWS(const std::vector<double> &L2,
   ws->mutableRun().addProperty(new PropertyWithValue<double>("Ei", Ei), true);
   // these properties have to be different -> specific for processed ws, as time
   // now should be reconciled
-  AddTSPEntry(ws->mutableRun(), "phi", 0);
-  AddTSPEntry(ws->mutableRun(), "chi", 0);
-  AddTSPEntry(ws->mutableRun(), "omega", 0);
+  addTSPEntry(ws->mutableRun(), "phi", 0);
+  addTSPEntry(ws->mutableRun(), "chi", 0);
+  addTSPEntry(ws->mutableRun(), "omega", 0);
   Mantid::Geometry::Goniometer gm;
   gm.makeUniversalGoniometer();
   ws->mutableRun().setGoniometer(gm, true);
@@ -1008,7 +1006,7 @@ createEventWorkspace3(Mantid::DataObjects::EventWorkspace_const_sptr sourceWS,
   return outputWS;
 }
 
-RebinnedOutput_sptr CreateRebinnedOutputWorkspace() {
+RebinnedOutput_sptr createRebinnedOutputWorkspace() {
   RebinnedOutput_sptr outputWS =
       Mantid::DataObjects::RebinnedOutput_sptr(new RebinnedOutput());
   // outputWS->setName("rebinTest");
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/MuonProcess.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/MuonProcess.h
index 5c91eb4df1a33b50b216f09b5d3d63ab46712ef6..0824d987083f86036d0f90bf3265ef19f35745f6 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/MuonProcess.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/MuonProcess.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidAPI/DataProcessorAlgorithm.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidDataObjects/TableWorkspace.h"
 
 namespace Mantid {
diff --git a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SetupILLD33Reduction.h b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SetupILLD33Reduction.h
index 37c2a37147341aebe2e770b8969b03897661a790..10c37566be50c407f3d619025a07f0602f89f3e1 100644
--- a/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SetupILLD33Reduction.h
+++ b/Framework/WorkflowAlgorithms/inc/MantidWorkflowAlgorithms/SetupILLD33Reduction.h
@@ -5,6 +5,7 @@
 // Includes
 //----------------------------------------------------------------------
 #include "MantidAPI/Algorithm.h"
+#include "MantidAPI/DeprecatedAlgorithm.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidKernel/PropertyManager.h"
@@ -36,7 +37,8 @@ namespace WorkflowAlgorithms {
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 
-class DLLExport SetupILLD33Reduction : public API::Algorithm {
+class DLLExport SetupILLD33Reduction : public API::Algorithm,
+                                       public API::DeprecatedAlgorithm {
 public:
   /// Algorithm's name
   const std::string name() const override { return "SetupILLD33Reduction"; }
diff --git a/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp b/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
index 35f6c9b401115fb6e2d4feb5338707574dd456e2..d9ac8e049bc94bf0cdadcf77f5d2b470f2af4f8c 100644
--- a/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
+++ b/Framework/WorkflowAlgorithms/src/AlignAndFocusPowder.cpp
@@ -1,7 +1,5 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/AlignAndFocusPowder.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/PropertyManagerDataService.h"
diff --git a/Framework/WorkflowAlgorithms/src/ComputeSensitivity.cpp b/Framework/WorkflowAlgorithms/src/ComputeSensitivity.cpp
index 8b2111110b974a560f753c598444c139225004f5..029e32c04dd0fd62685b59a65a48fd3556e1d104 100644
--- a/Framework/WorkflowAlgorithms/src/ComputeSensitivity.cpp
+++ b/Framework/WorkflowAlgorithms/src/ComputeSensitivity.cpp
@@ -66,7 +66,7 @@ void ComputeSensitivity::exec() {
   // Set patch information so that the SANS sensitivity algorithm can
   // patch the sensitivity workspace
   const std::string patchWSName = getPropertyValue("PatchWorkspace");
-  if (patchWSName.size() > 0) {
+  if (!patchWSName.empty()) {
     IAlgorithm_sptr patchAlg = createChildAlgorithm("EQSANSPatchSensitivity");
     patchAlg->setPropertyValue("PatchWorkspace", patchWSName);
     if (!reductionManager->existsProperty("SensitivityPatchAlgorithm")) {
diff --git a/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp b/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp
index 7e05ad35f573b30a148baf169e939bc14f628df5..93801abbccf4470a48dfe2b240a44ff834cf137c 100644
--- a/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp
+++ b/Framework/WorkflowAlgorithms/src/ConvolutionFitSequential.cpp
@@ -109,6 +109,14 @@ void ConvolutionFitSequential::init() {
   declareProperty("MaxIterations", 500, boundedV,
                   "The maximum number of iterations permitted",
                   Direction::Input);
+  declareProperty("PeakRadius", 0,
+                  "A value of the peak radius the peak functions should use. A "
+                  "peak radius defines an interval on the x axis around the "
+                  "centre of the peak where its values are calculated. Values "
+                  "outside the interval are not calculated and assumed zeros."
+                  "Numerically the radius is a whole number of peak widths "
+                  "(FWHM) that fit into the interval on each side from the "
+                  "centre. The default value of 0 means the whole x axis.");
 
   declareProperty(make_unique<WorkspaceProperty<>>("OutputWorkspace", "",
                                                    Direction::Output),
@@ -131,6 +139,7 @@ void ConvolutionFitSequential::exec() {
   const bool convolve = getProperty("Convolve");
   const int maxIter = getProperty("MaxIterations");
   const std::string minimizer = getProperty("Minimizer");
+  const int peakRadius = getProperty("PeakRadius");
 
   // Inspect function to obtain fit Type and background
   const auto functionValues = findValuesFromFunction(function);
@@ -207,6 +216,7 @@ void ConvolutionFitSequential::exec() {
   plotPeaks->setProperty("MaxIterations", maxIter);
   plotPeaks->setProperty("Minimizer", minimizer);
   plotPeaks->setProperty("PassWSIndexToFunction", passIndex);
+  plotPeaks->setProperty("PeakRadius", peakRadius);
   plotPeaks->executeAsChildAlg();
   ITableWorkspace_sptr outputWs = plotPeaks->getProperty("OutputWorkspace");
 
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp
index a4e189b80a076db2e0281436a1bb2d85d4eafdfb..210550da3ac68846261b81aeae64b3fdef146ced 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction.cpp
@@ -1,5 +1,6 @@
 #include "MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidAPI/FileProperty.h"
@@ -117,7 +118,7 @@ void EQSANSDarkCurrentSubtraction::exec() {
 
     std::string darkWSOutputName =
         getPropertyValue("OutputDarkCurrentWorkspace");
-    if (!(darkWSOutputName.size() == 0))
+    if (!darkWSOutputName.empty())
       setProperty("OutputDarkCurrentWorkspace", darkWS);
     AnalysisDataService::Instance().addOrReplace(darkWSName, darkWS);
     reductionManager->declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp
index fc5db20edebca8719f7efd74f71bdbe43ddafc26..8f0293a96fc1d055974a8b12504a2593bd827b1a 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSDarkCurrentSubtraction2.cpp
@@ -1,9 +1,11 @@
 #include "MantidWorkflowAlgorithms/EQSANSDarkCurrentSubtraction2.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidAPI/AlgorithmProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidKernel/PropertyManagerDataService.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidGeometry/IDetector.h"
 #include "MantidKernel/PropertyManager.h"
@@ -132,7 +134,7 @@ void EQSANSDarkCurrentSubtraction2::exec() {
 
     std::string darkWSOutputName =
         getPropertyValue("OutputDarkCurrentWorkspace");
-    if (!(darkWSOutputName.size() == 0))
+    if (!darkWSOutputName.empty())
       setProperty("OutputDarkCurrentWorkspace", darkWS);
     AnalysisDataService::Instance().addOrReplace(darkWSName, darkWS);
     reductionManager->declareProperty(Kernel::make_unique<WorkspaceProperty<>>(
@@ -208,11 +210,11 @@ void EQSANSDarkCurrentSubtraction2::exec() {
   }
 
   progress.report("Subtracting dark current");
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   // Loop over all tubes and patch as necessary
   for (int i = 0; i < numberOfSpectra; i++) {
-    IDetector_const_sptr det = inputWS->getDetector(i);
     // If this detector is a monitor, skip to the next one
-    if (det->isMasked())
+    if (spectrumInfo.isMasked(i))
       continue;
 
     const MantidVec &YDarkValues = scaledDarkWS->readY(i);
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
index 59c6490ef04c5887870946ec662113bb2dd2eb2c..5536ce88c958231de79e1af270742925215dbc01 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSLoad.cpp
@@ -442,12 +442,12 @@ void EQSANSLoad::exec() {
   // live data reduction (when it's implemented...)
   const std::string fileName = getPropertyValue("Filename");
   EventWorkspace_sptr inputEventWS = getProperty("InputWorkspace");
-  if (fileName.size() == 0 && !inputEventWS) {
+  if (fileName.empty() && !inputEventWS) {
     g_log.error() << "EQSANSLoad input error: Either a valid file path or an "
                      "input workspace must be provided\n";
     throw std::runtime_error("EQSANSLoad input error: Either a valid file path "
                              "or an input workspace must be provided");
-  } else if (fileName.size() > 0 && inputEventWS) {
+  } else if (!fileName.empty() && inputEventWS) {
     g_log.error() << "EQSANSLoad input error: Either a valid file path or an "
                      "input workspace must be provided, but not both\n";
     throw std::runtime_error("EQSANSLoad input error: Either a valid file path "
@@ -607,7 +607,7 @@ void EQSANSLoad::exec() {
 
   // Process the config file
   bool use_config = getProperty("UseConfig");
-  if (use_config && config_file.size() > 0) {
+  if (use_config && !config_file.empty()) {
     // Special case to force reading the beam center from the config file
     // We're adding this to be compatible with the original EQSANS load
     // written in python
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSPatchSensitivity.cpp b/Framework/WorkflowAlgorithms/src/EQSANSPatchSensitivity.cpp
index 9c5c8a0da6e7d04159d97ba958722e3b6689e34b..0e06d4457a2dabc3757bf85b952f7525ac7296e5 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSPatchSensitivity.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSPatchSensitivity.cpp
@@ -1,10 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/EQSANSPatchSensitivity.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidGeometry/Instrument.h"
-#include "MantidGeometry/Instrument/ParameterMap.h"
 #include "MantidKernel/cow_ptr.h"
 
 namespace Mantid {
@@ -40,9 +37,9 @@ void EQSANSPatchSensitivity::exec() {
       inputWS->getInstrument()->getNumberParameter("number-of-y-pixels")[0]);
 
   const int numberOfSpectra = static_cast<int>(inputWS->getNumberHistograms());
-  // Need to get hold of the parameter map
-  Geometry::ParameterMap &pmap = inputWS->instrumentParameters();
 
+  const auto &spectrumInfo = patchWS->spectrumInfo();
+  const auto &inSpectrumInfo = inputWS->spectrumInfo();
   // Loop over all tubes and patch as necessary
   for (int i = 0; i < nx_pixels; i++) {
     std::vector<int> patched_ids;
@@ -65,21 +62,19 @@ void EQSANSPatchSensitivity::exec() {
         continue;
       }
 
-      IDetector_const_sptr det = patchWS->getDetector(iDet);
       // If this detector is a monitor, skip to the next one
-      if (det->isMonitor())
+      if (spectrumInfo.isMonitor(iDet))
         continue;
 
       const MantidVec &YValues = inputWS->readY(iDet);
       const MantidVec &YErrors = inputWS->readE(iDet);
 
       // If this detector is masked, skip to the next one
-      if (det->isMasked())
+      if (spectrumInfo.isMasked(i))
         patched_ids.push_back(iDet);
       else {
-        IDetector_const_sptr sensitivityDet = inputWS->getDetector(iDet);
-        if (!sensitivityDet->isMasked()) {
-          double yPosition = det->getPos().Y();
+        if (!inSpectrumInfo.isMasked(iDet)) {
+          double yPosition = spectrumInfo.position(iDet).Y();
           totalUnmasked += YErrors[0] * YErrors[0] * YValues[0];
           errorUnmasked += YErrors[0] * YErrors[0];
           nUnmasked++;
@@ -104,26 +99,23 @@ void EQSANSPatchSensitivity::exec() {
 
       // Apply patch
       progress(0.91, "Applying patch");
+      auto &spectrumInfo = inputWS->mutableSpectrumInfo();
       for (auto patched_id : patched_ids) {
-        const Geometry::ComponentID det =
-            inputWS->getDetector(patched_id)->getComponentID();
-        try {
-          if (det) {
-            MantidVec &YValues = inputWS->dataY(patched_id);
-            MantidVec &YErrors = inputWS->dataE(patched_id);
-            if (useRegression) {
-              YValues[0] = alpha + beta * det->getPos().Y();
-              YErrors[0] = error;
-            } else {
-              YValues[0] = average;
-              YErrors[0] = error;
-            }
-
-            pmap.addBool(det, "masked", false);
-          }
-        } catch (Kernel::Exception::NotFoundError &e) {
-          g_log.warning() << e.what() << " Found while setting mask bit\n";
+        if (!spectrumInfo.hasDetectors(patched_id)) {
+          g_log.warning() << "Spectrum " << patched_id
+                          << " has no detector, skipping (not clearing mask)\n";
+          continue;
         }
+        MantidVec &YValues = inputWS->dataY(patched_id);
+        MantidVec &YErrors = inputWS->dataE(patched_id);
+        if (useRegression) {
+          YValues[0] = alpha + beta * spectrumInfo.position(patched_id).Y();
+          YErrors[0] = error;
+        } else {
+          YValues[0] = average;
+          YErrors[0] = error;
+        }
+        spectrumInfo.setMasked(patched_id, false);
       }
     }
   }
diff --git a/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp b/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp
index 32d410265f42cfe2446488701acf2768ca7e3662..3645d5b40ac0cf2b3dd4d2e86b194295ecba11c7 100644
--- a/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp
+++ b/Framework/WorkflowAlgorithms/src/EQSANSQ2D.cpp
@@ -45,7 +45,7 @@ void EQSANSQ2D::exec() {
   // If the OutputWorkspace property was not given, use the
   // name of the input workspace as the base name for the output
   std::string outputWSName = getPropertyValue("OutputWorkspace");
-  if (outputWSName.size() == 0) {
+  if (outputWSName.empty()) {
     outputWSName = inputWS->getName();
   }
 
diff --git a/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp b/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp
index 812c1038fd67a9fed29c8d3355d9e48418c379f8..a0f760750bebbf7da06d0b1ca94908c8de101ba1 100644
--- a/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp
+++ b/Framework/WorkflowAlgorithms/src/HFIRDarkCurrentSubtraction.cpp
@@ -83,7 +83,7 @@ void HFIRDarkCurrentSubtraction::exec() {
     output_message += darkWSName + '\n';
   } else {
     // Load the dark current if we don't have it already
-    if (darkWSName.size() == 0) {
+    if (darkWSName.empty()) {
       darkWSName = "__dark_current_" + path.getBaseName();
       setPropertyValue("OutputDarkCurrentWorkspace", darkWSName);
     }
diff --git a/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp b/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp
index 72a933f66a6442994d58a94d517cea37721e15cf..bdcb05a755ae3a9d8711ea64ad2ae1711207dcd5 100644
--- a/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp
+++ b/Framework/WorkflowAlgorithms/src/HFIRLoad.cpp
@@ -5,6 +5,7 @@
 #include "Poco/NumberFormatter.h"
 #include "MantidKernel/BoundedValidator.h"
 #include "MantidAPI/AlgorithmProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidKernel/PropertyManagerDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/Run.h"
diff --git a/Framework/WorkflowAlgorithms/src/RefReduction.cpp b/Framework/WorkflowAlgorithms/src/RefReduction.cpp
index fa22f2acedfc6dae7976615db35eb4ae2a0e5322..acc38e5cb3ffbf679fa7b85c3d78d60fda7871a5 100644
--- a/Framework/WorkflowAlgorithms/src/RefReduction.cpp
+++ b/Framework/WorkflowAlgorithms/src/RefReduction.cpp
@@ -1,4 +1,5 @@
 #include "MantidWorkflowAlgorithms/RefReduction.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileFinder.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -477,7 +478,7 @@ IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun,
     // If we can't find a workspace, find a file to load
     std::string path = FileFinder::Instance().getFullPath(dataRun);
 
-    if (path.size() == 0 || !Poco::File(path).exists()) {
+    if (path.empty() || !Poco::File(path).exists()) {
       try {
         std::vector<std::string> paths =
             FileFinder::Instance().findRuns(instrument + dataRun);
@@ -487,7 +488,7 @@ IEventWorkspace_sptr RefReduction::loadData(const std::string dataRun,
       }
     }
 
-    if (path.size() == 0 || !Poco::File(path).exists()) {
+    if (path.empty() || !Poco::File(path).exists()) {
       try {
         std::vector<std::string> paths =
             FileFinder::Instance().findRuns(dataRun);
diff --git a/Framework/WorkflowAlgorithms/src/RefRoi.cpp b/Framework/WorkflowAlgorithms/src/RefRoi.cpp
index 9296392432a701df7b4e8ce95a0aff0af14872f6..83cf7adbeb221270c48b3856826d8a56042d9a52 100644
--- a/Framework/WorkflowAlgorithms/src/RefRoi.cpp
+++ b/Framework/WorkflowAlgorithms/src/RefRoi.cpp
@@ -1,11 +1,9 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/RefRoi.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/CommonBinsValidator.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidKernel/Unit.h"
 #include "MantidKernel/UnitFactory.h"
 #include "Poco/String.h"
 
diff --git a/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp b/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp
index 39d8cf8cb2a923b7df81535a2dd026cabd240dfb..bab3d659f82f87dc3aeaee33a133991b24079200 100644
--- a/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp
+++ b/Framework/WorkflowAlgorithms/src/SANSBeamFinder.cpp
@@ -1,9 +1,7 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/SANSBeamFinder.h"
 #include "MantidWorkflowAlgorithms/EQSANSInstrument.h"
 #include "MantidWorkflowAlgorithms/HFIRInstrument.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/AlgorithmProperty.h"
 #include "MantidKernel/PropertyManagerDataService.h"
diff --git a/Framework/WorkflowAlgorithms/src/SANSBeamFluxCorrection.cpp b/Framework/WorkflowAlgorithms/src/SANSBeamFluxCorrection.cpp
index aafb6853d4c06caeeb784c2a8db4fe219450eb83..a628da8580cd35bcd7dbc36c517c7dd1b21697e7 100644
--- a/Framework/WorkflowAlgorithms/src/SANSBeamFluxCorrection.cpp
+++ b/Framework/WorkflowAlgorithms/src/SANSBeamFluxCorrection.cpp
@@ -1,8 +1,6 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/SANSBeamFluxCorrection.h"
 #include "MantidAPI/AlgorithmProperty.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/PropertyManager.h"
diff --git a/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp b/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp
index 350d754009aa463fc7d667115201af7ded44f47c..148c1418c4b0b06e821a1fe7d327e5637d7363f1 100644
--- a/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp
+++ b/Framework/WorkflowAlgorithms/src/SANSSensitivityCorrection.cpp
@@ -251,7 +251,7 @@ void SANSSensitivityCorrection::exec() {
             darkAlg->execute();
             if (darkAlg->existsProperty("OutputMessage"))
               dark_result = darkAlg->getPropertyValue("OutputMessage");
-          } else if (darkCurrentFile.size() > 0) {
+          } else if (!darkCurrentFile.empty()) {
             darkAlg->setProperty("Filename", darkCurrentFile);
             darkAlg->setProperty("PersistentCorrection", false);
             darkAlg->execute();
@@ -260,7 +260,7 @@ void SANSSensitivityCorrection::exec() {
             else
               dark_result = "   Dark current subtracted\n";
           }
-        } else if (darkCurrentFile.size() > 0) {
+        } else if (!darkCurrentFile.empty()) {
           // We need to subtract the dark current for the flood field but no
           // dark
           // current subtraction was set for the sample! Use the default dark
@@ -356,7 +356,7 @@ void SANSSensitivityCorrection::exec() {
     }
     std::string floodWSOutputName =
         getPropertyValue("OutputSensitivityWorkspace");
-    if (floodWSOutputName.size() == 0) {
+    if (floodWSOutputName.empty()) {
       setPropertyValue("OutputSensitivityWorkspace", floodWSName);
       AnalysisDataService::Instance().addOrReplace(floodWSName, floodWS);
       reductionManager->declareProperty(
diff --git a/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp b/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp
index 5d1452e6baba2bb7c09a6e7d66da2c8bb9c10d37..f6bd3f6a6204b67661b51bbc52bba60d731fc0ab 100644
--- a/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp
+++ b/Framework/WorkflowAlgorithms/src/SANSSolidAngleCorrection.cpp
@@ -1,17 +1,13 @@
-//----------------------------------------------------------------------
-// Includes
-//----------------------------------------------------------------------
 #include "MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h"
 #include "MantidAPI/AlgorithmProperty.h"
 #include "MantidAPI/HistogramValidator.h"
 #include "MantidKernel/PropertyManagerDataService.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 #include "MantidAPI/WorkspaceUnitValidator.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidDataObjects/EventList.h"
 #include "MantidDataObjects/TableWorkspace.h"
-#include "MantidGeometry/IDetector.h"
-#include "MantidGeometry/Instrument.h"
 #include "MantidKernel/CompositeValidator.h"
 #include "MantidKernel/PropertyManager.h"
 
@@ -28,16 +24,11 @@ DECLARE_ALGORITHM(SANSSolidAngleCorrection)
 
 /// Returns the angle between the sample-to-pixel vector and its
 /// projection on the X-Z plane.
-static double getYTubeAngle(const IDetector &det,
-                            const MatrixWorkspace &workspace) {
-
-  // Get the sample position
-  Geometry::IComponent_const_sptr sample =
-      workspace.getInstrument()->getSample();
-  const V3D samplePos = sample->getPos();
+static double getYTubeAngle(const SpectrumInfo &spectrumInfo, size_t i) {
+  const V3D samplePos = spectrumInfo.samplePosition();
 
   // Get the vector from the sample position to the detector pixel
-  V3D sampleDetVec = det.getPos() - samplePos;
+  V3D sampleDetVec = spectrumInfo.position(i) - samplePos;
 
   // Get the projection of that vector on the X-Z plane
   V3D inPlane = V3D(sampleDetVec);
@@ -110,29 +101,20 @@ void SANSSolidAngleCorrection::exec() {
   // Number of X bins
   const int xLength = static_cast<int>(inputWS->readY(0).size());
 
+  const auto &spectrumInfo = inputWS->spectrumInfo();
   PARALLEL_FOR_IF(Kernel::threadSafe(*outputWS, *inputWS))
   for (int i = 0; i < numHists; ++i) {
     PARALLEL_START_INTERUPT_REGION
     outputWS->dataX(i) = inputWS->readX(i);
 
-    IDetector_const_sptr det;
-    try {
-      det = inputWS->getDetector(i);
-    } catch (Exception::NotFoundError &) {
+    if (!spectrumInfo.hasDetectors(i)) {
       g_log.warning() << "Workspace index " << i
                       << " has no detector assigned to it - discarding\n";
-      // Catch if no detector. Next line tests whether this happened - test
-      // placed
-      // outside here because Mac Intel compiler doesn't like 'continue' in a
-      // catch
-      // in an openmp block.
-    }
-    // If no detector found, skip onto the next spectrum
-    if (!det)
       continue;
+    }
 
     // Skip if we have a monitor or if the detector is masked.
-    if (det->isMonitor() || det->isMasked())
+    if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
       continue;
 
     const MantidVec &YIn = inputWS->readY(i);
@@ -145,11 +127,11 @@ void SANSSolidAngleCorrection::exec() {
     const bool is_tube = getProperty("DetectorTubes");
     const bool is_wing = getProperty("DetectorWing");
 
-    const double tanTheta = tan(inputWS->detectorTwoTheta(*det));
+    const double tanTheta = tan(spectrumInfo.twoTheta(i));
     const double theta_term = sqrt(tanTheta * tanTheta + 1.0);
     double corr;
     if (is_tube || is_wing) {
-      const double tanAlpha = tan(getYTubeAngle(*det, *inputWS));
+      const double tanAlpha = tan(getYTubeAngle(spectrumInfo, i));
       const double alpha_term = sqrt(tanAlpha * tanAlpha + 1.0);
       if (is_tube)
         corr = alpha_term * theta_term * theta_term;
@@ -188,35 +170,28 @@ void SANSSolidAngleCorrection::execEvent() {
   Progress progress(this, 0.0, 1.0, numberOfSpectra);
   progress.report("Solid Angle Correction");
 
+  const auto &spectrumInfo = outputEventWS->spectrumInfo();
   PARALLEL_FOR_IF(Kernel::threadSafe(*outputEventWS))
   for (int i = 0; i < numberOfSpectra; i++) {
     PARALLEL_START_INTERUPT_REGION
-    IDetector_const_sptr det;
-    try {
-      det = outputEventWS->getDetector(i);
-    } catch (Exception::NotFoundError &) {
+
+    if (!spectrumInfo.hasDetectors(i)) {
       g_log.warning() << "Workspace index " << i
                       << " has no detector assigned to it - discarding\n";
-      // Catch if no detector. Next line tests whether this happened - test
-      // placed
-      // outside here because Mac Intel compiler doesn't like 'continue' in a
-      // catch
-      // in an openmp block.
-    }
-    if (!det)
       continue;
+    }
 
     // Skip if we have a monitor or if the detector is masked.
-    if (det->isMonitor() || det->isMasked())
+    if (spectrumInfo.isMonitor(i) || spectrumInfo.isMasked(i))
       continue;
 
     // Compute solid angle correction factor
     const bool is_tube = getProperty("DetectorTubes");
-    const double tanTheta = tan(outputEventWS->detectorTwoTheta(*det));
+    const double tanTheta = tan(spectrumInfo.twoTheta(i));
     const double theta_term = sqrt(tanTheta * tanTheta + 1.0);
     double corr;
     if (is_tube) {
-      const double tanAlpha = tan(getYTubeAngle(*det, *inputWS));
+      const double tanAlpha = tan(getYTubeAngle(spectrumInfo, i));
       const double alpha_term = sqrt(tanAlpha * tanAlpha + 1.0);
       corr = alpha_term * theta_term * theta_term;
     } else {
diff --git a/Framework/WorkflowAlgorithms/src/SetupEQSANSReduction.cpp b/Framework/WorkflowAlgorithms/src/SetupEQSANSReduction.cpp
index 736a7be6042ccd0293c7ed63b55962424b4e35ad..f221e3d744c04eb29b1f1b038adae7edec8f9a47 100644
--- a/Framework/WorkflowAlgorithms/src/SetupEQSANSReduction.cpp
+++ b/Framework/WorkflowAlgorithms/src/SetupEQSANSReduction.cpp
@@ -580,7 +580,7 @@ void SetupEQSANSReduction::init() {
 void SetupEQSANSReduction::exec() {
   // Reduction property manager
   const std::string reductionManagerName = getProperty("ReductionProperties");
-  if (reductionManagerName.size() == 0) {
+  if (reductionManagerName.empty()) {
     g_log.error() << "ERROR: Reduction Property Manager name is empty\n";
     return;
   }
@@ -619,7 +619,7 @@ void SetupEQSANSReduction::exec() {
     normAlg->setProperty("NormaliseToBeam", false);
   } else if (boost::contains(normalization, "Monitor")) {
     loadMonitors = true;
-    if (monitorRefFile.size() == 0) {
+    if (monitorRefFile.empty()) {
       g_log.error() << "ERROR: normalize-to-monitor was turned ON but no "
                        "reference data was selected\n";
     }
@@ -671,7 +671,7 @@ void SetupEQSANSReduction::exec() {
 
   // Store dark current algorithm
   const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");
-  if (darkCurrentFile.size() > 0) {
+  if (!darkCurrentFile.empty()) {
     IAlgorithm_sptr darkAlg =
         createChildAlgorithm("EQSANSDarkCurrentSubtraction");
     darkAlg->setProperty("Filename", darkCurrentFile);
@@ -722,7 +722,7 @@ void SetupEQSANSReduction::exec() {
     if (!boost::iequals(centerMethod, "DirectBeam"))
       useDirectBeamMethod = false;
     const std::string beamCenterFile = getProperty("BeamCenterFile");
-    if (beamCenterFile.size() > 0) {
+    if (!beamCenterFile.empty()) {
       const double beamRadius = getProperty("BeamRadius");
 
       IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
@@ -853,7 +853,7 @@ void SetupEQSANSReduction::setupSensitivity(
   const std::string reductionManagerName = getProperty("ReductionProperties");
 
   const std::string sensitivityFile = getPropertyValue("SensitivityFile");
-  if (sensitivityFile.size() > 0) {
+  if (!sensitivityFile.empty()) {
     const bool useSampleDC = getProperty("UseDefaultDC");
     const std::string sensitivityDarkCurrentFile =
         getPropertyValue("SensitivityDarkCurrentFile");
@@ -887,7 +887,7 @@ void SetupEQSANSReduction::setupSensitivity(
       const double sensitivityBeamRadius =
           getProperty("SensitivityBeamCenterRadius");
       bool useDirectBeam = boost::iequals(centerMethod, "DirectBeam");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeam);
@@ -975,7 +975,7 @@ void SetupEQSANSReduction::setupTransmission(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("TransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
@@ -1004,7 +1004,7 @@ void SetupEQSANSReduction::setupBackground(
   const std::string reductionManagerName = getProperty("ReductionProperties");
   // Background
   const std::string backgroundFile = getPropertyValue("BackgroundFiles");
-  if (backgroundFile.size() > 0)
+  if (!backgroundFile.empty())
     reductionManager->declareProperty(
         Kernel::make_unique<PropertyWithValue<std::string>>("BackgroundFiles",
                                                             backgroundFile));
@@ -1066,7 +1066,7 @@ void SetupEQSANSReduction::setupBackground(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("BckTransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
diff --git a/Framework/WorkflowAlgorithms/src/SetupHFIRReduction.cpp b/Framework/WorkflowAlgorithms/src/SetupHFIRReduction.cpp
index 22352ea734293426161bf6389cab1f4b19a979c3..87ad6e0318f1cd0cc1067b8e3899f6b6c7564e63 100644
--- a/Framework/WorkflowAlgorithms/src/SetupHFIRReduction.cpp
+++ b/Framework/WorkflowAlgorithms/src/SetupHFIRReduction.cpp
@@ -629,7 +629,7 @@ void SetupHFIRReduction::init() {
 void SetupHFIRReduction::exec() {
   // Reduction property manager
   const std::string reductionManagerName = getProperty("ReductionProperties");
-  if (reductionManagerName.size() == 0) {
+  if (reductionManagerName.empty()) {
     g_log.error() << "ERROR: Reduction Property Manager name is empty\n";
     return;
   }
@@ -691,7 +691,7 @@ void SetupHFIRReduction::exec() {
     if (!boost::iequals(centerMethod, "DirectBeam"))
       useDirectBeamMethod = false;
     const std::string beamCenterFile = getProperty("BeamCenterFile");
-    if (beamCenterFile.size() > 0) {
+    if (!beamCenterFile.empty()) {
       const double beamRadius = getProperty("BeamRadius");
 
       IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
@@ -713,7 +713,7 @@ void SetupHFIRReduction::exec() {
 
   // Store dark current algorithm
   const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");
-  if (darkCurrentFile.size() > 0) {
+  if (!darkCurrentFile.empty()) {
     IAlgorithm_sptr darkAlg =
         createChildAlgorithm("HFIRDarkCurrentSubtraction");
     darkAlg->setProperty("Filename", darkCurrentFile);
@@ -890,7 +890,7 @@ void SetupHFIRReduction::setupSensitivity(
   const std::string reductionManagerName = getProperty("ReductionProperties");
 
   const std::string sensitivityFile = getPropertyValue("SensitivityFile");
-  if (sensitivityFile.size() > 0) {
+  if (!sensitivityFile.empty()) {
     const bool useSampleDC = getProperty("UseDefaultDC");
     const std::string sensitivityDarkCurrentFile =
         getPropertyValue("SensitivityDarkCurrentFile");
@@ -945,7 +945,7 @@ void SetupHFIRReduction::setupSensitivity(
       const double sensitivityBeamRadius =
           getProperty("SensitivityBeamCenterRadius");
       bool useDirectBeam = boost::iequals(centerMethod, "DirectBeam");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeam);
@@ -979,7 +979,7 @@ void SetupHFIRReduction::setupBackground(
   const std::string reductionManagerName = getProperty("ReductionProperties");
   // Background
   const std::string backgroundFile = getPropertyValue("BackgroundFiles");
-  if (backgroundFile.size() > 0)
+  if (!backgroundFile.empty())
     reductionManager->declareProperty(
         Kernel::make_unique<PropertyWithValue<std::string>>("BackgroundFiles",
                                                             backgroundFile));
@@ -1037,7 +1037,7 @@ void SetupHFIRReduction::setupBackground(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("BckTransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
@@ -1150,7 +1150,7 @@ void SetupHFIRReduction::setupTransmission(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("TransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
diff --git a/Framework/WorkflowAlgorithms/src/SetupILLD33Reduction.cpp b/Framework/WorkflowAlgorithms/src/SetupILLD33Reduction.cpp
index 3a4297a17addf6045899a4f9308132194d4a28eb..45f57173cdcc0f17969997a63037efad89ab061e 100644
--- a/Framework/WorkflowAlgorithms/src/SetupILLD33Reduction.cpp
+++ b/Framework/WorkflowAlgorithms/src/SetupILLD33Reduction.cpp
@@ -483,7 +483,7 @@ void SetupILLD33Reduction::init() {
 void SetupILLD33Reduction::exec() {
   // Reduction property manager
   const std::string reductionManagerName = getProperty("ReductionProperties");
-  if (reductionManagerName.size() == 0) {
+  if (reductionManagerName.empty()) {
     g_log.error() << "ERROR: Reduction Property Manager name is empty\n";
     return;
   }
@@ -532,7 +532,7 @@ void SetupILLD33Reduction::exec() {
 
   // Store dark current algorithm
   const std::string darkCurrentFile = getPropertyValue("DarkCurrentFile");
-  if (darkCurrentFile.size() > 0) {
+  if (!darkCurrentFile.empty()) {
     IAlgorithm_sptr darkAlg =
         createChildAlgorithm("EQSANSDarkCurrentSubtraction");
     darkAlg->setProperty("Filename", darkCurrentFile);
@@ -583,7 +583,7 @@ void SetupILLD33Reduction::exec() {
     if (!boost::iequals(centerMethod, "DirectBeam"))
       useDirectBeamMethod = false;
     const std::string beamCenterFile = getProperty("BeamCenterFile");
-    if (beamCenterFile.size() > 0) {
+    if (!beamCenterFile.empty()) {
       const double beamRadius = getProperty("BeamRadius");
 
       IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
@@ -703,7 +703,7 @@ void SetupILLD33Reduction::setupSensitivity(
   const std::string reductionManagerName = getProperty("ReductionProperties");
 
   const std::string sensitivityFile = getPropertyValue("SensitivityFile");
-  if (sensitivityFile.size() > 0) {
+  if (!sensitivityFile.empty()) {
     const bool useSampleDC = getProperty("UseDefaultDC");
     const std::string sensitivityDarkCurrentFile =
         getPropertyValue("SensitivityDarkCurrentFile");
@@ -737,7 +737,7 @@ void SetupILLD33Reduction::setupSensitivity(
       const double sensitivityBeamRadius =
           getProperty("SensitivityBeamCenterRadius");
       bool useDirectBeam = boost::iequals(centerMethod, "DirectBeam");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", useDirectBeam);
@@ -824,7 +824,7 @@ void SetupILLD33Reduction::setupTransmission(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("TransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
@@ -854,7 +854,7 @@ void SetupILLD33Reduction::setupBackground(
   const std::string reductionManagerName = getProperty("ReductionProperties");
   // Background
   const std::string backgroundFile = getPropertyValue("BackgroundFiles");
-  if (backgroundFile.size() > 0)
+  if (!backgroundFile.empty())
     reductionManager->declareProperty(
         Kernel::make_unique<PropertyWithValue<std::string>>("BackgroundFiles",
                                                             backgroundFile));
@@ -915,7 +915,7 @@ void SetupILLD33Reduction::setupBackground(
     } else if (boost::iequals(centerMethod, "DirectBeam")) {
       const std::string beamCenterFile =
           getProperty("BckTransmissionBeamCenterFile");
-      if (beamCenterFile.size() > 0) {
+      if (!beamCenterFile.empty()) {
         IAlgorithm_sptr ctrAlg = createChildAlgorithm("SANSBeamFinder");
         ctrAlg->setProperty("Filename", beamCenterFile);
         ctrAlg->setProperty("UseDirectBeamMethod", true);
diff --git a/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h b/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h
index 3e159495a85da72fc33366e30a8ce05328211a0e..98a519c364c9fc6b9dc58b6add538eb22e6d946e 100644
--- a/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h
+++ b/Framework/WorkflowAlgorithms/test/ConvolutionFitSequentialTest.h
@@ -6,6 +6,7 @@
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include "MantidWorkflowAlgorithms/ConvolutionFitSequential.h"
 
diff --git a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
index 5cfa3e9ddbba848364b32dfa41a6409e83453ba4..974f8c18ae512048c4a4e7c981b1e408db4941f5 100644
--- a/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
+++ b/Framework/WorkflowAlgorithms/test/IMuonAsymmetryCalculatorTest.h
@@ -620,7 +620,7 @@ private:
   * X values are 1 2 3 for all the histograms.
   */
   MatrixWorkspace_sptr createWorkspace(double delta = 0.0) {
-    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(3, 3);
+    MatrixWorkspace_sptr ws = WorkspaceCreationHelper::create2DWorkspace(3, 3);
 
     for (size_t i = 0; i < ws->getNumberHistograms(); i++) {
       for (size_t j = 0; j < ws->blocksize(); j++) {
diff --git a/Framework/WorkflowAlgorithms/test/LoadEventAndCompressTest.h b/Framework/WorkflowAlgorithms/test/LoadEventAndCompressTest.h
index a1fc310b9320d0b32d18df80f14eed60b1d7f28d..237b86f7cb1f1d1bdde7c658fb611bcde53d9e12 100644
--- a/Framework/WorkflowAlgorithms/test/LoadEventAndCompressTest.h
+++ b/Framework/WorkflowAlgorithms/test/LoadEventAndCompressTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidDataObjects/EventWorkspace.h"
 #include "MantidWorkflowAlgorithms/LoadEventAndCompress.h"
diff --git a/Framework/WorkflowAlgorithms/test/ProcessIndirectFitParametersTest.h b/Framework/WorkflowAlgorithms/test/ProcessIndirectFitParametersTest.h
index 8f0ff2aa831e4cb4b76c649b51aaa0c72db417e6..37812f317d4e7865e1a011063606d1283c45869b 100644
--- a/Framework/WorkflowAlgorithms/test/ProcessIndirectFitParametersTest.h
+++ b/Framework/WorkflowAlgorithms/test/ProcessIndirectFitParametersTest.h
@@ -4,6 +4,7 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidWorkflowAlgorithms/ProcessIndirectFitParameters.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
diff --git a/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h b/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
index 587e563dad215035a2d243b91c67d0ca0c6e9f6e..c5fc3785e3f213f545f0f3db290d0dc39d1af7d9 100644
--- a/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
+++ b/Framework/WorkflowAlgorithms/test/SANSSolidAngleCorrectionTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidWorkflowAlgorithms/SANSSolidAngleCorrection.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidKernel/Unit.h"
 #include "MantidDataHandling/LoadSpice2D.h"
diff --git a/Framework/WorkflowAlgorithms/test/StepScanTest.h b/Framework/WorkflowAlgorithms/test/StepScanTest.h
index 62c431cade068d46b0ce938c37b799eb5d4636b2..9d84dffaff703b91740dd7b3cc517a4c692a8027 100644
--- a/Framework/WorkflowAlgorithms/test/StepScanTest.h
+++ b/Framework/WorkflowAlgorithms/test/StepScanTest.h
@@ -33,7 +33,7 @@ public:
     dummy.version();
     // End of dummy code
 
-    inputWS = WorkspaceCreationHelper::CreateEventWorkspace2(3, 1);
+    inputWS = WorkspaceCreationHelper::createEventWorkspace2(3, 1);
     inputWS->getAxis(0)->unit() = UnitFactory::Instance().create("TOF");
     auto scan_index = new TimeSeriesProperty<int>("scan_index");
     scan_index->addValue("2010-01-01T00:00:00", 0);
diff --git a/MantidPlot/src/ApplicationWindow.cpp b/MantidPlot/src/ApplicationWindow.cpp
index 8e469c1f9ac39bbbaa666d475f6e2fc9cff1a9b3..1e8d62d953e0b67de38816039ebf6ddd84ffff51 100644
--- a/MantidPlot/src/ApplicationWindow.cpp
+++ b/MantidPlot/src/ApplicationWindow.cpp
@@ -133,6 +133,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <cassert>
+#include <iostream>
 
 #include <qwt_scale_engine.h>
 #include <QColorGroup>
@@ -188,7 +189,6 @@
 #include "Mantid/ManageInterfaceCategories.h"
 #include "Mantid/FirstTimeSetup.h"
 
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/InterfaceManager.h"
 #include "MantidQtAPI/UserSubWindow.h"
 #include "MantidQtAPI/AlgorithmInputHistory.h"
@@ -201,6 +201,7 @@
 #include "MantidQtMantidWidgets/FitPropertyBrowser.h"
 #include "MantidQtMantidWidgets/MessageDisplay.h"
 #include "MantidQtMantidWidgets/MuonFitPropertyBrowser.h"
+#include "MantidQtMantidWidgets/TrackedAction.h"
 
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
@@ -3629,7 +3630,7 @@ MdiSubWindow *ApplicationWindow::window(const QString &name) {
 }
 
 Table *ApplicationWindow::table(const QString &name) {
-  int pos = name.lastIndexOf("_");
+  int pos = name.indexOf("_");
   QString caption = name.left(pos);
 
   Folder *f = projectFolder();
@@ -5939,13 +5940,11 @@ std::string ApplicationWindow::windowGeometryInfo(MdiSubWindow *w) {
   }
 
   tsv << x << y;
-  if (w->status() != MdiSubWindow::Minimized)
-    tsv << w->width() << w->height();
-  else
-    tsv << w->minRestoreSize().width() << w->minRestoreSize().height()
-        << "minimized";
+  tsv << w->width() << w->height();
 
-  if (hidden(w))
+  if (w->status() == MdiSubWindow::Minimized)
+    tsv << "minimized";
+  else if (hidden(w))
     tsv << "hidden";
   else if (w == activeWindow())
     tsv << "active";
@@ -6039,7 +6038,7 @@ void ApplicationWindow::savetoNexusFile() {
   QString selectedFilter;
   QString fileDir =
       MantidQt::API::AlgorithmInputHistory::Instance().getPreviousDirectory();
-  QString fileName = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString fileName = QFileDialog::getSaveFileName(
       this, tr("Save File As"), fileDir, filter, &selectedFilter);
   if (!fileName.isEmpty()) {
     std::string wsName;
@@ -6087,6 +6086,9 @@ void ApplicationWindow::loadDataFileByName(QString fn) {
   if (fnInfo.suffix() == "py") {
     // We have a python file, just load it into script window
     loadScript(fn, true);
+  } else if (fnInfo.suffix() == "mantid") {
+    // We have a mantid project file, pass on to project loading
+    open(fn);
   } else if (mantidUI) {
     // Run Load algorithm on file
     QHash<QString, QString> params;
@@ -6102,8 +6104,8 @@ void ApplicationWindow::saveProjectAs(const QString &fileName, bool compress) {
     filter += tr("Compressed MantidPlot project") + " (*.mantid.gz)";
 
     QString selectedFilter;
-    fn = MantidQt::API::FileDialogHandler::getSaveFileName(
-        this, tr("Save Project As"), workingDir, filter, &selectedFilter);
+    fn = QFileDialog::getSaveFileName(this, tr("Save Project As"), workingDir,
+                                      filter, &selectedFilter);
     if (selectedFilter.contains(".gz"))
       compress = true;
   }
@@ -6477,10 +6479,10 @@ void ApplicationWindow::exportASCII(const QString &tableName,
     return;
 
   QString selectedFilter;
-  QString fname = MantidQt::API::FileDialogHandler::getSaveFileName(
-      this, tr("Choose a filename to save under"),
-      asciiDirPath + "/" + w->objectName(), "*.txt;;*.dat;;*.DAT",
-      &selectedFilter);
+  QString fname =
+      QFileDialog::getSaveFileName(this, tr("Choose a filename to save under"),
+                                   asciiDirPath + "/" + w->objectName(),
+                                   "*.txt;;*.dat;;*.DAT", &selectedFilter);
   if (!fname.isEmpty()) {
     QFileInfo fi(fname);
     QString baseName = fi.fileName();
@@ -7614,7 +7616,7 @@ void ApplicationWindow::exportPDF() {
     return;
   }
 
-  QString fname = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString fname = QFileDialog::getSaveFileName(
       this, tr("Choose a filename to save under"), workingDir, "*.pdf");
   if (!fname.isEmpty()) {
     QFileInfo fi(fname);
@@ -11470,126 +11472,133 @@ void ApplicationWindow::setPlot3DOptions() {
 }
 
 void ApplicationWindow::createActions() {
-  actionCustomActionDialog = new QAction(tr("Manage Custom Menus..."), this);
+  actionCustomActionDialog = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Manage Custom Menus..."), this);
   connect(actionCustomActionDialog, SIGNAL(triggered()), this,
           SLOT(showCustomActionDialog()));
 
-  actionManageDirs = new QAction(QIcon(getQPixmap("managefolders_xpm")),
-                                 tr("Manage User Directories"), this);
+  actionManageDirs = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("managefolders_xpm")), tr("Manage User Directories"),
+      this);
   connect(actionManageDirs, SIGNAL(triggered()), this,
           SLOT(showUserDirectoryDialog()));
 
-  actionFirstTimeSetup = new QAction(tr("First Time Setup"), this);
+  actionFirstTimeSetup =
+      new MantidQt::MantidWidgets::TrackedAction(tr("First Time Setup"), this);
   connect(actionFirstTimeSetup, SIGNAL(triggered()), this,
           SLOT(showFirstTimeSetup()));
 
-  actionNewProject =
-      new QAction(QIcon(":/NewProject16x16.png"), tr("New &Project"), this);
+  actionNewProject = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/NewProject16x16.png"), tr("New &Project"), this);
   actionNewProject->setShortcut(tr("Ctrl+N"));
   connect(actionNewProject, SIGNAL(triggered()), this, SLOT(newProject()));
 
-  actionSaveProject =
-      new QAction(QIcon(":/SaveProject16x16.png"), tr("Save &Project"), this);
+  actionSaveProject = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/SaveProject16x16.png"), tr("Save &Project"), this);
   actionSaveProject->setShortcut(tr("Ctrl+Shift+S"));
   connect(actionSaveProject, SIGNAL(triggered()), this, SLOT(saveProject()));
 
-  actionSaveFile = new QAction(QIcon(getQPixmap("filesave_nexus_xpm")),
-                               tr("Save Nexus &File"), this);
+  actionSaveFile = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("filesave_nexus_xpm")), tr("Save Nexus &File"), this);
   actionSaveFile->setShortcut(tr("Ctrl+S"));
   connect(actionSaveFile, SIGNAL(triggered()), this, SLOT(savetoNexusFile()));
 
-  actionNewGraph =
-      new QAction(QIcon(getQPixmap("new_graph_xpm")), tr("New &Graph"), this);
+  actionNewGraph = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("new_graph_xpm")), tr("New &Graph"), this);
   actionNewGraph->setShortcut(tr("Ctrl+G"));
   connect(actionNewGraph, SIGNAL(triggered()), this, SLOT(newGraph()));
 
-  actionNewNote =
-      new QAction(QIcon(getQPixmap("new_note_xpm")), tr("New &Note"), this);
+  actionNewNote = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("new_note_xpm")), tr("New &Note"), this);
   connect(actionNewNote, SIGNAL(triggered()), this, SLOT(newNote()));
 
-  actionNewTable =
-      new QAction(QIcon(getQPixmap("table_xpm")), tr("New &Table"), this);
+  actionNewTable = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("table_xpm")), tr("New &Table"), this);
   actionNewTable->setShortcut(tr("Ctrl+T"));
   connect(actionNewTable, SIGNAL(triggered()), this, SLOT(newTable()));
 
-  actionNewTiledWindow = new QAction(QIcon(getQPixmap("tiledwindow_xpm")),
-                                     tr("New Tiled &Window"), this);
+  actionNewTiledWindow = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("tiledwindow_xpm")), tr("New Tiled &Window"), this);
   actionNewTiledWindow->setShortcut(tr("Ctrl+Shift+T"));
   connect(actionNewTiledWindow, SIGNAL(triggered()), this,
           SLOT(newTiledWindow()));
 
-  actionNewMatrix =
-      new QAction(QIcon(getQPixmap("new_matrix_xpm")), tr("New &Matrix"), this);
+  actionNewMatrix = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("new_matrix_xpm")), tr("New &Matrix"), this);
   actionNewMatrix->setShortcut(tr("Ctrl+M"));
   connect(actionNewMatrix, SIGNAL(triggered()), this, SLOT(newMatrix()));
 
-  actionNewFunctionPlot = new QAction(QIcon(getQPixmap("newF_xpm")),
-                                      tr("New &Function Plot"), this);
+  actionNewFunctionPlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("newF_xpm")), tr("New &Function Plot"), this);
   connect(actionNewFunctionPlot, SIGNAL(triggered()), this,
           SLOT(functionDialog()));
 
-  actionNewSurfacePlot = new QAction(QIcon(getQPixmap("newFxy_xpm")),
-                                     tr("New 3D &Surface Plot"), this);
+  actionNewSurfacePlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("newFxy_xpm")), tr("New 3D &Surface Plot"), this);
   actionNewSurfacePlot->setShortcut(tr("Ctrl+ALT+Z"));
   connect(actionNewSurfacePlot, SIGNAL(triggered()), this,
           SLOT(newSurfacePlot()));
 
-  actionOpenProj =
-      new QAction(QIcon(":/LoadProject16x16.png"), tr("&Project"), this);
+  actionOpenProj = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/LoadProject16x16.png"), tr("&Project"), this);
   actionOpenProj->setShortcut(tr("Ctrl+Shift+O"));
   connect(actionOpenProj, SIGNAL(triggered()), this, SLOT(open()));
 
-  actionLoadFile =
-      new QAction(QIcon(":/Open-icon16x16.png"), tr("Data File"), this);
+  actionLoadFile = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/Open-icon16x16.png"), tr("Data File"), this);
   actionLoadFile->setShortcut(tr("Ctrl+Shift+F"));
   connect(actionLoadFile, SIGNAL(triggered()), this, SLOT(loadDataFile()));
 
-  actionLoadImage = new QAction(tr("Open Image &File"), this);
+  actionLoadImage =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Open Image &File"), this);
   actionLoadImage->setShortcut(tr("Ctrl+I"));
   connect(actionLoadImage, SIGNAL(triggered()), this, SLOT(loadImage()));
 
-  actionScriptRepo = new QAction(tr("Script Repositor&y"), this);
+  actionScriptRepo = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Script Repositor&y"), this);
   connect(actionScriptRepo, SIGNAL(triggered()), this, SLOT(loadScriptRepo()));
 
-  actionImportImage = new QAction(tr("Import I&mage..."), this);
+  actionImportImage =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Import I&mage..."), this);
   connect(actionImportImage, SIGNAL(triggered()), this, SLOT(importImage()));
 
-  actionSaveProjectAs = new QAction(QIcon(":/SaveProject16x16.png"),
-                                    tr("Save Project &As..."), this);
+  actionSaveProjectAs = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/SaveProject16x16.png"), tr("Save Project &As..."), this);
   connect(actionSaveProjectAs, SIGNAL(triggered()), this,
           SLOT(saveProjectAs()));
   actionSaveProjectAs->setEnabled(false);
 
-  actionSaveNote = new QAction(tr("Save Note As..."), this);
+  actionSaveNote =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Save Note As..."), this);
   connect(actionSaveNote, SIGNAL(triggered()), this, SLOT(saveNoteAs()));
 
-  actionLoad = new QAction(QIcon(getQPixmap("import_xpm")),
-                           tr("&Import ASCII..."), this);
+  actionLoad = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("import_xpm")), tr("&Import ASCII..."), this);
   connect(actionLoad, SIGNAL(triggered()), this, SLOT(importASCII()));
 
-  actionCopyWindow =
-      new QAction(QIcon(getQPixmap("duplicate_xpm")), tr("&Duplicate"), this);
+  actionCopyWindow = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("duplicate_xpm")), tr("&Duplicate"), this);
   connect(actionCopyWindow, SIGNAL(triggered()), this, SLOT(clone()));
 
-  actionCutSelection =
-      new QAction(QIcon(getQPixmap("cut_xpm")), tr("Cu&t Selection"), this);
+  actionCutSelection = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("cut_xpm")), tr("Cu&t Selection"), this);
   actionCutSelection->setShortcut(tr("Ctrl+X"));
   connect(actionCutSelection, SIGNAL(triggered()), this, SLOT(cutSelection()));
 
-  actionCopySelection =
-      new QAction(QIcon(getQPixmap("copy_xpm")), tr("&Copy Selection"), this);
+  actionCopySelection = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("copy_xpm")), tr("&Copy Selection"), this);
   actionCopySelection->setShortcut(tr("Ctrl+C"));
   connect(actionCopySelection, SIGNAL(triggered()), this,
           SLOT(copySelection()));
 
-  actionPasteSelection =
-      new QAction(QIcon(getQPixmap("paste_xpm")), tr("&Paste Selection"), this);
+  actionPasteSelection = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("paste_xpm")), tr("&Paste Selection"), this);
   actionPasteSelection->setShortcut(tr("Ctrl+V"));
   connect(actionPasteSelection, SIGNAL(triggered()), this,
           SLOT(pasteSelection()));
 
-  actionClearSelection = new QAction(QIcon(getQPixmap("erase_xpm")),
-                                     tr("&Delete Selection"), this);
+  actionClearSelection = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("erase_xpm")), tr("&Delete Selection"), this);
   actionClearSelection->setShortcut(tr("Del", "delete key"));
   connect(actionClearSelection, SIGNAL(triggered()), this,
           SLOT(clearSelection()));
@@ -11602,8 +11611,8 @@ void ApplicationWindow::createActions() {
   actionShowLog->setIcon(getQPixmap("log_xpm"));
 
 #ifdef SCRIPTING_PYTHON
-  actionShowScriptWindow =
-      new QAction(getQPixmap("python_xpm"), tr("Toggle &Script Window"), this);
+  actionShowScriptWindow = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("python_xpm"), tr("Toggle &Script Window"), this);
 #ifdef __APPLE__
   actionShowScriptWindow->setShortcut(
       tr("Ctrl+3")); // F3 is used by the window manager on Mac
@@ -11614,7 +11623,7 @@ void ApplicationWindow::createActions() {
   connect(actionShowScriptWindow, SIGNAL(triggered()), this,
           SLOT(showScriptWindow()));
 
-  actionShowScriptInterpreter = new QAction(
+  actionShowScriptInterpreter = new MantidQt::MantidWidgets::TrackedAction(
       getQPixmap("python_xpm"), tr("Toggle Script &Interpreter"), this);
 #ifdef __APPLE__
   actionShowScriptInterpreter->setShortcut(
@@ -11627,783 +11636,891 @@ void ApplicationWindow::createActions() {
           SLOT(showScriptInterpreter()));
 #endif
 
-  actionAddLayer =
-      new QAction(QIcon(getQPixmap("newLayer_xpm")), tr("Add La&yer"), this);
+  actionAddLayer = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("newLayer_xpm")), tr("Add La&yer"), this);
   actionAddLayer->setShortcut(tr("Alt+L"));
   connect(actionAddLayer, SIGNAL(triggered()), this, SLOT(addLayer()));
 
-  actionShowLayerDialog = new QAction(QIcon(getQPixmap("arrangeLayers_xpm")),
-                                      tr("Arran&ge Layers"), this);
+  actionShowLayerDialog = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("arrangeLayers_xpm")), tr("Arran&ge Layers"), this);
   actionShowLayerDialog->setShortcut(tr("Alt+A"));
   connect(actionShowLayerDialog, SIGNAL(triggered()), this,
           SLOT(showLayerDialog()));
 
-  actionAutomaticLayout = new QAction(QIcon(getQPixmap("auto_layout_xpm")),
-                                      tr("Automatic Layout"), this);
+  actionAutomaticLayout = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("auto_layout_xpm")), tr("Automatic Layout"), this);
   connect(actionAutomaticLayout, SIGNAL(triggered()), this,
           SLOT(autoArrangeLayers()));
 
-  actionExportGraph = new QAction(tr("&Current"), this);
+  actionExportGraph =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Current"), this);
   actionExportGraph->setShortcut(tr("Alt+G"));
   connect(actionExportGraph, SIGNAL(triggered()), this, SLOT(exportGraph()));
 
-  actionExportAllGraphs = new QAction(tr("&All"), this);
+  actionExportAllGraphs =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&All"), this);
   actionExportAllGraphs->setShortcut(tr("Alt+X"));
   connect(actionExportAllGraphs, SIGNAL(triggered()), this,
           SLOT(exportAllGraphs()));
 
-  actionExportPDF =
-      new QAction(QIcon(getQPixmap("pdf_xpm")), tr("&Export PDF"), this);
+  actionExportPDF = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("pdf_xpm")), tr("&Export PDF"), this);
   actionExportPDF->setShortcut(tr("Ctrl+Alt+P"));
   connect(actionExportPDF, SIGNAL(triggered()), this, SLOT(exportPDF()));
 
-  actionPrint =
-      new QAction(QIcon(getQPixmap("fileprint_xpm")), tr("&Print"), this);
+  actionPrint = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("fileprint_xpm")), tr("&Print"), this);
   actionPrint->setShortcut(tr("Ctrl+P"));
   connect(actionPrint, SIGNAL(triggered()), this, SLOT(print()));
 
-  actionPrintAllPlots = new QAction(tr("Print All Plo&ts"), this);
+  actionPrintAllPlots =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Print All Plo&ts"), this);
   connect(actionPrintAllPlots, SIGNAL(triggered()), this,
           SLOT(printAllPlots()));
 
-  actionShowExportASCIIDialog = new QAction(tr("E&xport ASCII"), this);
+  actionShowExportASCIIDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("E&xport ASCII"), this);
   connect(actionShowExportASCIIDialog, SIGNAL(triggered()), this,
           SLOT(showExportASCIIDialog()));
 
-  actionCloseAllWindows =
-      new QAction(QIcon(getQPixmap("quit_xpm")), tr("&Quit"), this);
+  actionCloseAllWindows = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("quit_xpm")), tr("&Quit"), this);
   actionCloseAllWindows->setShortcut(tr("Ctrl+Q"));
   connect(actionCloseAllWindows, SIGNAL(triggered()), qApp,
           SLOT(closeAllWindows()));
 
-  actionDeleteFitTables = new QAction(QIcon(getQPixmap("close_xpm")),
-                                      tr("Delete &Fit Tables"), this);
+  actionDeleteFitTables = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("close_xpm")), tr("Delete &Fit Tables"), this);
   connect(actionDeleteFitTables, SIGNAL(triggered()), this,
           SLOT(deleteFitTables()));
 
-  actionShowPlotWizard =
-      new QAction(QIcon(getQPixmap("wizard_xpm")), tr("Plot &Wizard"), this);
+  actionShowPlotWizard = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("wizard_xpm")), tr("Plot &Wizard"), this);
   actionShowPlotWizard->setShortcut(tr("Ctrl+Alt+W"));
   connect(actionShowPlotWizard, SIGNAL(triggered()), this,
           SLOT(showPlotWizard()));
 
-  actionShowConfigureDialog =
-      new QAction(QIcon(":/configure.png"), tr("&Preferences..."), this);
+  actionShowConfigureDialog = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/configure.png"), tr("&Preferences..."), this);
   connect(actionShowConfigureDialog, SIGNAL(triggered()), this,
           SLOT(showPreferencesDialog()));
 
-  actionShowCurvesDialog = new QAction(QIcon(getQPixmap("curves_xpm")),
-                                       tr("Add/Remove &Curve..."), this);
+  actionShowCurvesDialog = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("curves_xpm")), tr("Add/Remove &Curve..."), this);
   actionShowCurvesDialog->setShortcut(tr("Ctrl+Alt+C"));
   connect(actionShowCurvesDialog, SIGNAL(triggered()), this,
           SLOT(showCurvesDialog()));
 
-  actionAddErrorBars = new QAction(QIcon(getQPixmap("errors_xpm")),
-                                   tr("Add &Error Bars..."), this);
+  actionAddErrorBars = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("errors_xpm")), tr("Add &Error Bars..."), this);
   actionAddErrorBars->setShortcut(tr("Ctrl+Alt+E"));
   connect(actionAddErrorBars, SIGNAL(triggered()), this, SLOT(addErrorBars()));
 
-  actionRemoveErrorBars = new QAction(QIcon(getQPixmap("errors_remove_xpm")),
-                                      tr("&Remove Error Bars..."), this);
+  actionRemoveErrorBars = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("errors_remove_xpm")), tr("&Remove Error Bars..."),
+      this);
   actionRemoveErrorBars->setShortcut(tr("Ctrl+Alt+R"));
   connect(actionRemoveErrorBars, SIGNAL(triggered()), this,
           SLOT(removeErrorBars()));
 
-  actionAddFunctionCurve =
-      new QAction(QIcon(getQPixmap("fx_xpm")), tr("Add &Function..."), this);
+  actionAddFunctionCurve = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("fx_xpm")), tr("Add &Function..."), this);
   actionAddFunctionCurve->setShortcut(tr("Ctrl+Alt+F"));
   connect(actionAddFunctionCurve, SIGNAL(triggered()), this,
           SLOT(addFunctionCurve()));
 
-  actionUnzoom = new QAction(QIcon(getQPixmap("unzoom_xpm")),
-                             tr("&Rescale to Show All"), this);
+  actionUnzoom = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("unzoom_xpm")), tr("&Rescale to Show All"), this);
   actionUnzoom->setShortcut(tr("Ctrl+Shift+R"));
   connect(actionUnzoom, SIGNAL(triggered()), this, SLOT(setAutoScale()));
 
-  actionNewLegend =
-      new QAction(QIcon(getQPixmap("legend_xpm")), tr("New &Legend"), this);
+  actionNewLegend = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("legend_xpm")), tr("New &Legend"), this);
   actionNewLegend->setShortcut(tr("Ctrl+Alt+L"));
   connect(actionNewLegend, SIGNAL(triggered()), this, SLOT(newLegend()));
 
-  actionTimeStamp =
-      new QAction(QIcon(getQPixmap("clock_xpm")), tr("Add Time &Stamp"), this);
+  actionTimeStamp = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("clock_xpm")), tr("Add Time &Stamp"), this);
   actionTimeStamp->setShortcut(tr("Ctrl+ALT+S"));
   connect(actionTimeStamp, SIGNAL(triggered()), this, SLOT(addTimeStamp()));
 
-  actionAddImage =
-      new QAction(QIcon(getQPixmap("monalisa_xpm")), tr("Add &Image"), this);
+  actionAddImage = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("monalisa_xpm")), tr("Add &Image"), this);
   actionAddImage->setShortcut(tr("Ctrl+Alt+I"));
   connect(actionAddImage, SIGNAL(triggered()), this, SLOT(addImage()));
 
-  actionPlotL = new QAction(QIcon(getQPixmap("lPlot_xpm")), tr("&Line"), this);
+  actionPlotL = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("lPlot_xpm")), tr("&Line"), this);
   connect(actionPlotL, SIGNAL(triggered()), this, SLOT(plotL()));
 
-  actionPlotP =
-      new QAction(QIcon(getQPixmap("pPlot_xpm")), tr("&Scatter"), this);
+  actionPlotP = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("pPlot_xpm")), tr("&Scatter"), this);
   connect(actionPlotP, SIGNAL(triggered()), this, SLOT(plotP()));
 
-  actionPlotLP =
-      new QAction(QIcon(getQPixmap("lpPlot_xpm")), tr("Line + S&ymbol"), this);
+  actionPlotLP = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("lpPlot_xpm")), tr("Line + S&ymbol"), this);
   connect(actionPlotLP, SIGNAL(triggered()), this, SLOT(plotLP()));
 
-  actionPlotVerticalDropLines = new QAction(QIcon(getQPixmap("dropLines_xpm")),
-                                            tr("Vertical &Drop Lines"), this);
+  actionPlotVerticalDropLines = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("dropLines_xpm")), tr("Vertical &Drop Lines"), this);
   connect(actionPlotVerticalDropLines, SIGNAL(triggered()), this,
           SLOT(plotVerticalDropLines()));
 
-  actionPlotSpline =
-      new QAction(QIcon(getQPixmap("spline_xpm")), tr("&Spline"), this);
+  actionPlotSpline = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("spline_xpm")), tr("&Spline"), this);
   connect(actionPlotSpline, SIGNAL(triggered()), this, SLOT(plotSpline()));
 
-  actionPlotHorSteps =
-      new QAction(getQPixmap("hor_steps_xpm"), tr("&Horizontal Steps"), this);
+  actionPlotHorSteps = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("hor_steps_xpm"), tr("&Horizontal Steps"), this);
   connect(actionPlotHorSteps, SIGNAL(triggered()), this, SLOT(plotHorSteps()));
 
-  actionPlotVertSteps = new QAction(QIcon(getQPixmap("vert_steps_xpm")),
-                                    tr("&Vertical Steps"), this);
+  actionPlotVertSteps = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("vert_steps_xpm")), tr("&Vertical Steps"), this);
   connect(actionPlotVertSteps, SIGNAL(triggered()), this,
           SLOT(plotVertSteps()));
 
-  actionPlotVerticalBars =
-      new QAction(QIcon(getQPixmap("vertBars_xpm")), tr("&Columns"), this);
+  actionPlotVerticalBars = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("vertBars_xpm")), tr("&Columns"), this);
   connect(actionPlotVerticalBars, SIGNAL(triggered()), this,
           SLOT(plotVerticalBars()));
 
-  actionPlotHorizontalBars =
-      new QAction(QIcon(getQPixmap("hBars_xpm")), tr("&Rows"), this);
+  actionPlotHorizontalBars = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("hBars_xpm")), tr("&Rows"), this);
   connect(actionPlotHorizontalBars, SIGNAL(triggered()), this,
           SLOT(plotHorizontalBars()));
 
-  actionPlotArea =
-      new QAction(QIcon(getQPixmap("area_xpm")), tr("&Area"), this);
+  actionPlotArea = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("area_xpm")), tr("&Area"), this);
   connect(actionPlotArea, SIGNAL(triggered()), this, SLOT(plotArea()));
 
-  actionPlotPie = new QAction(QIcon(getQPixmap("pie_xpm")), tr("&Pie"), this);
+  actionPlotPie = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("pie_xpm")), tr("&Pie"), this);
   connect(actionPlotPie, SIGNAL(triggered()), this, SLOT(plotPie()));
 
-  actionPlotVectXYAM =
-      new QAction(QIcon(getQPixmap("vectXYAM_xpm")), tr("Vectors XY&AM"), this);
+  actionPlotVectXYAM = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("vectXYAM_xpm")), tr("Vectors XY&AM"), this);
   connect(actionPlotVectXYAM, SIGNAL(triggered()), this, SLOT(plotVectXYAM()));
 
-  actionPlotVectXYXY = new QAction(QIcon(getQPixmap("vectXYXY_xpm")),
-                                   tr("&Vectors &XYXY"), this);
+  actionPlotVectXYXY = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("vectXYXY_xpm")), tr("&Vectors &XYXY"), this);
   connect(actionPlotVectXYXY, SIGNAL(triggered()), this, SLOT(plotVectXYXY()));
 
-  actionPlotHistogram =
-      new QAction(QIcon(getQPixmap("histogram_xpm")), tr("&Histogram"), this);
+  actionPlotHistogram = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("histogram_xpm")), tr("&Histogram"), this);
   connect(actionPlotHistogram, SIGNAL(triggered()), this,
           SLOT(plotHistogram()));
 
-  actionPlotStackedHistograms = new QAction(
+  actionPlotStackedHistograms = new MantidQt::MantidWidgets::TrackedAction(
       QIcon(getQPixmap("stacked_hist_xpm")), tr("&Stacked Histogram"), this);
   connect(actionPlotStackedHistograms, SIGNAL(triggered()), this,
           SLOT(plotStackedHistograms()));
 
-  actionStemPlot =
-      new QAction(QIcon(":/leaf.png"), tr("Stem-and-&Leaf Plot"), this);
+  actionStemPlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/leaf.png"), tr("Stem-and-&Leaf Plot"), this);
   connect(actionStemPlot, SIGNAL(triggered()), this, SLOT(newStemPlot()));
 
-  actionPlot2VerticalLayers = new QAction(QIcon(getQPixmap("panel_v2_xpm")),
-                                          tr("&Vertical 2 Layers"), this);
+  actionPlot2VerticalLayers = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("panel_v2_xpm")), tr("&Vertical 2 Layers"), this);
   connect(actionPlot2VerticalLayers, SIGNAL(triggered()), this,
           SLOT(plot2VerticalLayers()));
 
-  actionPlot2HorizontalLayers = new QAction(QIcon(getQPixmap("panel_h2_xpm")),
-                                            tr("&Horizontal 2 Layers"), this);
+  actionPlot2HorizontalLayers = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("panel_h2_xpm")), tr("&Horizontal 2 Layers"), this);
   connect(actionPlot2HorizontalLayers, SIGNAL(triggered()), this,
           SLOT(plot2HorizontalLayers()));
 
-  actionPlot4Layers =
-      new QAction(QIcon(getQPixmap("panel_4_xpm")), tr("&4 Layers"), this);
+  actionPlot4Layers = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("panel_4_xpm")), tr("&4 Layers"), this);
   connect(actionPlot4Layers, SIGNAL(triggered()), this, SLOT(plot4Layers()));
 
-  actionPlotStackedLayers = new QAction(QIcon(getQPixmap("stacked_xpm")),
-                                        tr("&Stacked Layers"), this);
+  actionPlotStackedLayers = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("stacked_xpm")), tr("&Stacked Layers"), this);
   connect(actionPlotStackedLayers, SIGNAL(triggered()), this,
           SLOT(plotStackedLayers()));
 
-  actionPlot3DRibbon =
-      new QAction(QIcon(getQPixmap("ribbon_xpm")), tr("&Ribbon"), this);
+  actionPlot3DRibbon = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("ribbon_xpm")), tr("&Ribbon"), this);
   connect(actionPlot3DRibbon, SIGNAL(triggered()), this, SLOT(plot3DRibbon()));
 
-  actionPlot3DBars =
-      new QAction(QIcon(getQPixmap("bars_xpm")), tr("&Bars"), this);
+  actionPlot3DBars = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("bars_xpm")), tr("&Bars"), this);
   connect(actionPlot3DBars, SIGNAL(triggered()), this, SLOT(plot3DBars()));
 
-  actionPlot3DScatter =
-      new QAction(QIcon(getQPixmap("scatter_xpm")), tr("&Scatter"), this);
+  actionPlot3DScatter = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("scatter_xpm")), tr("&Scatter"), this);
   connect(actionPlot3DScatter, SIGNAL(triggered()), this,
           SLOT(plot3DScatter()));
 
-  actionPlot3DTrajectory =
-      new QAction(QIcon(getQPixmap("trajectory_xpm")), tr("&Trajectory"), this);
+  actionPlot3DTrajectory = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("trajectory_xpm")), tr("&Trajectory"), this);
   connect(actionPlot3DTrajectory, SIGNAL(triggered()), this,
           SLOT(plot3DTrajectory()));
 
-  actionShowColStatistics = new QAction(QIcon(getQPixmap("col_stat_xpm")),
-                                        tr("Statistics on &Columns"), this);
+  actionShowColStatistics = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("col_stat_xpm")), tr("Statistics on &Columns"), this);
   connect(actionShowColStatistics, SIGNAL(triggered()), this,
           SLOT(showColStatistics()));
 
-  actionShowRowStatistics = new QAction(QIcon(getQPixmap("stat_rows_xpm")),
-                                        tr("Statistics on &Rows"), this);
+  actionShowRowStatistics = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("stat_rows_xpm")), tr("Statistics on &Rows"), this);
   connect(actionShowRowStatistics, SIGNAL(triggered()), this,
           SLOT(showRowStatistics()));
 
-  actionIntegrate = new QAction(tr("&Integrate"), this);
+  actionIntegrate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Integrate"), this);
   connect(actionIntegrate, SIGNAL(triggered()), this, SLOT(integrate()));
 
-  actionShowIntDialog = new QAction(tr("Integr&ate Function..."), this);
+  actionShowIntDialog = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Integr&ate Function..."), this);
   connect(actionShowIntDialog, SIGNAL(triggered()), this,
           SLOT(showIntegrationDialog()));
 
-  actionInterpolate = new QAction(tr("Inte&rpolate ..."), this);
+  actionInterpolate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Inte&rpolate ..."), this);
   connect(actionInterpolate, SIGNAL(triggered()), this,
           SLOT(showInterpolationDialog()));
 
-  actionLowPassFilter = new QAction(tr("&Low Pass..."), this);
+  actionLowPassFilter =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Low Pass..."), this);
   connect(actionLowPassFilter, SIGNAL(triggered()), this,
           SLOT(lowPassFilterDialog()));
 
-  actionHighPassFilter = new QAction(tr("&High Pass..."), this);
+  actionHighPassFilter =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&High Pass..."), this);
   connect(actionHighPassFilter, SIGNAL(triggered()), this,
           SLOT(highPassFilterDialog()));
 
-  actionBandPassFilter = new QAction(tr("&Band Pass..."), this);
+  actionBandPassFilter =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Band Pass..."), this);
   connect(actionBandPassFilter, SIGNAL(triggered()), this,
           SLOT(bandPassFilterDialog()));
 
-  actionBandBlockFilter = new QAction(tr("&Band Block..."), this);
+  actionBandBlockFilter =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Band Block..."), this);
   connect(actionBandBlockFilter, SIGNAL(triggered()), this,
           SLOT(bandBlockFilterDialog()));
 
-  actionFFT = new QAction(tr("&FFT..."), this);
+  actionFFT = new MantidQt::MantidWidgets::TrackedAction(tr("&FFT..."), this);
   connect(actionFFT, SIGNAL(triggered()), this, SLOT(showFFTDialog()));
 
-  actionSmoothSavGol = new QAction(tr("&Savitzky-Golay..."), this);
+  actionSmoothSavGol = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Savitzky-Golay..."), this);
   connect(actionSmoothSavGol, SIGNAL(triggered()), this,
           SLOT(showSmoothSavGolDialog()));
 
-  actionSmoothFFT = new QAction(tr("&FFT Filter..."), this);
+  actionSmoothFFT =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&FFT Filter..."), this);
   connect(actionSmoothFFT, SIGNAL(triggered()), this,
           SLOT(showSmoothFFTDialog()));
 
-  actionSmoothAverage = new QAction(tr("Moving Window &Average..."), this);
+  actionSmoothAverage = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Moving Window &Average..."), this);
   connect(actionSmoothAverage, SIGNAL(triggered()), this,
           SLOT(showSmoothAverageDialog()));
 
-  actionDifferentiate = new QAction(tr("&Differentiate"), this);
+  actionDifferentiate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Differentiate"), this);
   connect(actionDifferentiate, SIGNAL(triggered()), this,
           SLOT(differentiate()));
 
-  actionFitLinear = new QAction(tr("Fit &Linear"), this);
+  actionFitLinear =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Fit &Linear"), this);
   connect(actionFitLinear, SIGNAL(triggered()), this, SLOT(fitLinear()));
 
-  actionShowFitPolynomDialog = new QAction(tr("Fit &Polynomial ..."), this);
+  actionShowFitPolynomDialog = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Fit &Polynomial ..."), this);
   connect(actionShowFitPolynomDialog, SIGNAL(triggered()), this,
           SLOT(showFitPolynomDialog()));
 
-  actionShowExpDecayDialog = new QAction(tr("&First Order ..."), this);
+  actionShowExpDecayDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&First Order ..."), this);
   connect(actionShowExpDecayDialog, SIGNAL(triggered()), this,
           SLOT(showExpDecayDialog()));
 
-  actionShowTwoExpDecayDialog = new QAction(tr("&Second Order ..."), this);
+  actionShowTwoExpDecayDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Second Order ..."), this);
   connect(actionShowTwoExpDecayDialog, SIGNAL(triggered()), this,
           SLOT(showTwoExpDecayDialog()));
 
-  actionShowExpDecay3Dialog = new QAction(tr("&Third Order ..."), this);
+  actionShowExpDecay3Dialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Third Order ..."), this);
   connect(actionShowExpDecay3Dialog, SIGNAL(triggered()), this,
           SLOT(showExpDecay3Dialog()));
 
-  actionFitExpGrowth = new QAction(tr("Fit Exponential Gro&wth ..."), this);
+  actionFitExpGrowth = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Fit Exponential Gro&wth ..."), this);
   connect(actionFitExpGrowth, SIGNAL(triggered()), this,
           SLOT(showExpGrowthDialog()));
 
-  actionFitSigmoidal = new QAction(tr("Fit &Boltzmann (Sigmoidal)"), this);
+  actionFitSigmoidal = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Fit &Boltzmann (Sigmoidal)"), this);
   connect(actionFitSigmoidal, SIGNAL(triggered()), this, SLOT(fitSigmoidal()));
 
-  actionFitGauss = new QAction(tr("Fit &Gaussian"), this);
+  actionFitGauss =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Fit &Gaussian"), this);
   connect(actionFitGauss, SIGNAL(triggered()), this, SLOT(fitGauss()));
 
-  actionFitLorentz = new QAction(tr("Fit Lorent&zian"), this);
+  actionFitLorentz =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Fit Lorent&zian"), this);
   connect(actionFitLorentz, SIGNAL(triggered()), this, SLOT(fitLorentz()));
 
-  actionShowFitDialog = new QAction(tr("Fit &Wizard..."), this);
+  actionShowFitDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Fit &Wizard..."), this);
   actionShowFitDialog->setShortcut(tr("Ctrl+Y"));
   connect(actionShowFitDialog, SIGNAL(triggered()), this,
           SLOT(showFitDialog()));
 
-  actionShowPlotDialog = new QAction(tr("&Plot ..."), this);
+  actionShowPlotDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Plot ..."), this);
   connect(actionShowPlotDialog, SIGNAL(triggered()), this,
           SLOT(showGeneralPlotDialog()));
 
-  actionShowScaleDialog = new QAction(tr("&Scales..."), this);
+  actionShowScaleDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Scales..."), this);
   connect(actionShowScaleDialog, SIGNAL(triggered()), this,
           SLOT(showScaleDialog()));
 
-  actionShowAxisDialog = new QAction(tr("&Axes..."), this);
+  actionShowAxisDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Axes..."), this);
   connect(actionShowAxisDialog, SIGNAL(triggered()), this,
           SLOT(showAxisDialog()));
 
-  actionShowGridDialog = new QAction(tr("&Grid ..."), this);
+  actionShowGridDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Grid ..."), this);
   connect(actionShowGridDialog, SIGNAL(triggered()), this,
           SLOT(showGridDialog()));
 
-  actionShowTitleDialog = new QAction(tr("&Title ..."), this);
+  actionShowTitleDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Title ..."), this);
   connect(actionShowTitleDialog, SIGNAL(triggered()), this,
           SLOT(showTitleDialog()));
 
-  actionShowColumnOptionsDialog = new QAction(tr("Column &Options ..."), this);
+  actionShowColumnOptionsDialog = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Column &Options ..."), this);
   actionShowColumnOptionsDialog->setShortcut(tr("Ctrl+Alt+O"));
   connect(actionShowColumnOptionsDialog, SIGNAL(triggered()), this,
           SLOT(showColumnOptionsDialog()));
 
-  actionShowColumnValuesDialog = new QAction(
+  actionShowColumnValuesDialog = new MantidQt::MantidWidgets::TrackedAction(
       QIcon(getQPixmap("formula_xpm")), tr("Set Column &Values ..."), this);
   connect(actionShowColumnValuesDialog, SIGNAL(triggered()), this,
           SLOT(showColumnValuesDialog()));
   actionShowColumnValuesDialog->setShortcut(tr("Alt+Q"));
 
-  actionTableRecalculate = new QAction(tr("Recalculate"), this);
+  actionTableRecalculate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Recalculate"), this);
   actionTableRecalculate->setShortcut(tr("Ctrl+Return"));
   connect(actionTableRecalculate, SIGNAL(triggered()), this,
           SLOT(recalculateTable()));
 
-  actionHideSelectedColumns = new QAction(tr("&Hide Selected"), this);
+  actionHideSelectedColumns =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Hide Selected"), this);
   connect(actionHideSelectedColumns, SIGNAL(triggered()), this,
           SLOT(hideSelectedColumns()));
 
-  actionShowAllColumns = new QAction(tr("Sho&w All Columns"), this);
+  actionShowAllColumns =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Sho&w All Columns"), this);
   connect(actionShowAllColumns, SIGNAL(triggered()), this,
           SLOT(showAllColumns()));
 
-  actionSwapColumns = new QAction(QIcon(getQPixmap("swap_columns_xpm")),
-                                  tr("&Swap columns"), this);
+  actionSwapColumns = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("swap_columns_xpm")), tr("&Swap columns"), this);
   connect(actionSwapColumns, SIGNAL(triggered()), this, SLOT(swapColumns()));
 
-  actionMoveColRight = new QAction(QIcon(getQPixmap("move_col_right_xpm")),
-                                   tr("Move &Right"), this);
+  actionMoveColRight = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("move_col_right_xpm")), tr("Move &Right"), this);
   connect(actionMoveColRight, SIGNAL(triggered()), this,
           SLOT(moveColumnRight()));
 
-  actionMoveColLeft = new QAction(QIcon(getQPixmap("move_col_left_xpm")),
-                                  tr("Move &Left"), this);
+  actionMoveColLeft = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("move_col_left_xpm")), tr("Move &Left"), this);
   connect(actionMoveColLeft, SIGNAL(triggered()), this, SLOT(moveColumnLeft()));
 
-  actionMoveColFirst = new QAction(QIcon(getQPixmap("move_col_first_xpm")),
-                                   tr("Move to F&irst"), this);
+  actionMoveColFirst = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("move_col_first_xpm")), tr("Move to F&irst"), this);
   connect(actionMoveColFirst, SIGNAL(triggered()), this,
           SLOT(moveColumnFirst()));
 
-  actionMoveColLast = new QAction(QIcon(getQPixmap("move_col_last_xpm")),
-                                  tr("Move to Las&t"), this);
+  actionMoveColLast = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("move_col_last_xpm")), tr("Move to Las&t"), this);
   connect(actionMoveColLast, SIGNAL(triggered()), this, SLOT(moveColumnLast()));
 
-  actionShowColsDialog = new QAction(tr("&Columns..."), this);
+  actionShowColsDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Columns..."), this);
   connect(actionShowColsDialog, SIGNAL(triggered()), this,
           SLOT(showColsDialog()));
 
-  actionShowRowsDialog = new QAction(tr("&Rows..."), this);
+  actionShowRowsDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Rows..."), this);
   connect(actionShowRowsDialog, SIGNAL(triggered()), this,
           SLOT(showRowsDialog()));
 
-  actionDeleteRows = new QAction(tr("&Delete Rows Interval..."), this);
+  actionDeleteRows = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Delete Rows Interval..."), this);
   connect(actionDeleteRows, SIGNAL(triggered()), this,
           SLOT(showDeleteRowsDialog()));
 
-  actionAbout = new QAction(tr("&About MantidPlot"), this); // Mantid
+  actionAbout = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&About MantidPlot"), this); // Mantid
   actionAbout->setShortcut(tr("F1"));
   connect(actionAbout, SIGNAL(triggered()), this, SLOT(about()));
 
-  actionShowHelp = new QAction(tr("&Help"), this);
+  actionShowHelp =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Help"), this);
   actionShowHelp->setShortcut(tr("Ctrl+H"));
   connect(actionShowHelp, SIGNAL(triggered()), this, SLOT(showHelp()));
 
-  actionMantidConcepts = new QAction(tr("&Mantid Concepts"), this);
+  actionMantidConcepts =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Mantid Concepts"), this);
   connect(actionMantidConcepts, SIGNAL(triggered()), this,
           SLOT(showMantidConcepts()));
 
-  actionMantidAlgorithms = new QAction(tr("&Algorithm Descriptions"), this);
+  actionMantidAlgorithms = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Algorithm Descriptions"), this);
   connect(actionMantidAlgorithms, SIGNAL(triggered()), this,
           SLOT(showalgorithmDescriptions()));
 
-  actionmantidplotHelp = new QAction(tr("&MantidPlot Help"), this);
+  actionmantidplotHelp =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&MantidPlot Help"), this);
   connect(actionmantidplotHelp, SIGNAL(triggered()), this,
           SLOT(showmantidplotHelp()));
 
-  actionChooseHelpFolder = new QAction(tr("&Choose Help Folder..."), this);
+  actionChooseHelpFolder = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Choose Help Folder..."), this);
   connect(actionChooseHelpFolder, SIGNAL(triggered()), this,
           SLOT(chooseHelpFolder()));
 
-  actionRename = new QAction(tr("&Rename Window"), this);
+  actionRename =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Rename Window"), this);
   connect(actionRename, SIGNAL(triggered()), this, SLOT(rename()));
 
-  actionCloseWindow =
-      new QAction(QIcon(getQPixmap("close_xpm")), tr("Close &Window"), this);
+  actionCloseWindow = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("close_xpm")), tr("Close &Window"), this);
   actionCloseWindow->setShortcut(tr("Ctrl+W"));
   connect(actionCloseWindow, SIGNAL(triggered()), this,
           SLOT(closeActiveWindow()));
 
-  actionAddColToTable =
-      new QAction(QIcon(getQPixmap("addCol_xpm")), tr("Add Column"), this);
+  actionAddColToTable = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("addCol_xpm")), tr("Add Column"), this);
   connect(actionAddColToTable, SIGNAL(triggered()), this,
           SLOT(addColToTable()));
 
-  actionGoToRow = new QAction(tr("&Go to Row..."), this);
+  actionGoToRow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Go to Row..."), this);
   actionGoToRow->setShortcut(tr("Ctrl+Alt+G"));
   connect(actionGoToRow, SIGNAL(triggered()), this, SLOT(goToRow()));
 
-  actionGoToColumn = new QAction(tr("Go to Colum&n..."), this);
+  actionGoToColumn =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Go to Colum&n..."), this);
   actionGoToColumn->setShortcut(tr("Ctrl+Alt+C"));
   connect(actionGoToColumn, SIGNAL(triggered()), this, SLOT(goToColumn()));
 
-  actionClearTable = new QAction(getQPixmap("erase_xpm"), tr("Clear"), this);
+  actionClearTable = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("erase_xpm"), tr("Clear"), this);
   connect(actionClearTable, SIGNAL(triggered()), this, SLOT(clearTable()));
 
-  actionDeleteLayer =
-      new QAction(QIcon(getQPixmap("erase_xpm")), tr("&Remove Layer"), this);
+  actionDeleteLayer = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("erase_xpm")), tr("&Remove Layer"), this);
   actionDeleteLayer->setShortcut(tr("Alt+R"));
   connect(actionDeleteLayer, SIGNAL(triggered()), this, SLOT(deleteLayer()));
 
-  actionResizeActiveWindow = new QAction(QIcon(getQPixmap("resize_xpm")),
-                                         tr("Window &Geometry..."), this);
+  actionResizeActiveWindow = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("resize_xpm")), tr("Window &Geometry..."), this);
   connect(actionResizeActiveWindow, SIGNAL(triggered()), this,
           SLOT(resizeActiveWindow()));
 
-  actionHideActiveWindow = new QAction(tr("&Hide Window"), this);
+  actionHideActiveWindow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Hide Window"), this);
   connect(actionHideActiveWindow, SIGNAL(triggered()), this,
           SLOT(hideActiveWindow()));
 
-  actionShowMoreWindows = new QAction(tr("More windows..."), this);
+  actionShowMoreWindows =
+      new MantidQt::MantidWidgets::TrackedAction(tr("More windows..."), this);
   connect(actionShowMoreWindows, SIGNAL(triggered()), this,
           SLOT(showMoreWindows()));
 
-  actionPixelLineProfile = new QAction(QIcon(getQPixmap("pixelProfile_xpm")),
-                                       tr("&View Pixel Line Profile"), this);
+  actionPixelLineProfile = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("pixelProfile_xpm")), tr("&View Pixel Line Profile"),
+      this);
   connect(actionPixelLineProfile, SIGNAL(triggered()), this,
           SLOT(pixelLineProfile()));
 
-  actionIntensityTable = new QAction(tr("&Intensity Table"), this);
+  actionIntensityTable =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Intensity Table"), this);
   connect(actionIntensityTable, SIGNAL(triggered()), this,
           SLOT(intensityTable()));
 
-  actionShowLineDialog = new QAction(tr("&Properties"), this);
+  actionShowLineDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Properties"), this);
   connect(actionShowLineDialog, SIGNAL(triggered()), this,
           SLOT(showLineDialog()));
 
-  actionShowImageDialog = new QAction(tr("&Properties"), this);
+  actionShowImageDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Properties"), this);
   connect(actionShowImageDialog, SIGNAL(triggered()), this,
           SLOT(showImageDialog()));
 
-  actionShowTextDialog = new QAction(tr("&Properties"), this);
+  actionShowTextDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Properties"), this);
   connect(actionShowTextDialog, SIGNAL(triggered()), this,
           SLOT(showTextDialog()));
 
-  actionActivateWindow = new QAction(tr("&Activate Window"), this);
+  actionActivateWindow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Activate Window"), this);
   connect(actionActivateWindow, SIGNAL(triggered()), this,
           SLOT(activateWindow()));
 
-  actionMinimizeWindow = new QAction(tr("Mi&nimize Window"), this);
+  actionMinimizeWindow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Mi&nimize Window"), this);
   connect(actionMinimizeWindow, SIGNAL(triggered()), this,
           SLOT(minimizeWindow()));
 
-  actionMaximizeWindow = new QAction(tr("Ma&ximize Window"), this);
+  actionMaximizeWindow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Ma&ximize Window"), this);
   connect(actionMaximizeWindow, SIGNAL(triggered()), this,
           SLOT(maximizeWindow()));
 
-  actionHideWindow = new QAction(tr("&Hide Window"), this);
+  actionHideWindow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Hide Window"), this);
   connect(actionHideWindow, SIGNAL(triggered()), this, SLOT(hideWindow()));
 
-  actionResizeWindow = new QAction(QIcon(getQPixmap("resize_xpm")),
-                                   tr("Re&size Window..."), this);
+  actionResizeWindow = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("resize_xpm")), tr("Re&size Window..."), this);
   connect(actionResizeWindow, SIGNAL(triggered()), this, SLOT(resizeWindow()));
 
-  actionEditSurfacePlot = new QAction(tr("&Surface..."), this);
+  actionEditSurfacePlot =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Surface..."), this);
   connect(actionEditSurfacePlot, SIGNAL(triggered()), this,
           SLOT(editSurfacePlot()));
 
-  actionAdd3DData = new QAction(tr("&Data Set..."), this);
+  actionAdd3DData =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Data Set..."), this);
   connect(actionAdd3DData, SIGNAL(triggered()), this, SLOT(add3DData()));
 
-  actionSetMatrixProperties = new QAction(tr("Set &Properties..."), this);
+  actionSetMatrixProperties = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Set &Properties..."), this);
   connect(actionSetMatrixProperties, SIGNAL(triggered()), this,
           SLOT(showMatrixDialog()));
 
-  actionSetMatrixDimensions = new QAction(tr("Set &Dimensions..."), this);
+  actionSetMatrixDimensions = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Set &Dimensions..."), this);
   connect(actionSetMatrixDimensions, SIGNAL(triggered()), this,
           SLOT(showMatrixSizeDialog()));
   actionSetMatrixDimensions->setShortcut(tr("Ctrl+D"));
 
-  actionSetMatrixValues =
-      new QAction(QIcon(getQPixmap("formula_xpm")), tr("Set &Values..."), this);
+  actionSetMatrixValues = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("formula_xpm")), tr("Set &Values..."), this);
   connect(actionSetMatrixValues, SIGNAL(triggered()), this,
           SLOT(showMatrixValuesDialog()));
   actionSetMatrixValues->setShortcut(tr("Alt+Q"));
 
-  actionImagePlot =
-      new QAction(QIcon(getQPixmap("image_plot_xpm")), tr("&Image Plot"), this);
+  actionImagePlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("image_plot_xpm")), tr("&Image Plot"), this);
   connect(actionImagePlot, SIGNAL(triggered()), this, SLOT(plotImage()));
 
-  actionTransposeMatrix = new QAction(tr("&Transpose"), this);
+  actionTransposeMatrix =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Transpose"), this);
   connect(actionTransposeMatrix, SIGNAL(triggered()), this,
           SLOT(transposeMatrix()));
 
-  actionFlipMatrixVertically =
-      new QAction(QIcon(getQPixmap("flip_vertical_xpm")), tr("Flip &V"), this);
+  actionFlipMatrixVertically = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("flip_vertical_xpm")), tr("Flip &V"), this);
   actionFlipMatrixVertically->setShortcut(tr("Ctrl+Shift+V"));
   connect(actionFlipMatrixVertically, SIGNAL(triggered()), this,
           SLOT(flipMatrixVertically()));
 
-  actionFlipMatrixHorizontally = new QAction(
+  actionFlipMatrixHorizontally = new MantidQt::MantidWidgets::TrackedAction(
       QIcon(getQPixmap("flip_horizontal_xpm")), tr("Flip &H"), this);
   actionFlipMatrixHorizontally->setShortcut(tr("Ctrl+Shift+H"));
   connect(actionFlipMatrixHorizontally, SIGNAL(triggered()), this,
           SLOT(flipMatrixHorizontally()));
 
-  actionRotateMatrix = new QAction(QIcon(getQPixmap("rotate_clockwise_xpm")),
-                                   tr("R&otate 90"), this);
+  actionRotateMatrix = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("rotate_clockwise_xpm")), tr("R&otate 90"), this);
   actionRotateMatrix->setShortcut(tr("Ctrl+Shift+R"));
   connect(actionRotateMatrix, SIGNAL(triggered()), this,
           SLOT(rotateMatrix90()));
 
-  actionRotateMatrixMinus =
-      new QAction(QIcon(getQPixmap("rotate_counterclockwise_xpm")),
-                  tr("Rotate &-90"), this);
+  actionRotateMatrixMinus = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("rotate_counterclockwise_xpm")), tr("Rotate &-90"),
+      this);
   actionRotateMatrixMinus->setShortcut(tr("Ctrl+Alt+R"));
   connect(actionRotateMatrixMinus, SIGNAL(triggered()), this,
           SLOT(rotateMatrixMinus90()));
 
-  actionInvertMatrix = new QAction(tr("&Invert"), this);
+  actionInvertMatrix =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Invert"), this);
   connect(actionInvertMatrix, SIGNAL(triggered()), this, SLOT(invertMatrix()));
 
-  actionMatrixDeterminant = new QAction(tr("&Determinant"), this);
+  actionMatrixDeterminant =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Determinant"), this);
   connect(actionMatrixDeterminant, SIGNAL(triggered()), this,
           SLOT(matrixDeterminant()));
 
-  actionViewMatrixImage = new QAction(tr("&Image mode"), this);
+  actionViewMatrixImage =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Image mode"), this);
   actionViewMatrixImage->setShortcut(tr("Ctrl+Shift+I"));
   connect(actionViewMatrixImage, SIGNAL(triggered()), this,
           SLOT(viewMatrixImage()));
   actionViewMatrixImage->setCheckable(true);
 
-  actionViewMatrix = new QAction(tr("&Data mode"), this);
+  actionViewMatrix =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Data mode"), this);
   actionViewMatrix->setShortcut(tr("Ctrl+Shift+D"));
   connect(actionViewMatrix, SIGNAL(triggered()), this, SLOT(viewMatrixTable()));
   actionViewMatrix->setCheckable(true);
 
-  actionMatrixXY = new QAction(tr("Show &X/Y"), this);
+  actionMatrixXY =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Show &X/Y"), this);
   actionMatrixXY->setShortcut(tr("Ctrl+Shift+X"));
   connect(actionMatrixXY, SIGNAL(triggered()), this, SLOT(viewMatrixXY()));
   actionMatrixXY->setCheckable(true);
 
-  actionMatrixColumnRow = new QAction(tr("Show &Column/Row"), this);
+  actionMatrixColumnRow =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Show &Column/Row"), this);
   actionMatrixColumnRow->setShortcut(tr("Ctrl+Shift+C"));
   connect(actionMatrixColumnRow, SIGNAL(triggered()), this,
           SLOT(viewMatrixColumnRow()));
   actionMatrixColumnRow->setCheckable(true);
 
-  actionMatrixGrayScale = new QAction(tr("&Gray Scale"), this);
+  actionMatrixGrayScale =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Gray Scale"), this);
   connect(actionMatrixGrayScale, SIGNAL(triggered()), this,
           SLOT(setMatrixGrayScale()));
   actionMatrixGrayScale->setCheckable(true);
 
-  actionMatrixRainbowScale = new QAction(tr("&Rainbow"), this);
+  actionMatrixRainbowScale =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Rainbow"), this);
   connect(actionMatrixRainbowScale, SIGNAL(triggered()), this,
           SLOT(setMatrixRainbowScale()));
   actionMatrixRainbowScale->setCheckable(true);
 
-  actionMatrixCustomScale = new QAction(tr("&Custom"), this);
+  actionMatrixCustomScale =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Custom"), this);
   connect(actionMatrixCustomScale, SIGNAL(triggered()), this,
           SLOT(showColorMapDialog()));
   actionMatrixCustomScale->setCheckable(true);
 
-  actionExportMatrix = new QAction(tr("&Export Image ..."), this);
+  actionExportMatrix =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Export Image ..."), this);
   connect(actionExportMatrix, SIGNAL(triggered()), this, SLOT(exportMatrix()));
 
-  actionConvertMatrixDirect = new QAction(tr("&Direct"), this);
+  actionConvertMatrixDirect =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Direct"), this);
   connect(actionConvertMatrixDirect, SIGNAL(triggered()), this,
           SLOT(convertMatrixToTableDirect()));
 
-  actionConvertMatrixXYZ = new QAction(tr("&XYZ Columns"), this);
+  actionConvertMatrixXYZ =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&XYZ Columns"), this);
   connect(actionConvertMatrixXYZ, SIGNAL(triggered()), this,
           SLOT(convertMatrixToTableXYZ()));
 
-  actionConvertMatrixYXZ = new QAction(tr("&YXZ Columns"), this);
+  actionConvertMatrixYXZ =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&YXZ Columns"), this);
   connect(actionConvertMatrixYXZ, SIGNAL(triggered()), this,
           SLOT(convertMatrixToTableYXZ()));
 
-  actionMatrixFFTDirect = new QAction(tr("&Forward FFT"), this);
+  actionMatrixFFTDirect =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Forward FFT"), this);
   connect(actionMatrixFFTDirect, SIGNAL(triggered()), this,
           SLOT(matrixDirectFFT()));
 
-  actionMatrixFFTInverse = new QAction(tr("&Inverse FFT"), this);
+  actionMatrixFFTInverse =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Inverse FFT"), this);
   connect(actionMatrixFFTInverse, SIGNAL(triggered()), this,
           SLOT(matrixInverseFFT()));
 
-  actionConvertTable = new QAction(tr("Convert to &Matrix"), this);
+  actionConvertTable = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Convert to &Matrix"), this);
   connect(actionConvertTable, SIGNAL(triggered()), this,
           SLOT(convertTableToMatrix()));
 
-  actionConvertTableToWorkspace =
-      new QAction(tr("Convert to Table&Workspace"), this);
+  actionConvertTableToWorkspace = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Convert to Table&Workspace"), this);
   connect(actionConvertTableToWorkspace, SIGNAL(triggered()), this,
           SLOT(convertTableToWorkspace()));
 
   actionConvertTableToMatrixWorkspace =
-      new QAction(tr("Convert to MatrixWorkspace"), this);
+      new MantidQt::MantidWidgets::TrackedAction(
+          tr("Convert to MatrixWorkspace"), this);
   connect(actionConvertTableToMatrixWorkspace, SIGNAL(triggered()), this,
           SLOT(convertTableToMatrixWorkspace()));
 
-  actionPlot3DWireFrame = new QAction(QIcon(getQPixmap("lineMesh_xpm")),
-                                      tr("3D &Wire Frame"), this);
+  actionPlot3DWireFrame = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("lineMesh_xpm")), tr("3D &Wire Frame"), this);
   connect(actionPlot3DWireFrame, SIGNAL(triggered()), this,
           SLOT(plot3DWireframe()));
 
-  actionPlot3DHiddenLine = new QAction(QIcon(getQPixmap("grid_only_xpm")),
-                                       tr("3D &Hidden Line"), this);
+  actionPlot3DHiddenLine = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("grid_only_xpm")), tr("3D &Hidden Line"), this);
   connect(actionPlot3DHiddenLine, SIGNAL(triggered()), this,
           SLOT(plot3DHiddenLine()));
 
-  actionPlot3DPolygons =
-      new QAction(QIcon(getQPixmap("no_grid_xpm")), tr("3D &Polygons"), this);
+  actionPlot3DPolygons = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("no_grid_xpm")), tr("3D &Polygons"), this);
   connect(actionPlot3DPolygons, SIGNAL(triggered()), this,
           SLOT(plot3DPolygons()));
 
-  actionPlot3DWireSurface = new QAction(QIcon(getQPixmap("grid_poly_xpm")),
-                                        tr("3D Wire &Surface"), this);
+  actionPlot3DWireSurface = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("grid_poly_xpm")), tr("3D Wire &Surface"), this);
   connect(actionPlot3DWireSurface, SIGNAL(triggered()), this,
           SLOT(plot3DWireSurface()));
 
-  actionColorMap = new QAction(QIcon(getQPixmap("color_map_xpm")),
-                               tr("Contour - &Color Fill"), this);
+  actionColorMap = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("color_map_xpm")), tr("Contour - &Color Fill"), this);
   connect(actionColorMap, SIGNAL(triggered()), this, SLOT(plotColorMap()));
 
-  actionContourMap = new QAction(QIcon(getQPixmap("contour_map_xpm")),
-                                 tr("Contour &Lines"), this);
+  actionContourMap = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("contour_map_xpm")), tr("Contour &Lines"), this);
   connect(actionContourMap, SIGNAL(triggered()), this, SLOT(plotContour()));
 
-  actionGrayMap = new QAction(QIcon(getQPixmap("gray_map_xpm")),
-                              tr("&Gray Scale Map"), this);
+  actionGrayMap = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("gray_map_xpm")), tr("&Gray Scale Map"), this);
   connect(actionGrayMap, SIGNAL(triggered()), this, SLOT(plotGrayScale()));
 
-  actionNoContourColorMap =
-      new QAction(QIcon(getQPixmap("color_map_xpm")), tr("Color &Fill"), this);
+  actionNoContourColorMap = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("color_map_xpm")), tr("Color &Fill"), this);
   connect(actionNoContourColorMap, SIGNAL(triggered()), this,
           SLOT(plotNoContourColorMap()));
 
-  actionSortTable = new QAction(tr("Sort Ta&ble"), this);
+  actionSortTable =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Sort Ta&ble"), this);
   connect(actionSortTable, SIGNAL(triggered()), this, SLOT(sortActiveTable()));
 
-  actionSortSelection = new QAction(tr("Sort Columns"), this);
+  actionSortSelection =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Sort Columns"), this);
   connect(actionSortSelection, SIGNAL(triggered()), this,
           SLOT(sortSelection()));
 
-  actionNormalizeTable = new QAction(tr("&Table"), this);
+  actionNormalizeTable =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Table"), this);
   connect(actionNormalizeTable, SIGNAL(triggered()), this,
           SLOT(normalizeActiveTable()));
 
-  actionNormalizeSelection = new QAction(tr("&Columns"), this);
+  actionNormalizeSelection =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Columns"), this);
   connect(actionNormalizeSelection, SIGNAL(triggered()), this,
           SLOT(normalizeSelection()));
 
-  actionCorrelate = new QAction(tr("Co&rrelate"), this);
+  actionCorrelate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Co&rrelate"), this);
   connect(actionCorrelate, SIGNAL(triggered()), this, SLOT(correlate()));
 
-  actionAutoCorrelate = new QAction(tr("&Autocorrelate"), this);
+  actionAutoCorrelate =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Autocorrelate"), this);
   connect(actionAutoCorrelate, SIGNAL(triggered()), this,
           SLOT(autoCorrelate()));
 
-  actionConvolute = new QAction(tr("&Convolute"), this);
+  actionConvolute =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Convolute"), this);
   connect(actionConvolute, SIGNAL(triggered()), this, SLOT(convolute()));
 
-  actionDeconvolute = new QAction(tr("&Deconvolute"), this);
+  actionDeconvolute =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Deconvolute"), this);
   connect(actionDeconvolute, SIGNAL(triggered()), this, SLOT(deconvolute()));
 
-  actionSetAscValues = new QAction(QIcon(getQPixmap("rowNumbers_xpm")),
-                                   tr("Ro&w Numbers"), this);
+  actionSetAscValues = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("rowNumbers_xpm")), tr("Ro&w Numbers"), this);
   connect(actionSetAscValues, SIGNAL(triggered()), this, SLOT(setAscValues()));
 
-  actionSetRandomValues = new QAction(QIcon(getQPixmap("randomNumbers_xpm")),
-                                      tr("&Random Values"), this);
+  actionSetRandomValues = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("randomNumbers_xpm")), tr("&Random Values"), this);
   connect(actionSetRandomValues, SIGNAL(triggered()), this,
           SLOT(setRandomValues()));
 
-  actionReadOnlyCol = new QAction(tr("&Read Only"), this);
+  actionReadOnlyCol =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Read Only"), this);
   connect(actionReadOnlyCol, SIGNAL(triggered()), this, SLOT(setReadOnlyCol()));
 
-  actionSetXCol = new QAction(QIcon(getQPixmap("x_col_xpm")), tr("&X"), this);
+  actionSetXCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("x_col_xpm")), tr("&X"), this);
   connect(actionSetXCol, SIGNAL(triggered()), this, SLOT(setXCol()));
 
-  actionSetYCol = new QAction(QIcon(getQPixmap("y_col_xpm")), tr("&Y"), this);
+  actionSetYCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("y_col_xpm")), tr("&Y"), this);
   connect(actionSetYCol, SIGNAL(triggered()), this, SLOT(setYCol()));
 
-  actionSetZCol = new QAction(QIcon(getQPixmap("z_col_xpm")), tr("&Z"), this);
+  actionSetZCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("z_col_xpm")), tr("&Z"), this);
   connect(actionSetZCol, SIGNAL(triggered()), this, SLOT(setZCol()));
 
-  actionSetXErrCol = new QAction(tr("X E&rror"), this);
+  actionSetXErrCol =
+      new MantidQt::MantidWidgets::TrackedAction(tr("X E&rror"), this);
   connect(actionSetXErrCol, SIGNAL(triggered()), this, SLOT(setXErrCol()));
 
-  actionSetYErrCol =
-      new QAction(QIcon(getQPixmap("errors_xpm")), tr("Y &Error"), this);
+  actionSetYErrCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("errors_xpm")), tr("Y &Error"), this);
   connect(actionSetYErrCol, SIGNAL(triggered()), this, SLOT(setYErrCol()));
 
-  actionDisregardCol = new QAction(QIcon(getQPixmap("disregard_col_xpm")),
-                                   tr("&Disregard"), this);
+  actionDisregardCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("disregard_col_xpm")), tr("&Disregard"), this);
   connect(actionDisregardCol, SIGNAL(triggered()), this, SLOT(disregardCol()));
 
-  actionSetLabelCol =
-      new QAction(QIcon(getQPixmap("set_label_col_xpm")), tr("&Label"), this);
+  actionSetLabelCol = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("set_label_col_xpm")), tr("&Label"), this);
   connect(actionSetLabelCol, SIGNAL(triggered()), this, SLOT(setLabelCol()));
 
-  actionBoxPlot =
-      new QAction(QIcon(getQPixmap("boxPlot_xpm")), tr("&Box Plot"), this);
+  actionBoxPlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(getQPixmap("boxPlot_xpm")), tr("&Box Plot"), this);
   connect(actionBoxPlot, SIGNAL(triggered()), this, SLOT(plotBoxDiagram()));
 
-  actionHomePage = new QAction(tr("&Mantid Homepage"), this); // Mantid change
+  actionHomePage = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Mantid Homepage"), this); // Mantid change
   connect(actionHomePage, SIGNAL(triggered()), this, SLOT(showHomePage()));
 
-  actionHelpBugReports = new QAction(tr("Report a &Bug"), this);
+  actionHelpBugReports =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Report a &Bug"), this);
   connect(actionHelpBugReports, SIGNAL(triggered()), this,
           SLOT(showBugTracker()));
 
-  actionAskHelp = new QAction(tr("Ask for Help"), this);
+  actionAskHelp =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Ask for Help"), this);
   connect(actionAskHelp, SIGNAL(triggered()), this, SLOT(showBugTracker()));
 
-  actionShowCurvePlotDialog = new QAction(tr("&Plot details..."), this);
+  actionShowCurvePlotDialog =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Plot details..."), this);
   connect(actionShowCurvePlotDialog, SIGNAL(triggered()), this,
           SLOT(showCurvePlotDialog()));
 
-  actionShowCurveWorksheet = new QAction(tr("&Worksheet"), this);
+  actionShowCurveWorksheet =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Worksheet"), this);
   connect(actionShowCurveWorksheet, SIGNAL(triggered()), this,
           SLOT(showCurveWorksheet()));
 
-  actionCurveFullRange = new QAction(tr("&Reset to Full Range"), this);
+  actionCurveFullRange = new MantidQt::MantidWidgets::TrackedAction(
+      tr("&Reset to Full Range"), this);
   connect(actionCurveFullRange, SIGNAL(triggered()), this,
           SLOT(setCurveFullRange()));
 
-  actionEditCurveRange = new QAction(tr("Edit &Range..."), this);
+  actionEditCurveRange =
+      new MantidQt::MantidWidgets::TrackedAction(tr("Edit &Range..."), this);
   connect(actionEditCurveRange, SIGNAL(triggered()), this,
           SLOT(showCurveRangeDialog()));
 
-  actionRemoveCurve = new QAction(getQPixmap("close_xpm"), tr("&Delete"), this);
+  actionRemoveCurve = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("close_xpm"), tr("&Delete"), this);
   connect(actionRemoveCurve, SIGNAL(triggered()), this, SLOT(removeCurve()));
 
-  actionHideCurve = new QAction(tr("&Hide"), this);
+  actionHideCurve =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Hide"), this);
   connect(actionHideCurve, SIGNAL(triggered()), this, SLOT(hideCurve()));
 
-  actionHideOtherCurves = new QAction(tr("Hide &Other Curves"), this);
+  actionHideOtherCurves = new MantidQt::MantidWidgets::TrackedAction(
+      tr("Hide &Other Curves"), this);
   connect(actionHideOtherCurves, SIGNAL(triggered()), this,
           SLOT(hideOtherCurves()));
 
-  actionShowAllCurves = new QAction(tr("&Show All Curves"), this);
+  actionShowAllCurves =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Show All Curves"), this);
   connect(actionShowAllCurves, SIGNAL(triggered()), this,
           SLOT(showAllCurves()));
 
-  actionEditFunction = new QAction(tr("&Edit Function..."), this);
+  actionEditFunction =
+      new MantidQt::MantidWidgets::TrackedAction(tr("&Edit Function..."), this);
   connect(actionEditFunction, SIGNAL(triggered()), this,
           SLOT(showFunctionDialog()));
 
-  actionFontBold = new QAction("B", this);
+  actionFontBold = new MantidQt::MantidWidgets::TrackedAction("B", this);
   actionFontBold->setToolTip(tr("Bold"));
   QFont font = appFont;
   font.setBold(true);
@@ -12411,7 +12528,7 @@ void ApplicationWindow::createActions() {
   actionFontBold->setCheckable(true);
   connect(actionFontBold, SIGNAL(toggled(bool)), this, SLOT(setBoldFont(bool)));
 
-  actionFontItalic = new QAction("It", this);
+  actionFontItalic = new MantidQt::MantidWidgets::TrackedAction("It", this);
   actionFontItalic->setToolTip(tr("Italic"));
   font = appFont;
   font.setItalic(true);
@@ -12420,17 +12537,18 @@ void ApplicationWindow::createActions() {
   connect(actionFontItalic, SIGNAL(toggled(bool)), this,
           SLOT(setItalicFont(bool)));
 
-  actionSuperscript =
-      new QAction(getQPixmap("exp_xpm"), tr("Superscript"), this);
+  actionSuperscript = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("exp_xpm"), tr("Superscript"), this);
   connect(actionSuperscript, SIGNAL(triggered()), this,
           SLOT(insertSuperscript()));
   actionSuperscript->setEnabled(false);
 
-  actionSubscript = new QAction(getQPixmap("index_xpm"), tr("Subscript"), this);
+  actionSubscript = new MantidQt::MantidWidgets::TrackedAction(
+      getQPixmap("index_xpm"), tr("Subscript"), this);
   connect(actionSubscript, SIGNAL(triggered()), this, SLOT(insertSubscript()));
   actionSubscript->setEnabled(false);
 
-  actionUnderline = new QAction("U", this);
+  actionUnderline = new MantidQt::MantidWidgets::TrackedAction("U", this);
   actionUnderline->setToolTip(tr("Underline (Ctrl+U)"));
   actionUnderline->setShortcut(tr("Ctrl+U"));
   font = appFont;
@@ -12439,51 +12557,59 @@ void ApplicationWindow::createActions() {
   connect(actionUnderline, SIGNAL(triggered()), this, SLOT(underline()));
   actionUnderline->setEnabled(false);
 
-  actionGreekSymbol =
-      new QAction(QString(QChar(0x3B1)) + QString(QChar(0x3B2)), this);
+  actionGreekSymbol = new MantidQt::MantidWidgets::TrackedAction(
+      QString(QChar(0x3B1)) + QString(QChar(0x3B2)), this);
   actionGreekSymbol->setToolTip(tr("Greek"));
   connect(actionGreekSymbol, SIGNAL(triggered()), this,
           SLOT(insertGreekSymbol()));
 
-  actionGreekMajSymbol = new QAction(QString(QChar(0x393)), this);
+  actionGreekMajSymbol =
+      new MantidQt::MantidWidgets::TrackedAction(QString(QChar(0x393)), this);
   actionGreekMajSymbol->setToolTip(tr("Greek"));
   connect(actionGreekMajSymbol, SIGNAL(triggered()), this,
           SLOT(insertGreekMajSymbol()));
 
-  actionMathSymbol = new QAction(QString(QChar(0x222B)), this);
+  actionMathSymbol =
+      new MantidQt::MantidWidgets::TrackedAction(QString(QChar(0x222B)), this);
   actionMathSymbol->setToolTip(tr("Mathematical Symbols"));
   connect(actionMathSymbol, SIGNAL(triggered()), this,
           SLOT(insertMathSymbol()));
 
-  actionclearAllMemory = new QAction("&Clear All Memory", this);
+  actionclearAllMemory =
+      new MantidQt::MantidWidgets::TrackedAction("&Clear All Memory", this);
   actionclearAllMemory->setShortcut(QKeySequence::fromString("Ctrl+Shift+L"));
   connect(actionclearAllMemory, SIGNAL(triggered()), mantidUI,
           SLOT(clearAllMemory()));
 
-  actionPanPlot = new QAction(QIcon(":/panning.png"), tr("Panning tool"), this);
+  actionPanPlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/panning.png"), tr("Panning tool"), this);
   connect(actionPanPlot, SIGNAL(triggered()), this, SLOT(panOnPlot()));
 
-  actionCatalogLogin = new QAction("Login", this);
+  actionCatalogLogin =
+      new MantidQt::MantidWidgets::TrackedAction("Login", this);
   actionCatalogLogin->setToolTip(tr("Catalog Login"));
   connect(actionCatalogLogin, SIGNAL(triggered()), this, SLOT(CatalogLogin()));
 
-  actionCatalogSearch = new QAction("Search", this);
+  actionCatalogSearch =
+      new MantidQt::MantidWidgets::TrackedAction("Search", this);
   actionCatalogSearch->setToolTip(tr("Search data in archives."));
   connect(actionCatalogSearch, SIGNAL(triggered()), this,
           SLOT(CatalogSearch()));
 
-  actionCatalogPublish = new QAction("Publish", this);
+  actionCatalogPublish =
+      new MantidQt::MantidWidgets::TrackedAction("Publish", this);
   actionCatalogPublish->setToolTip(tr("Publish data to the archives."));
   connect(actionCatalogPublish, SIGNAL(triggered()), this,
           SLOT(CatalogPublish()));
 
-  actionCatalogLogout = new QAction("Logout", this);
+  actionCatalogLogout =
+      new MantidQt::MantidWidgets::TrackedAction("Logout", this);
   actionCatalogLogout->setToolTip(tr("Catalog Logout"));
   connect(actionCatalogLogout, SIGNAL(triggered()), this,
           SLOT(CatalogLogout()));
 
-  actionWaterfallPlot =
-      new QAction(QIcon(":/waterfall_plot.png"), tr("&Waterfall Plot"), this);
+  actionWaterfallPlot = new MantidQt::MantidWidgets::TrackedAction(
+      QIcon(":/waterfall_plot.png"), tr("&Waterfall Plot"), this);
   connect(actionWaterfallPlot, SIGNAL(triggered()), this,
           SLOT(waterfallPlot()));
 }
@@ -13861,7 +13987,7 @@ void ApplicationWindow::saveFolderAsProject(Folder *f) {
   filter += tr("Compressed MantidPlot project") + " (*.qti.gz)";
 
   QString selectedFilter;
-  QString fn = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString fn = QFileDialog::getSaveFileName(
       this, tr("Save project as"), workingDir, filter, &selectedFilter);
   if (!fn.isEmpty()) {
     QFileInfo fi(fn);
@@ -14240,7 +14366,9 @@ bool ApplicationWindow::changeFolder(Folder *newFolder, bool force) {
   if (active_window)
     active_window_state = active_window->status();
 
-  hideFolderWindows(oldFolder);
+  if (newFolder != oldFolder)
+    hideFolderWindows(oldFolder);
+
   d_current_folder = newFolder;
 
   resultsLog->clear();
diff --git a/MantidPlot/src/ConfigDialog.cpp b/MantidPlot/src/ConfigDialog.cpp
index 032912b7ef8db18881a14e6f7f740ee2fecf60b7..f30837b4dd25b2f05baa0af6c0b0d6b76363084a 100644
--- a/MantidPlot/src/ConfigDialog.cpp
+++ b/MantidPlot/src/ConfigDialog.cpp
@@ -1586,11 +1586,6 @@ void ConfigDialog::initCurveFittingTab() {
   findPeaksTolerance->setMaximum(1000000);
   grid->addWidget(findPeaksTolerance, 4, 1);
 
-  grid->addWidget(new QLabel(tr("Peak Radius (in FWHM)")), 5, 0);
-  peakRadius = new QSpinBox();
-  peakRadius->setMaximum(std::numeric_limits<int>::max());
-  grid->addWidget(peakRadius, 5, 1);
-
   grid->addWidget(new QLabel(tr("Double property decimals")), 6, 0);
   decimals = new QSpinBox();
   grid->addWidget(decimals, 6, 1);
@@ -1675,15 +1670,6 @@ void ConfigDialog::initCurveFittingTab() {
     findPeaksTolerance->setValue(4);
   }
 
-  setting = QString::fromStdString(
-      Mantid::Kernel::ConfigService::Instance().getString(
-          "curvefitting.peakRadius"));
-  if (!setting.isEmpty()) {
-    peakRadius->setValue(setting.toInt());
-  } else {
-    peakRadius->setValue(5);
-  }
-
   decimals->setValue(app->mantidUI->fitFunctionBrowser()->getDecimals());
 }
 
@@ -2806,9 +2792,6 @@ void ConfigDialog::updateCurveFitSettings() {
   setting = QString::number(findPeaksTolerance->value()).toStdString();
   cfgSvc.setString("curvefitting.findPeaksTolerance", setting);
 
-  setting = QString::number(peakRadius->value()).toStdString();
-  cfgSvc.setString("curvefitting.peakRadius", setting);
-
   app->mantidUI->fitFunctionBrowser()->setDecimals(decimals->value());
 }
 
diff --git a/MantidPlot/src/ConfigDialog.h b/MantidPlot/src/ConfigDialog.h
index cc14cf626f202a95a2818351ba15c2fdd8fdc002..e795145e2acd681c176c82cdc12d41f23707524f 100644
--- a/MantidPlot/src/ConfigDialog.h
+++ b/MantidPlot/src/ConfigDialog.h
@@ -219,7 +219,6 @@ private:
   QLineEdit *functionArguments;
   QComboBox *defaultPeakShape;
   QSpinBox *findPeaksFWHM, *findPeaksTolerance;
-  QSpinBox *peakRadius;
   QSpinBox *decimals;
   /// mantid options page
   QWidget *mantidOptionsPage;
diff --git a/MantidPlot/src/FitDialog.cpp b/MantidPlot/src/FitDialog.cpp
index 225ae7a19cd01d48428e05622155d3b66fe02a3d..f4cde40d9fef22eeccff0ac10d79abbd005ea55f 100644
--- a/MantidPlot/src/FitDialog.cpp
+++ b/MantidPlot/src/FitDialog.cpp
@@ -65,8 +65,6 @@
 
 #include <qwt_plot_curve.h>
 
-#include "MantidQtAPI/FileDialogHandler.h"
-
 using namespace MantidQt::API;
 
 FitDialog::FitDialog(Graph *g, QWidget *parent, Qt::WFlags fl)
@@ -662,7 +660,7 @@ void FitDialog::saveUserFunction() {
     }
     QString filter = tr("MantidPlot fit model") + " (*.fit);;";
     filter += tr("All files") + " (*)";
-    QString fn = MantidQt::API::FileDialogHandler::getSaveFileName(
+    QString fn = QFileDialog::getSaveFileName(
         app, tr("MantidPlot") + " - " + tr("Save Fit Model As"),
         app->fitModelsPath + "/" + name, filter);
     if (!fn.isEmpty()) {
@@ -1423,7 +1421,7 @@ void FitDialog::saveInitialGuesses() {
     }
     QString filter = tr("MantidPlot fit model") + " (*.fit);;";
     filter += tr("All files") + " (*)";
-    QString fn = MantidQt::API::FileDialogHandler::getSaveFileName(
+    QString fn = QFileDialog::getSaveFileName(
         app, tr("MantidPlot") + " - " + tr("Save Fit Model As"),
         app->fitModelsPath + "/" + d_current_fit->objectName(), filter);
     if (!fn.isEmpty()) {
diff --git a/MantidPlot/src/FunctionCurve.cpp b/MantidPlot/src/FunctionCurve.cpp
index 46ff376e7223b96b31f2a9a393c4f2aa64a93e28..6ce438adc963976b15111b3b48163bf9868342ca 100644
--- a/MantidPlot/src/FunctionCurve.cpp
+++ b/MantidPlot/src/FunctionCurve.cpp
@@ -254,9 +254,10 @@ void FunctionCurve::loadData(int points) {
  * Load the data from a MatrixWorkspace if it is a Mantid-type FunctionCurve.
  * @param ws :: A workspace to load the data from.
  * @param wi :: An index of a histogram with the data.
+ * @param peakRadius :: A peak radius to pass to the domain.
  */
 void FunctionCurve::loadMantidData(Mantid::API::MatrixWorkspace_const_sptr ws,
-                                   size_t wi) {
+                                   size_t wi, int peakRadius) {
   if (!d_variable.isEmpty() || d_formulas.isEmpty() ||
       d_formulas[0] != "Mantid")
     return;
@@ -310,6 +311,9 @@ void FunctionCurve::loadMantidData(Mantid::API::MatrixWorkspace_const_sptr ws,
     f->applyTies();
     Mantid::API::FunctionDomain1DVector domain(X);
     Mantid::API::FunctionValues Y(domain);
+    if (peakRadius > 0) {
+      domain.setPeakRadius(peakRadius);
+    }
     f->function(domain, Y);
 
     setData(&X[0], Y.getPointerToCalculated(0), static_cast<int>(X.size()));
diff --git a/MantidPlot/src/FunctionCurve.h b/MantidPlot/src/FunctionCurve.h
index d0d01b9d2ecffc25bec45b4f3d0e6ab24122cd86..fa19031030d15bfb5ced3b7f2a1f51ad1110954e 100644
--- a/MantidPlot/src/FunctionCurve.h
+++ b/MantidPlot/src/FunctionCurve.h
@@ -84,7 +84,7 @@ public:
   void loadData(int points = 0);
 
   void loadMantidData(boost::shared_ptr<const Mantid::API::MatrixWorkspace> ws,
-                      size_t wi);
+                      size_t wi, int peakRadius = 0);
 
   /// No error bars on this curve: Always return an empty list.
   QList<ErrorBarSettings *> errorBarSettingsList() const override {
diff --git a/MantidPlot/src/Graph.cpp b/MantidPlot/src/Graph.cpp
index 15010d5b5fc86f025f337fdb90fb5fc1034ae284..ffb3cc405c8388063a2d7042fefae749567dded8 100644
--- a/MantidPlot/src/Graph.cpp
+++ b/MantidPlot/src/Graph.cpp
@@ -62,6 +62,7 @@
 #include "Mantid/ErrorBarSettings.h"
 #include "Mantid/MantidMDCurve.h"
 #include "Mantid/MantidMatrixCurve.h"
+#include "MantidKernel/Strings.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidQtAPI/PlotAxis.h"
 #include "MantidQtAPI/QwtRasterDataMD.h"
@@ -3285,6 +3286,20 @@ void Graph::addLegendItem() {
   }
 }
 
+/**
+ * Trim a table name from the legend key.
+ *
+ * Take a string that looks like 'Table-1_run-number' and convert it
+ * to just 'run-number'
+ *
+ * @param key :: the legend key to trim
+ * @return QString containing the trimmed value
+ */
+QString Graph::trimTableNameFromLegendKey(const QString &key) const {
+  int splitPos = key.indexOf("_");
+  return key.mid(splitPos + 1, key.size()).replace('_', '-');
+}
+
 QString Graph::yAxisTitleFromFirstCurve() {
   // I really don't like this...
   if (auto *firstCurve = dynamic_cast<MantidMatrixCurve *>(curve(0))) {
@@ -6036,6 +6051,10 @@ void Graph::loadFromProject(const std::string &lines, ApplicationWindow *app,
       tsv >> tableName >> plotType;
 
       Table *table = app->table(tableName);
+
+      curveValues[1] = trimTableNameFromLegendKey(curveValues[1]);
+      curveValues[2] = trimTableNameFromLegendKey(curveValues[2]);
+
       if (table) {
         PlotCurve *c = NULL;
         if (plotType == GraphOptions::VectXYXY ||
@@ -6180,6 +6199,9 @@ void Graph::loadFromProject(const std::string &lines, ApplicationWindow *app,
       Table *w = app->table(sl[3]);
       Table *errTable = app->table(sl[4]);
       if (w && errTable) {
+        sl[2] = trimTableNameFromLegendKey(sl[2]);
+        sl[3] = trimTableNameFromLegendKey(sl[3]);
+        sl[4] = trimTableNameFromLegendKey(sl[4]);
         addErrorBars(sl[2], sl[3], errTable, sl[4], sl[1].toInt(),
                      sl[5].toDouble(), sl[6].toInt(), QColor(sl[7]),
                      sl[8].toInt(), sl[10].toInt(), sl[9].toInt());
diff --git a/MantidPlot/src/Graph.h b/MantidPlot/src/Graph.h
index e0ef6c981410927b6bfc6e6583f8be237aeb1cb3..dedc4c1609d954c961286c9a6012043a77b0114c 100644
--- a/MantidPlot/src/Graph.h
+++ b/MantidPlot/src/Graph.h
@@ -898,6 +898,8 @@ private:
   void niceLogScales(QwtPlot::Axis axis);
   void deselectCurves();
   void addLegendItem();
+  /// trim a title from a legend key
+  QString trimTableNameFromLegendKey(const QString &key) const;
 
   QString yAxisTitleFromFirstCurve();
 
diff --git a/MantidPlot/src/Graph3D.cpp b/MantidPlot/src/Graph3D.cpp
index 9c9950f09b4642d366b3453c81ef27f80327c31b..cb70c2e1e4872e2285cbe3a54daf4935c14e44d8 100644
--- a/MantidPlot/src/Graph3D.cpp
+++ b/MantidPlot/src/Graph3D.cpp
@@ -44,7 +44,6 @@
 #include <QBitmap>
 #include <QClipboard>
 #include <QCursor>
-#include <QFileDialog>
 #include <QImageWriter>
 #include <QMessageBox>
 #include <QPixmap>
diff --git a/MantidPlot/src/Mantid/AlgorithmDockWidget.cpp b/MantidPlot/src/Mantid/AlgorithmDockWidget.cpp
index a58653032080dfc0b16869e7c7a32b686b36e732..45610917d9e07426ac20a8876d3ba08d402b396a 100644
--- a/MantidPlot/src/Mantid/AlgorithmDockWidget.cpp
+++ b/MantidPlot/src/Mantid/AlgorithmDockWidget.cpp
@@ -1,5 +1,6 @@
 #include "AlgorithmDockWidget.h"
 #include "MantidUI.h"
+#include <iomanip>
 
 //-------------------- AlgorithmDockWidget ----------------------//
 /** Create a QDockWidget containing:
@@ -110,4 +111,4 @@ void AlgorithmDockWidget::hideProgressBar() {
     delete m_progressBar;
     m_progressBar = NULL;
   }
-}
\ No newline at end of file
+}
diff --git a/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp b/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp
index e5eaa086c92877187fbcfa3793dc0a038d99cdfd..da000c1c69f67995d6c1bd4a741484d73289144a 100644
--- a/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp
+++ b/MantidPlot/src/Mantid/AlgorithmHistoryWindow.cpp
@@ -1,22 +1,23 @@
 #include "AlgorithmHistoryWindow.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/Workspace.h"
 
 #include "MantidQtAPI/AlgorithmInputHistory.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 
-#include <QLineEdit>
-#include <QLabel>
-#include <QFileDialog>
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
 #include <QDateTime>
+#include <QDir>
+#include <QFileDialog>
 #include <QFormLayout>
+#include <QLabel>
+#include <QLineEdit>
 #include <QMenu>
-#include <QAction>
 #include <QMessageBox>
-#include <QApplication>
-#include <QClipboard>
-#include <QTextStream>
 #include <QTemporaryFile>
-#include <QDir>
+#include <QTextStream>
 
 #include <numeric>
 #include <fstream>
@@ -391,7 +392,7 @@ void AlgorithmHistoryWindow::writeToScriptFile() {
   } else {
     scriptDir = prevDir;
   }
-  QString filePath = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString filePath = QFileDialog::getSaveFileName(
       this, tr("Save Script As "), scriptDir, tr("Script files (*.py)"));
   // An empty string indicates they clicked cancel
   if (filePath.isEmpty())
diff --git a/MantidPlot/src/Mantid/InputHistory.cpp b/MantidPlot/src/Mantid/InputHistory.cpp
index 94aa62e35c1d7816cb8e2f5fbe14cf7eb823eb80..f3b0b438979cf22992c965e5ee187e3c13e9bca0 100644
--- a/MantidPlot/src/Mantid/InputHistory.cpp
+++ b/MantidPlot/src/Mantid/InputHistory.cpp
@@ -4,6 +4,7 @@
 #include <QSettings>
 #include <QStringList>
 #include <vector>
+#include <iostream>
 
 using namespace Mantid::API;
 using namespace Mantid::Kernel;
diff --git a/MantidPlot/src/Mantid/MantidDock.cpp b/MantidPlot/src/Mantid/MantidDock.cpp
deleted file mode 100644
index 33713e175abfca37148d3b28f9c413d21e6e8719..0000000000000000000000000000000000000000
--- a/MantidPlot/src/Mantid/MantidDock.cpp
+++ /dev/null
@@ -1,1541 +0,0 @@
-#include "MantidDock.h"
-#include "../ApplicationWindow.h"
-#include "../pixmaps.h"
-#include "FlowLayout.h"
-#include "MantidGroupPlotGenerator.h"
-#include "MantidMatrix.h"
-#include "MantidTreeWidget.h"
-#include "MantidTreeWidgetItem.h"
-#include "MantidUI.h"
-#include "MantidWSIndexDialog.h"
-#include "WorkspaceIcons.h"
-
-#include "MantidAPI/IMDEventWorkspace.h"
-#include "MantidAPI/IMDHistoWorkspace.h"
-
-#include "MantidAPI/IPeaksWorkspace.h"
-#include "MantidAPI/MatrixWorkspace.h"
-#include "MantidAPI/WorkspaceGroup.h"
-#include "MantidGeometry/Instrument.h"
-#include <MantidAPI/FileProperty.h>
-#include <MantidKernel/make_unique.h>
-#include <MantidQtAPI/InterfaceManager.h>
-#include <MantidQtMantidWidgets/LineEditWithClear.h>
-
-#include <Poco/Path.h>
-
-#include <QFileDialog>
-#include <QMenu>
-#include <QSignalMapper>
-
-#ifdef MAKE_VATES
-#include "vtkPVDisplayInformation.h"
-#endif
-
-#include <algorithm>
-#include <sstream>
-
-using namespace Mantid::API;
-using namespace Mantid::Kernel;
-using namespace Mantid::Geometry;
-
-namespace {
-/// static logger for dock widget
-Mantid::Kernel::Logger docklog("MantidDockWidget");
-
-WorkspaceIcons WORKSPACE_ICONS = WorkspaceIcons();
-}
-
-MantidDockWidget::MantidDockWidget(MantidUI *mui, ApplicationWindow *parent)
-    : QDockWidget(tr("Workspaces"), parent), m_mantidUI(mui), m_updateCount(0),
-      m_treeUpdating(false),
-      m_ads(Mantid::API::AnalysisDataService::Instance()) {
-  setObjectName(
-      "exploreMantid"); // this is needed for QMainWindow::restoreState()
-  setMinimumHeight(150);
-  setMinimumWidth(200);
-  parent->addDockWidget(Qt::RightDockWidgetArea, this);
-
-  m_appParent = parent;
-
-  QFrame *f = new QFrame(this);
-  setWidget(f);
-
-  m_tree = new MantidTreeWidget(this, m_mantidUI);
-  m_tree->setHeaderLabel("Workspaces");
-
-  FlowLayout *buttonLayout = new FlowLayout();
-  m_loadButton = new QPushButton("Load");
-  m_saveButton = new QPushButton("Save");
-  m_deleteButton = new QPushButton("Delete");
-  m_groupButton = new QPushButton("Group");
-  m_sortButton = new QPushButton("Sort");
-
-  if (m_groupButton)
-    m_groupButton->setEnabled(false);
-  m_deleteButton->setEnabled(false);
-  m_saveButton->setEnabled(false);
-
-  buttonLayout->addWidget(m_loadButton);
-  buttonLayout->addWidget(m_deleteButton);
-  buttonLayout->addWidget(m_groupButton);
-  buttonLayout->addWidget(m_sortButton);
-  buttonLayout->addWidget(m_saveButton);
-
-  m_workspaceFilter = new MantidQt::MantidWidgets::LineEditWithClear();
-  m_workspaceFilter->setPlaceholderText("Filter Workspaces");
-  m_workspaceFilter->setToolTip("Type here to filter the workspaces");
-
-  connect(m_workspaceFilter, SIGNAL(textChanged(const QString &)), this,
-          SLOT(filterWorkspaceTree(const QString &)));
-
-  QVBoxLayout *layout = new QVBoxLayout();
-  f->setLayout(layout);
-  layout->setSpacing(0);
-  layout->setMargin(0);
-  layout->addLayout(buttonLayout);
-  layout->addWidget(m_workspaceFilter);
-  layout->addWidget(m_tree);
-
-  m_loadMenu = new QMenu(this);
-  m_saveMenu = new QMenu(this);
-
-  QAction *loadFileAction = new QAction("File", this);
-  QAction *liveDataAction = new QAction("Live Data", this);
-  m_loadMapper = new QSignalMapper(this);
-  m_loadMapper->setMapping(liveDataAction, "StartLiveData");
-  m_loadMapper->setMapping(loadFileAction, "Load");
-  connect(liveDataAction, SIGNAL(triggered()), m_loadMapper, SLOT(map()));
-  connect(loadFileAction, SIGNAL(triggered()), m_loadMapper, SLOT(map()));
-  connect(m_loadMapper, SIGNAL(mapped(const QString &)), m_mantidUI,
-          SLOT(showAlgorithmDialog(const QString &)));
-  m_loadMenu->addAction(loadFileAction);
-  m_loadMenu->addAction(liveDataAction);
-  m_loadButton->setMenu(m_loadMenu);
-
-  // Dialog box used for user to specify folder to save multiple workspaces into
-  m_saveFolderDialog = new QFileDialog;
-  m_saveFolderDialog->setFileMode(QFileDialog::DirectoryOnly);
-  m_saveFolderDialog->setOption(QFileDialog::ShowDirsOnly);
-
-  // SET UP SORT
-  createSortMenuActions();
-  createWorkspaceMenuActions();
-
-  connect(m_deleteButton, SIGNAL(clicked()), this, SLOT(deleteWorkspaces()));
-  connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
-          SLOT(clickedWorkspace(QTreeWidgetItem *, int)));
-  connect(m_tree, SIGNAL(itemSelectionChanged()), this,
-          SLOT(workspaceSelected()));
-  connect(m_groupButton, SIGNAL(clicked()), this, SLOT(groupingButtonClick()));
-
-  m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
-  connect(m_tree, SIGNAL(customContextMenuRequested(const QPoint &)), this,
-          SLOT(popupMenu(const QPoint &)));
-
-  // call this slot directly after the signal is received. just increment the
-  // update counter
-  connect(m_mantidUI, SIGNAL(workspace_renamed(QString, QString)), this,
-          SLOT(recordWorkspaceRename(QString, QString)), Qt::DirectConnection);
-  // call this slot directly after the signal is received. just increment the
-  // update counter
-  connect(m_mantidUI, SIGNAL(ADS_updated()), this, SLOT(incrementUpdateCount()),
-          Qt::DirectConnection);
-  // this slot is called when the GUI thread is free. decrement the counter. do
-  // nothing until the counter == 0
-  connect(m_mantidUI, SIGNAL(ADS_updated()), this,
-          SLOT(updateTreeOnADSUpdate()), Qt::QueuedConnection);
-
-  connect(m_mantidUI, SIGNAL(workspaces_cleared()), m_tree, SLOT(clear()),
-          Qt::QueuedConnection);
-  connect(m_tree, SIGNAL(itemSelectionChanged()), this,
-          SLOT(treeSelectionChanged()));
-  connect(m_tree, SIGNAL(itemExpanded(QTreeWidgetItem *)), this,
-          SLOT(populateChildData(QTreeWidgetItem *)));
-  m_tree->setDragEnabled(true);
-}
-
-MantidDockWidget::~MantidDockWidget() {}
-
-/** Returns the name of the selected workspace
-*  (the first one if more than one is selected)
-*/
-QString MantidDockWidget::getSelectedWorkspaceName() const {
-  QList<QTreeWidgetItem *> items = m_tree->selectedItems();
-  QString str("");
-  if (!items.empty()) {
-    QTreeWidgetItem *item = items[0];
-    if (item)
-      str = item->text(0);
-  }
-  return str;
-}
-
-/// Returns a pointer to the selected workspace (the first if multiple
-/// workspaces selected)
-Mantid::API::Workspace_sptr MantidDockWidget::getSelectedWorkspace() const {
-  QString workspaceName = getSelectedWorkspaceName();
-  if (m_ads.doesExist(workspaceName.toStdString())) {
-    return m_ads.retrieve(workspaceName.toStdString());
-  } else {
-    return Mantid::API::Workspace_sptr();
-  }
-}
-
-/**
-* Create the action items associated with the dock
-*/
-void MantidDockWidget::createWorkspaceMenuActions() {
-  m_showData = new QAction(tr("Show Data"), this);
-  connect(m_showData, SIGNAL(triggered()), m_mantidUI, SLOT(importWorkspace()));
-
-  m_showInst = new QAction(tr("Show Instrument"), this);
-  connect(m_showInst, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showMantidInstrumentSelected()));
-
-  m_plotSpec = new QAction(tr("Plot Spectrum..."), this);
-  connect(m_plotSpec, SIGNAL(triggered()), this, SLOT(plotSpectra()));
-
-  m_plotSpecErr = new QAction(tr("Plot Spectrum with Errors..."), this);
-  connect(m_plotSpecErr, SIGNAL(triggered()), this, SLOT(plotSpectraErr()));
-
-  m_colorFill = new QAction(tr("Color Fill Plot"), this);
-  connect(m_colorFill, SIGNAL(triggered()), this, SLOT(drawColorFillPlot()));
-
-  m_showDetectors = new QAction(tr("Show Detectors"), this);
-  connect(m_showDetectors, SIGNAL(triggered()), this,
-          SLOT(showDetectorTable()));
-
-  m_showBoxData = new QAction(tr("Show Box Data Table"), this);
-  connect(m_showBoxData, SIGNAL(triggered()), m_mantidUI,
-          SLOT(importBoxDataTable()));
-
-  m_showVatesGui = new QAction(tr("Show Vates Simple Interface"), this);
-  {
-    QIcon icon;
-    icon.addFile(
-        QString::fromUtf8(":/VatesSimpleGuiViewWidgets/icons/pvIcon.png"),
-        QSize(), QIcon::Normal, QIcon::Off);
-    m_showVatesGui->setIcon(icon);
-  }
-  connect(m_showVatesGui, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showVatesSimpleInterface()));
-
-  m_showMDPlot = new QAction(tr("Plot MD"), this);
-  connect(m_showMDPlot, SIGNAL(triggered()), m_mantidUI, SLOT(showMDPlot()));
-
-  m_showListData = new QAction(tr("List Data"), this);
-  connect(m_showListData, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showListData()));
-
-  m_showSpectrumViewer = new QAction(tr("Show Spectrum Viewer"), this);
-  connect(m_showSpectrumViewer, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showSpectrumViewer()));
-
-  m_showSliceViewer = new QAction(tr("Show Slice Viewer"), this);
-  {
-    QIcon icon;
-    icon.addFile(
-        QString::fromUtf8(":/SliceViewer/icons/SliceViewerWindow_icon.png"),
-        QSize(), QIcon::Normal, QIcon::Off);
-    m_showSliceViewer->setIcon(icon);
-  }
-  connect(m_showSliceViewer, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showSliceViewer()));
-
-  m_showLogs = new QAction(tr("Sample Logs..."), this);
-  connect(m_showLogs, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showLogFileWindow()));
-
-  m_showSampleMaterial = new QAction(tr("Sample Material..."), this);
-  connect(m_showSampleMaterial, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showSampleMaterialWindow()));
-
-  m_showHist = new QAction(tr("Show History"), this);
-  connect(m_showHist, SIGNAL(triggered()), m_mantidUI,
-          SLOT(showAlgorithmHistory()));
-
-  m_saveNexus = new QAction(tr("Save Nexus"), this);
-  connect(m_saveNexus, SIGNAL(triggered()), m_mantidUI,
-          SLOT(saveNexusWorkspace()));
-
-  m_rename = new QAction(tr("Rename"), this);
-  connect(m_rename, SIGNAL(triggered()), this, SLOT(renameWorkspace()));
-
-  m_delete = new QAction(tr("Delete"), this);
-  connect(m_delete, SIGNAL(triggered()), this, SLOT(deleteWorkspaces()));
-
-  m_showTransposed = new QAction(tr("Show Transposed"), this);
-  connect(m_showTransposed, SIGNAL(triggered()), m_mantidUI,
-          SLOT(importTransposed()));
-
-  m_convertToMatrixWorkspace =
-      new QAction(tr("Convert to MatrixWorkspace"), this);
-  m_convertToMatrixWorkspace->setIcon(QIcon(getQPixmap("mantid_matrix_xpm")));
-  connect(m_convertToMatrixWorkspace, SIGNAL(triggered()), this,
-          SLOT(convertToMatrixWorkspace()));
-
-  m_convertMDHistoToMatrixWorkspace =
-      new QAction(tr("Convert to MatrixWorkspace"), this);
-  m_convertMDHistoToMatrixWorkspace->setIcon(
-      QIcon(getQPixmap("mantid_matrix_xpm")));
-  connect(m_convertMDHistoToMatrixWorkspace, SIGNAL(triggered()), this,
-          SLOT(convertMDHistoToMatrixWorkspace()));
-
-  m_clearUB = new QAction(tr("Clear UB Matrix"), this);
-  connect(m_clearUB, SIGNAL(triggered()), this, SLOT(clearUB()));
-
-  m_plotSurface = new QAction(tr("Plot Surface from Group"), this);
-  connect(m_plotSurface, SIGNAL(triggered()), this, SLOT(plotSurface()));
-
-  m_plotContour = new QAction(tr("Plot Contour from Group"), this);
-  connect(m_plotContour, SIGNAL(triggered()), this, SLOT(plotContour()));
-}
-
-/**
-* Create actions for sorting.
-*/
-void MantidDockWidget::createSortMenuActions() {
-  chooseByName();
-  m_sortMenu = new QMenu(this);
-
-  QAction *m_ascendingSortAction = new QAction("Ascending", this);
-  QAction *m_descendingSortAction = new QAction("Descending", this);
-  QAction *m_byNameChoice = new QAction("Name", this);
-  QAction *m_byLastModifiedChoice = new QAction("Last Modified", this);
-
-  m_ascendingSortAction->setCheckable(true);
-  m_ascendingSortAction->setEnabled(true);
-
-  m_descendingSortAction->setCheckable(true);
-  m_descendingSortAction->setEnabled(true);
-
-  QActionGroup *sortDirectionGroup = new QActionGroup(m_sortMenu);
-  sortDirectionGroup->addAction(m_ascendingSortAction);
-  sortDirectionGroup->addAction(m_descendingSortAction);
-  sortDirectionGroup->setExclusive(true);
-  m_ascendingSortAction->setChecked(true);
-
-  m_byNameChoice->setCheckable(true);
-  m_byNameChoice->setEnabled(true);
-
-  m_byLastModifiedChoice->setCheckable(true);
-  m_byLastModifiedChoice->setEnabled(true);
-
-  m_sortChoiceGroup = new QActionGroup(m_sortMenu);
-  m_sortChoiceGroup->addAction(m_byNameChoice);
-  m_sortChoiceGroup->addAction(m_byLastModifiedChoice);
-  m_sortChoiceGroup->setExclusive(true);
-  m_byNameChoice->setChecked(true);
-
-  connect(m_ascendingSortAction, SIGNAL(triggered()), this,
-          SLOT(sortAscending()));
-  connect(m_descendingSortAction, SIGNAL(triggered()), this,
-          SLOT(sortDescending()));
-  connect(m_byNameChoice, SIGNAL(triggered()), this, SLOT(chooseByName()));
-  connect(m_byLastModifiedChoice, SIGNAL(triggered()), this,
-          SLOT(chooseByLastModified()));
-
-  m_sortMenu->addActions(sortDirectionGroup->actions());
-  m_sortMenu->addSeparator();
-  m_sortMenu->addActions(m_sortChoiceGroup->actions());
-  m_sortButton->setMenu(m_sortMenu);
-}
-
-/**
-* When an item is expanded, populate the child data for this item
-* @param item :: The item being expanded
-*/
-void MantidDockWidget::populateChildData(QTreeWidgetItem *item) {
-  QVariant userData = item->data(0, Qt::UserRole);
-  if (userData.isNull())
-    return;
-
-  // Clear it first
-  while (item->childCount() > 0) {
-    auto *widgetItem = item->takeChild(0);
-    delete widgetItem;
-  }
-
-  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 *node = addTreeEntry(std::make_pair(ws->name(), ws), item);
-      excludeItemFromSort(node);
-      if (shouldBeSelected(node->text(0)))
-        node->setSelected(true);
-    }
-  } else {
-    QString details;
-    try {
-      details = workspace->toString().c_str();
-    } catch (std::runtime_error &e) {
-      details = QString("Error: %1").arg(e.what());
-    }
-    QStringList rows =
-        details.split(QLatin1Char('\n'), QString::SkipEmptyParts);
-    rows.append(QString("Memory used: ") +
-                workspace->getMemorySizeAsStr().c_str());
-
-    auto iend = rows.constEnd();
-    for (auto itr = rows.constBegin(); itr != iend; ++itr) {
-      MantidTreeWidgetItem *data =
-          new MantidTreeWidgetItem(QStringList(*itr), m_tree);
-      data->setFlags(Qt::NoItemFlags);
-      excludeItemFromSort(data);
-      item->addChild(data);
-    }
-  }
-}
-
-/**
-* Set tree item's icon based on the ID of the workspace.
-* @param item :: A workspace tree item.
-* @param wsID :: An icon type code.
-*/
-void MantidDockWidget::setItemIcon(QTreeWidgetItem *item,
-                                   const std::string &wsID) {
-  try {
-    item->setIcon(0, QIcon(WORKSPACE_ICONS.getIcon(wsID)));
-  } catch (std::runtime_error &) {
-    docklog.warning() << "Cannot find icon for workspace ID '" << wsID << "'\n";
-  }
-}
-
-void MantidDockWidget::updateTreeOnADSUpdate() {
-  // do not update until the counter is zero
-  if (m_updateCount.deref())
-    return;
-  updateTree();
-}
-
-/**
-* Update the workspace tree to match the current state of the ADS.
-* It is important that the workspace tree is modified only by this method.
-*/
-void MantidDockWidget::updateTree() {
-  // find all expanded top-level entries
-  QStringList expanded;
-  int n = m_tree->topLevelItemCount();
-  for (int i = 0; i < n; ++i) {
-    auto item = m_tree->topLevelItem(i);
-    if (item->isExpanded()) {
-      expanded << item->text(0);
-    }
-  }
-
-  // create a new tree
-  setTreeUpdating(true);
-  populateTopLevel(m_ads.topLevelItems(), expanded);
-  setTreeUpdating(false);
-
-  // Re-sort
-  m_tree->sort();
-}
-
-/**
-* Slot to be connected directly to ADS_updated signal. Increase m_updateCount
-* and return.
-*/
-void MantidDockWidget::incrementUpdateCount() { m_updateCount.ref(); }
-
-/**
-* Save the old and the new name in m_renameMap. This is needed to restore
-* selection
-*   of the renamed workspace (if it was selected before renaming).
-* @param old_name :: Old name of a renamed workspace.
-* @param new_name :: New name of a renamed workspace.
-*/
-void MantidDockWidget::recordWorkspaceRename(QString old_name,
-                                             QString new_name) {
-  // check if old_name has been recently a new name
-  QList<QString> oldNames = m_renameMap.keys(old_name);
-  // non-empty list of oldNames become new_name
-  if (!oldNames.isEmpty()) {
-    foreach (QString name, oldNames) { m_renameMap[name] = new_name; }
-  } else {
-    // record a new rename pair
-    m_renameMap[old_name] = new_name;
-  }
-}
-
-/**
-* Flips the flag indicating whether a tree update is in progress. Actions such
-* as sorting
-* are disabled while an update is in progress.
-* @param state The required state for the flag
-*/
-void MantidDockWidget::setTreeUpdating(const bool state) {
-  m_treeUpdating = state;
-}
-
-/**
-* Clears the tree and re-populates it with the given top level items
-* @param topLevelItems The map of names to workspaces
-* @param expanded Names of items who should expanded after being populated
-*/
-void MantidDockWidget::populateTopLevel(
-    const std::map<std::string, Mantid::API::Workspace_sptr> &topLevelItems,
-    const QStringList &expanded) {
-  // collect names of selected workspaces
-  QList<QTreeWidgetItem *> selected = m_tree->selectedItems();
-  m_selectedNames.clear(); // just in case
-  foreach (QTreeWidgetItem *item, selected) {
-    m_selectedNames << item->text(0);
-  }
-
-  // populate the tree from scratch
-  m_tree->clear();
-  auto iend = topLevelItems.end();
-  for (auto it = topLevelItems.begin(); it != iend; ++it) {
-    auto *node = addTreeEntry(*it);
-    QString name = node->text(0);
-    if (expanded.contains(name))
-      node->setExpanded(true);
-    // see if item must be selected
-    if (shouldBeSelected(name))
-      node->setSelected(true);
-  }
-  m_selectedNames.clear();
-  m_renameMap.clear();
-
-  // apply any filtering
-  filterWorkspaceTree(m_workspaceFilter->text());
-}
-
-/**
-* Adds a node for the given named item, including a single child ID item to make
-* each node have a expandable button
-* and allowing plotting to work from non-expanded items
-* @param item A name/workspace pair to add.
-* @param parent If not null then add the new items as a child of the given item
-*/
-MantidTreeWidgetItem *MantidDockWidget::addTreeEntry(
-    const std::pair<std::string, Mantid::API::Workspace_sptr> &item,
-    QTreeWidgetItem *parent) {
-  MantidTreeWidgetItem *node =
-      new MantidTreeWidgetItem(QStringList(item.first.c_str()), m_tree);
-  node->setData(0, Qt::UserRole, QVariant::fromValue(item.second));
-
-  // A a child ID item so that it becomes expandable. Using the correct ID is
-  // needed when plotting from non-expanded groups.
-  const std::string wsID = item.second->id();
-  MantidTreeWidgetItem *idNode =
-      new MantidTreeWidgetItem(QStringList(wsID.c_str()), m_tree);
-  idNode->setFlags(Qt::NoItemFlags);
-  node->addChild(idNode);
-  setItemIcon(node, wsID);
-
-  if (parent) {
-    parent->addChild(node);
-  } else {
-    m_tree->addTopLevelItem(node);
-  }
-  return node;
-}
-
-/**
-* Check if a workspace should be selected after dock update.
-* @param name :: Name of a workspace to check.
-*/
-bool MantidDockWidget::shouldBeSelected(QString name) const {
-  QStringList renamed = m_renameMap.keys(name);
-  if (!renamed.isEmpty()) {
-    foreach (QString oldName, renamed) {
-      if (m_selectedNames.contains(oldName)) {
-        return true;
-      }
-    }
-  } else if (m_selectedNames.contains(name)) {
-    return true;
-  }
-  return false;
-}
-
-/**
-* Add the actions that are appropriate for a MatrixWorkspace
-* @param menu :: The menu to store the items
-* @param matrixWS :: The workspace related to the menu
-*/
-void MantidDockWidget::addMatrixWorkspaceMenuItems(
-    QMenu *menu,
-    const Mantid::API::MatrixWorkspace_const_sptr &matrixWS) const {
-  // Add all options except plot of we only have 1 value
-  menu->addAction(m_showData);
-  menu->addAction(m_showInst);
-  // Disable the 'show instrument' option if a workspace doesn't have an
-  // instrument attached
-  m_showInst->setEnabled(matrixWS->getInstrument() &&
-                         !matrixWS->getInstrument()->getName().empty());
-  menu->addSeparator();
-  menu->addAction(m_plotSpec);
-  menu->addAction(m_plotSpecErr);
-
-  // Don't plot a spectrum if only one X value
-  m_plotSpec->setEnabled(matrixWS->blocksize() > 1);
-  m_plotSpecErr->setEnabled(matrixWS->blocksize() > 1);
-
-  menu->addAction(m_showSpectrumViewer); // The 2D spectrum viewer
-
-  menu->addAction(m_colorFill);
-  // Show the color fill plot if you have more than one histogram
-  m_colorFill->setEnabled(
-      (matrixWS->axes() > 1 && matrixWS->getNumberHistograms() > 1));
-  menu->addAction(m_showSliceViewer); // The 2D slice viewer
-  menu->addSeparator();
-  menu->addAction(m_showDetectors);
-  menu->addAction(m_showLogs);
-  menu->addAction(m_showSampleMaterial);
-  menu->addAction(m_showHist);
-  menu->addAction(m_saveNexus);
-}
-
-/**
-* Add the actions that are appropriate for a MDEventWorkspace
-* @param menu :: The menu to store the items
-* @param WS :: The workspace related to the menu
-*/
-void MantidDockWidget::addMDEventWorkspaceMenuItems(
-    QMenu *menu, const Mantid::API::IMDEventWorkspace_const_sptr &WS) const {
-  Q_UNUSED(WS);
-
-  // menu->addAction(m_showBoxData); // Show MD Box data (for debugging only)
-  menu->addAction(m_showVatesGui); // Show the Vates simple interface
-  if (!MantidQt::API::InterfaceManager::hasVatesLibraries()) {
-    m_showVatesGui->setEnabled(false);
-#ifdef MAKE_VATES
-  } else if (!vtkPVDisplayInformation::SupportsOpenGLLocally()) {
-    m_showVatesGui->setEnabled(false);
-#endif
-  } else {
-    std::size_t nDim = WS->getNonIntegratedDimensions().size();
-    m_showVatesGui->setEnabled(nDim >= 3 && nDim < 5);
-  }
-  menu->addAction(m_showSliceViewer); // The 2D slice viewer
-  menu->addAction(m_showHist);        // Algorithm history
-  menu->addAction(m_showListData);    // Show data in table
-  menu->addAction(m_showLogs);
-}
-
-void MantidDockWidget::addMDHistoWorkspaceMenuItems(
-    QMenu *menu, const Mantid::API::IMDWorkspace_const_sptr &WS) const {
-  Q_UNUSED(WS);
-  menu->addAction(m_showHist);     // Algorithm history
-  menu->addAction(m_showVatesGui); // Show the Vates simple interface
-  if (!MantidQt::API::InterfaceManager::hasVatesLibraries()) {
-    m_showVatesGui->setEnabled(false);
-#ifdef MAKE_VATES
-  } else if (!vtkPVDisplayInformation::SupportsOpenGLLocally()) {
-    m_showVatesGui->setEnabled(false);
-#endif
-  } else {
-    std::size_t nDim = WS->getNonIntegratedDimensions().size();
-    m_showVatesGui->setEnabled(nDim >= 3 && nDim < 5);
-  }
-  menu->addAction(m_showSliceViewer); // The 2D slice viewer
-  menu->addAction(m_showMDPlot);      // A plot of intensity vs bins
-  menu->addAction(m_showListData);    // Show data in table
-  menu->addAction(m_convertMDHistoToMatrixWorkspace);
-  menu->addAction(m_showLogs);
-}
-
-/** Add the actions that are appropriate for a PeaksWorkspace
-* @param menu :: The menu to store the items
-* @param WS :: The workspace related to the menu
-*/
-void MantidDockWidget::addPeaksWorkspaceMenuItems(
-    QMenu *menu, const Mantid::API::IPeaksWorkspace_const_sptr &WS) const {
-  Q_UNUSED(WS);
-  menu->addAction(m_showData);
-  menu->addSeparator();
-  menu->addAction(m_showDetectors);
-  menu->addAction(m_showHist);
-}
-
-/**
-* Add the actions that are appropriate for a WorkspaceGroup
-* @param menu :: The menu to store the items
-* @param groupWS :: [input] Workspace group related to the menu
-*/
-void MantidDockWidget::addWorkspaceGroupMenuItems(
-    QMenu *menu, const WorkspaceGroup_const_sptr &groupWS) const {
-  m_plotSpec->setEnabled(true);
-  menu->addAction(m_plotSpec);
-  m_plotSpecErr->setEnabled(true);
-  menu->addAction(m_plotSpecErr);
-  menu->addAction(m_colorFill);
-  m_colorFill->setEnabled(true);
-
-  // If appropriate, add "plot surface" and "plot contour" options
-  // Only add these if:
-  // - there are >2 workspaces in group
-  // - all are MatrixWorkspaces (otherwise they can't be plotted)
-  // - only one group is selected
-  if (m_tree->selectedItems().size() == 1) {
-    if (groupWS && groupWS->getNumberOfEntries() > 2) {
-      if (MantidGroupPlotGenerator::groupIsAllMatrixWorkspaces(groupWS)) {
-        menu->addAction(m_plotSurface);
-        m_plotSurface->setEnabled(true);
-        menu->addAction(m_plotContour);
-        m_plotContour->setEnabled(true);
-      }
-    }
-  }
-
-  menu->addSeparator();
-  menu->addAction(m_saveNexus);
-}
-
-/**
-* Add the actions that are appropriate for a MatrixWorkspace
-* @param menu :: The menu to store the items
-*/
-void MantidDockWidget::addTableWorkspaceMenuItems(QMenu *menu) const {
-  menu->addAction(m_showData);
-  menu->addAction(m_showTransposed);
-  menu->addAction(m_showHist);
-  menu->addAction(m_saveNexus);
-  menu->addAction(m_convertToMatrixWorkspace);
-}
-
-/**
-* Add menu for clearing workspace items.
-* @param menu : Parent menu.
-* @param wsName : Name of the selected workspace.
-*/
-void MantidDockWidget::addClearMenuItems(QMenu *menu, const QString &wsName) {
-  QMenu *clearMenu = new QMenu(tr("Clear Options"), this);
-
-  m_clearUB->setEnabled(m_mantidUI->hasUB(wsName));
-
-  clearMenu->addAction(m_clearUB);
-  menu->addMenu(clearMenu);
-}
-
-/**
-* Filter workspaces based on the string provided
-* @param text : the string to filter on.
-*/
-void MantidDockWidget::filterWorkspaceTree(const QString &text) {
-  const QString filterText = text.trimmed();
-  QRegExp filterRegEx(filterText, Qt::CaseInsensitive);
-
-  // show all items
-  QTreeWidgetItemIterator it(m_tree);
-  while (*it) {
-    (*it)->setHidden(false);
-    ++it;
-  }
-
-  int hiddenCount = 0;
-  QList<QTreeWidgetItem *> visibleGroups;
-  if (!filterText.isEmpty()) {
-
-    // Loop over everything (currently loaded) and top level
-    // find out what is already expanded
-    QStringList expanded;
-    int n = m_tree->topLevelItemCount();
-    for (int i = 0; i < n; ++i) {
-      auto item = m_tree->topLevelItem(i);
-      if (item->isExpanded()) {
-        expanded << item->text(0);
-      } else {
-        // expand everything that is at the top level (as we lazy load this is
-        // required)
-        item->setExpanded(true);
-      }
-    }
-
-    // filter based on the string
-    QTreeWidgetItemIterator it(m_tree, QTreeWidgetItemIterator::All);
-    while (*it) {
-      QTreeWidgetItem *item = (*it);
-      QVariant userData = item->data(0, Qt::UserRole);
-
-      if (!userData.isNull()) {
-        Workspace_sptr workspace = userData.value<Workspace_sptr>();
-        if (workspace) {
-          // I am a workspace
-          if (item->text(0).contains(filterRegEx)) {
-            // my name does match the filter
-            if (auto group =
-                    boost::dynamic_pointer_cast<WorkspaceGroup>(workspace)) {
-              // I am a group, I will want my children to be visible
-              // but I cannot do that until this iterator has finished
-              // store this pointer in a list for processing later
-              visibleGroups.append(item);
-              item->setHidden(false);
-            }
-
-            if (item->parent() == NULL) {
-              // No parent, I am a top level workspace - show me
-              item->setHidden(false);
-            } else {
-              // I am a child workspace of a group
-              // I match, so I want my parent to remain visible as well.
-              item->setHidden(false);
-              if (item->parent()->isHidden()) {
-                // I was previously hidden, show me and set to be expanded
-                --hiddenCount;
-                item->parent()->setHidden(false);
-                expanded << item->parent()->text(0);
-              }
-            }
-          } else {
-            // my name does not match the filter - hide me
-            item->setHidden(true);
-            ++hiddenCount;
-          }
-        }
-      }
-      ++it;
-    }
-
-    // make children of visible groups visible
-    for (auto itGroup = visibleGroups.begin(); itGroup != visibleGroups.end();
-         ++itGroup) {
-      QTreeWidgetItem *group = (*itGroup);
-      for (int i = 0; i < group->childCount(); i++) {
-        QTreeWidgetItem *child = group->child(i);
-        if (child->isHidden()) {
-          // I was previously hidden, show me
-          --hiddenCount;
-          child->setHidden(false);
-        }
-      }
-    }
-
-    // set the expanded state
-    for (int i = 0; i < n; ++i) {
-      auto item = m_tree->topLevelItem(i);
-      item->setExpanded(expanded.contains(item->text(0)));
-    }
-  }
-
-  // display a message if items are hidden
-  if (hiddenCount > 0) {
-    QString headerString =
-        QString("Workspaces (%1 filtered)").arg(QString::number(hiddenCount));
-    m_tree->headerItem()->setText(0, headerString);
-  } else {
-    m_tree->headerItem()->setText(0, "Workspaces");
-  }
-}
-
-void MantidDockWidget::clickedWorkspace(QTreeWidgetItem *item, int) {
-  Q_UNUSED(item);
-}
-
-void MantidDockWidget::workspaceSelected() {
-  QList<QTreeWidgetItem *> selectedItems = m_tree->selectedItems();
-  if (selectedItems.isEmpty())
-    return;
-
-  // If there are multiple workspaces selected group and save as Nexus
-  if (selectedItems.length() > 1) {
-    connect(m_saveButton, SIGNAL(clicked()), this, SLOT(saveWorkspaceGroup()));
-
-    // Don't display as a group
-    m_saveButton->setMenu(NULL);
-  } else {
-    // Don't run the save group function when clicked
-    disconnect(m_saveButton, SIGNAL(clicked()), this,
-               SLOT(saveWorkspaceGroup()));
-
-    // Remove all existing save algorithms from list
-    m_saveMenu->clear();
-
-    // Add some save algorithms
-    addSaveMenuOption("SaveNexus", "Nexus");
-    addSaveMenuOption("SaveAscii", "ASCII");
-    addSaveMenuOption("SaveAscii.1", "ASCII v1");
-
-    // Set the button to show the menu
-    m_saveButton->setMenu(m_saveMenu);
-  }
-
-  QString wsName = selectedItems[0]->text(0);
-  if (m_ads.doesExist(wsName.toStdString())) {
-    m_mantidUI->enableSaveNexus(wsName);
-  }
-}
-
-/**
- * Adds an algorithm to the save menu.
- *
- * @param algorithmString Algorithm string in format ALGO_NAME.VERSION or
- * ALGO_NAME
- * @param menuEntryName Text to be shown in menu
- */
-void MantidDockWidget::addSaveMenuOption(QString algorithmString,
-                                         QString menuEntryName) {
-  // Default to algo string if no entry name given
-  if (menuEntryName.isEmpty())
-    menuEntryName = algorithmString;
-
-  // Create the action and add data
-  QAction *saveAction = new QAction(menuEntryName, this);
-  saveAction->setData(QVariant(algorithmString));
-
-  // Connect the tigger slot to show algorithm dialog
-  connect(saveAction, SIGNAL(triggered()), this,
-          SLOT(handleShowSaveAlgorithm()));
-
-  // Add it to the menu
-  m_saveMenu->addAction(saveAction);
-}
-
-/**
- * Save all selected workspaces
- */
-void MantidDockWidget::saveWorkspaceGroup() {
-  QList<QTreeWidgetItem *> items = m_tree->selectedItems();
-  if (items.size() < 2)
-    return;
-
-  m_saveFolderDialog->setWindowTitle("Select save folder");
-  m_saveFolderDialog->setLabelText(QFileDialog::Accept, "Select");
-  m_saveFolderDialog->open(this, SLOT(saveWorkspacesToFolder(const QString &)));
-}
-
-/**
- * Handler for the directory browser being closed when selecting save on
- * multiple workspaces
- *
- * @param folder Path to folder to save workspaces in
- */
-void MantidDockWidget::saveWorkspacesToFolder(const QString &folder) {
-  QList<QTreeWidgetItem *> items = m_tree->selectedItems();
-
-  // Loop through multiple items selected from the mantid tree
-  QList<QTreeWidgetItem *>::iterator itr = items.begin();
-  for (itr = items.begin(); itr != items.end(); ++itr) {
-    QString workspaceName = (*itr)->text(0);
-    QString filename = folder + "/" + workspaceName + ".nxs";
-
-    IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create("SaveNexus");
-    saveAlg->initialize();
-    try {
-      saveAlg->setProperty("InputWorkspace", workspaceName.toStdString());
-      saveAlg->setProperty("Filename", filename.toStdString());
-      saveAlg->execute();
-    } catch (std::runtime_error &rte) {
-      docklog.error() << "Error saving workspace "
-                      << workspaceName.toStdString() << ": " << rte.what()
-                      << '\n';
-    }
-  }
-}
-
-/**
- * Handles a save algorithm being triggered by the Save menu.
- *
- * To select a specific algorithm add a QString to the data of the QAction
- * in the form ALGORITHM_NAME.VERSION or just ALGORITHM_NAME to use the
- * most recent version.
- */
-void MantidDockWidget::handleShowSaveAlgorithm() {
-  const QAction *sendingAction = dynamic_cast<QAction *>(sender());
-
-  if (sendingAction) {
-    const auto inputWorkspace = getSelectedWorkspace();
-    const QString wsName = QString::fromStdString(inputWorkspace->getName());
-    const QVariant data = sendingAction->data();
-
-    if (data.canConvert<QString>()) {
-      QString algorithmName;
-      int version = -1;
-
-      // Check if workspace is MD, this is the same check used in
-      // SaveNexusProcessed.cpp in the doExec()
-      if (bool(boost::dynamic_pointer_cast<const IMDEventWorkspace>(
-              inputWorkspace)) ||
-          bool(boost::dynamic_pointer_cast<const IMDHistoWorkspace>(
-              inputWorkspace))) {
-        // This will also be executed if the user clicks Save to ASCII or ASCII
-        // v1, therefore overwriting their choice and running
-        // SaveMD. SaveASCII doesn't support MD Workspaces, but if an issue,
-        // move the MD check to case 1: below
-        algorithmName = "SaveMD";
-
-      } else {
-        QStringList splitData = data.toString().split(".");
-        switch (splitData.length()) {
-        case 2:
-          version = splitData[1].toInt();
-        // intentional fall through to get algorithm name
-        case 1:
-          algorithmName = splitData[0];
-          break;
-        default:
-          m_mantidUI->saveNexusWorkspace();
-          return;
-        }
-      }
-      QHash<QString, QString> presets;
-      if (!wsName.isEmpty())
-        presets["InputWorkspace"] = wsName;
-
-      m_mantidUI->showAlgorithmDialog(algorithmName, presets, NULL, version);
-      return;
-    }
-  }
-
-  // If we can't get the type of algorithm this should be we can always fall
-  // back on Nexus
-  m_mantidUI->saveNexusWorkspace();
-}
-
-/**
-deleteWorkspaces
-*/
-void MantidDockWidget::deleteWorkspaces() {
-  QList<QTreeWidgetItem *> items = m_tree->selectedItems();
-  MantidMatrix *m =
-      dynamic_cast<MantidMatrix *>(m_mantidUI->appWindow()->activeWindow());
-
-  bool deleteExplorer = false;
-  bool deleteActive = false;
-
-  if ((m_deleteButton->hasFocus() || m_tree->hasFocus()) && !items.empty()) {
-    deleteExplorer = true;
-  }
-  if ((m && (strcmp(m->metaObject()->className(), "MantidMatrix") == 0)) &&
-      (!m->workspaceName().isEmpty() &&
-       m_ads.doesExist(m->workspaceName().toStdString()))) {
-    deleteActive = true;
-  }
-
-  if (deleteActive || deleteExplorer) {
-    QMessageBox::StandardButton reply;
-
-    if (m_appParent->isDeleteWorkspacePromptEnabled()) {
-      reply = QMessageBox::question(
-          this, "Delete Workspaces",
-          "Are you sure you want to delete the selected Workspaces?\n\nThis "
-          "prompt can be disabled from:\nPreferences->General->Confirmations",
-          QMessageBox::Yes | QMessageBox::No);
-    } else {
-      reply = QMessageBox::Yes;
-    }
-
-    if (reply == QMessageBox::Yes) {
-      if (deleteExplorer) {
-        // loop through multiple items selected from the mantid tree
-        QList<QTreeWidgetItem *>::iterator itr = items.begin();
-        for (itr = items.begin(); itr != items.end(); ++itr) {
-          // Sometimes we try to delete a workspace that's already been deleted.
-          if (m_ads.doesExist((*itr)->text(0).toStdString()))
-            m_mantidUI->deleteWorkspace((*itr)->text(0));
-        } // end of for loop for selected items
-      } else if (deleteActive) {
-        m_mantidUI->deleteWorkspace(m->workspaceName());
-      }
-    }
-  }
-}
-
-void MantidDockWidget::sortAscending() {
-  if (isTreeUpdating())
-    return;
-  m_tree->setSortOrder(Qt::AscendingOrder);
-  m_tree->sort();
-}
-
-void MantidDockWidget::sortDescending() {
-  if (isTreeUpdating())
-    return;
-  m_tree->setSortOrder(Qt::DescendingOrder);
-  m_tree->sort();
-}
-
-void MantidDockWidget::chooseByName() {
-  if (isTreeUpdating())
-    return;
-  m_tree->setSortScheme(MantidItemSortScheme::ByName);
-  m_tree->sort();
-}
-
-void MantidDockWidget::chooseByLastModified() {
-  if (isTreeUpdating())
-    return;
-  m_tree->setSortScheme(MantidItemSortScheme::ByLastModified);
-  m_tree->sort();
-}
-
-void MantidDockWidget::excludeItemFromSort(MantidTreeWidgetItem *item) {
-  static int counter = 1;
-
-  item->setSortPos(counter);
-
-  counter++;
-}
-
-/**
-* Saves a workspace based on the program the user chooses to save to.
-* @param name :: A string containing the name of the program
-*/
-
-void MantidDockWidget::saveToProgram(const QString &name) {
-  // Create a map for the keys and details to go into
-  std::map<std::string, std::string> programKeysAndDetails;
-  programKeysAndDetails["name"] = name.toStdString();
-
-  // Get a list of the program detail keys (mandatory - target, saveusing)
-  // (optional - arguments, save parameters, workspace type)
-  std::vector<std::string> programKeys =
-      (Mantid::Kernel::ConfigService::Instance().getKeys(
-          ("workspace.sendto." + programKeysAndDetails.find("name")->second)));
-
-  for (size_t i = 0; i < programKeys.size(); i++) {
-    // Assign a key to its value using the map
-    programKeysAndDetails[programKeys[i]] =
-        (Mantid::Kernel::ConfigService::Instance().getString(
-            ("workspace.sendto." + programKeysAndDetails.find("name")->second +
-             "." + programKeys[i])));
-  }
-
-  // Check to see if mandatory information is included
-  if ((programKeysAndDetails.count("name") != 0) &&
-      (programKeysAndDetails.count("target") != 0) &&
-      (programKeysAndDetails.count("saveusing") != 0)) {
-    std::string expTarget =
-        Poco::Path::expand(programKeysAndDetails.find("target")->second);
-
-    QFileInfo target = QString::fromStdString(expTarget);
-    if (target.exists()) {
-      try {
-        // Setup a shared pointer for the algorithm using the appropriate save
-        // type
-        Mantid::API::IAlgorithm_sptr alg;
-
-        // Convert to QString and create Algorithm
-        QString saveUsing = QString::fromStdString(
-            programKeysAndDetails.find("saveusing")->second);
-
-        // Create a new save based on what files the new program can open
-        alg = m_mantidUI->createAlgorithm(saveUsing);
-
-        // Get the file extention based on the workspace
-        Property *prop = alg->getProperty("Filename");
-        FileProperty *fileProp = dynamic_cast<FileProperty *>(prop);
-        std::string ext;
-        if (fileProp) {
-          ext = fileProp->getDefaultExt();
-        }
-
-        // Save as.. default save + the file type i.e .nxs
-        alg->setPropertyValue(
-            "fileName", "auto_save_" + selectedWsName.toStdString() + ext);
-
-        // Save the workspace
-        alg->setPropertyValue("InputWorkspace", selectedWsName.toStdString());
-
-        // If there are any save parameters
-        if (programKeysAndDetails.count("saveparameters") != 0) {
-          QString saveParametersGrouped = QString::fromStdString(
-              programKeysAndDetails.find("saveparameters")->second);
-          QStringList saveParameters = saveParametersGrouped.split(',');
-
-          // For each one found split it up and assign the parameter
-          for (int i = 0; i < saveParameters.size(); i++) {
-            QStringList sPNameAndDetail = saveParameters[i].split('=');
-            std::string saveParameterName =
-                sPNameAndDetail[0].trimmed().toStdString();
-            std::string saveParameterDetail =
-                sPNameAndDetail[1].trimmed().toStdString();
-            if (saveParameterDetail == "True")
-              alg->setProperty(saveParameterName, true);
-            else if (saveParameterDetail == "False")
-              alg->setProperty(saveParameterName, false);
-            else // if not true or false then must be a value
-            {
-              alg->setPropertyValue(saveParameterName, saveParameterDetail);
-            }
-          }
-        }
-
-        // Execute the save
-        m_mantidUI->executeAlgorithmAsync(alg, true);
-        // alg->execute();
-
-        // Get the save location of the file (should be default Mantid folder)
-        // std::string savedFile = alg->getProperty("Filename");
-        QString savedFile =
-            QString::fromStdString(alg->getProperty("Filename"));
-        QStringList arguments;
-
-        // Arguments for the program to take. Default will be the file anyway.
-        if (programKeysAndDetails.count("arguments") != 0) {
-          QString temp = QString::fromStdString(
-              programKeysAndDetails.find("arguments")->second);
-          temp.replace(QString("[file]"), savedFile);
-          // temp.replace(QString("[user]"), user;
-          arguments = temp.split(",");
-        } else
-          arguments.insert(0, savedFile);
-
-        // convert the list into a standard vector for compatibility with Poco
-        std::vector<std::string> argumentsV;
-
-        for (int i = 0; i < arguments.size(); i++) {
-          argumentsV.assign(1, (arguments[i].toStdString()));
-        }
-
-        // Execute the program
-        try {
-          Mantid::Kernel::ConfigService::Instance().launchProcess(expTarget,
-                                                                  argumentsV);
-        } catch (std::runtime_error &) {
-          QMessageBox::information(
-              this, "Error", "User tried to open program from: " +
-                                 QString::fromStdString(expTarget) +
-                                 " There was an error opening the program. "
-                                 "Please check the target and arguments list "
-                                 "to ensure that these are correct");
-        }
-      } catch (std::exception &) {
-        QMessageBox::information(
-            this, "Mantid - Send to Program",
-            "A file property wasn't found. Please check that the correct" +
-                QString("save algorithm was used.\n(View -> Preferences -> "
-                        "Mantid -> SendTo -> Edit -> SaveUsing)"));
-      }
-    } else
-      QMessageBox::information(this, "Target Path Error",
-                               "User tried to open program from: " +
-                                   QString::fromStdString(expTarget) +
-                                   " The target file path for the program "
-                                   "can't be found. Please check that the full "
-                                   "path is correct");
-  }
-}
-
-void MantidDockWidget::renameWorkspace() {
-  // get selected workspace
-  QList<QTreeWidgetItem *> selectedItems = m_tree->selectedItems();
-  QStringList selectedwsNames;
-  if (!selectedItems.empty()) {
-    for (int i = 0; i < selectedItems.size(); ++i) {
-      selectedwsNames.append(selectedItems[i]->text(0));
-    }
-  }
-  m_mantidUI->renameWorkspace(selectedwsNames);
-}
-
-void MantidDockWidget::showDetectorTable() {
-  // get selected workspace
-  QList<QTreeWidgetItem *> selectedItems = m_tree->selectedItems();
-  QString selctedwsName;
-  if (!selectedItems.empty()) {
-    selctedwsName = selectedItems[0]->text(0);
-  }
-  m_mantidUI->createDetectorTable(selctedwsName, std::vector<int>());
-}
-
-void MantidDockWidget::popupMenu(const QPoint &pos) {
-  QTreeWidgetItem *treeItem = m_tree->itemAt(pos);
-  selectedWsName = "";
-  if (treeItem)
-    selectedWsName = treeItem->text(0);
-  else
-    m_tree->selectionModel()->clear();
-  QMenu *menu(NULL);
-
-  // If no workspace is here then have load raw and dae
-  if (selectedWsName.isEmpty()) {
-    menu = m_loadMenu;
-  }
-  // else show instrument, sample logs and delete
-  else {
-    // Fresh menu
-    menu = new QMenu(this);
-    menu->setObjectName("WorkspaceContextMenu");
-    Mantid::API::Workspace_const_sptr ws;
-    try {
-      ws = m_ads.retrieve(selectedWsName.toStdString());
-    } catch (Mantid::Kernel::Exception::NotFoundError &) {
-      // Nothing to do
-      return;
-    }
-
-    // Add the items that are appropriate for the type
-    if (MatrixWorkspace_const_sptr matrixWS =
-            boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
-                ws)) {
-      addMatrixWorkspaceMenuItems(menu, matrixWS);
-    } else if (IMDEventWorkspace_const_sptr mdeventWS =
-                   boost::dynamic_pointer_cast<const IMDEventWorkspace>(ws)) {
-      addMDEventWorkspaceMenuItems(menu, mdeventWS);
-    } else if (IMDWorkspace_const_sptr mdWS =
-                   boost::dynamic_pointer_cast<const IMDWorkspace>(ws)) {
-      addMDHistoWorkspaceMenuItems(menu, mdWS);
-    } else if (IPeaksWorkspace_const_sptr peaksWS =
-                   boost::dynamic_pointer_cast<const IPeaksWorkspace>(ws)) {
-      addPeaksWorkspaceMenuItems(menu, peaksWS);
-    } else if (WorkspaceGroup_const_sptr groupWS =
-                   boost::dynamic_pointer_cast<const WorkspaceGroup>(ws)) {
-      addWorkspaceGroupMenuItems(menu, groupWS);
-    } else if (boost::dynamic_pointer_cast<const Mantid::API::ITableWorkspace>(
-                   ws)) {
-      addTableWorkspaceMenuItems(menu);
-    }
-    addClearMenuItems(menu, selectedWsName);
-
-    // Get the names of the programs for the send to option
-    std::vector<std::string> programNames =
-        (Mantid::Kernel::ConfigService::Instance().getKeys(
-            "workspace.sendto.name"));
-    bool firstPass(true);
-    // Check to see if any options aren't visible
-    for (size_t i = 0; i < programNames.size(); i++) {
-      std::string visible = Mantid::Kernel::ConfigService::Instance().getString(
-          "workspace.sendto." + programNames[i] + ".visible");
-      std::string target = Mantid::Kernel::ConfigService::Instance().getString(
-          "workspace.sendto." + programNames[i] + ".target");
-      if (Mantid::Kernel::ConfigService::Instance().isExecutable(target) &&
-          visible == "Yes") {
-        bool compatible(true);
-        std::string saveUsing(
-            Mantid::Kernel::ConfigService::Instance().getString(
-                "workspace.sendto." + programNames[i] + ".saveusing"));
-        try {
-          Mantid::API::IAlgorithm_sptr alg =
-              Mantid::API::AlgorithmManager::Instance().create(saveUsing);
-          alg->setPropertyValue("InputWorkspace", selectedWsName.toStdString());
-        } catch (std::exception &) {
-          compatible = false;
-        }
-        if (compatible) {
-          if (firstPass) {
-            m_saveToProgram = new QMenu(tr("Send to"), this);
-            menu->addMenu(m_saveToProgram);
-
-            // Sub-menu for program list
-            m_programMapper = new QSignalMapper(this);
-          }
-          QString name = QString::fromStdString(programNames[i]);
-          // Setup new menu option for the program
-          m_program = new QAction(name, this);
-          connect(m_program, SIGNAL(triggered()), m_programMapper, SLOT(map()));
-          // Send name of program when clicked
-          m_programMapper->setMapping(m_program, name);
-          m_saveToProgram->addAction(m_program);
-
-          // Set first pass to false so that it doesn't set up another menu
-          // entry for all programs.
-          firstPass = false;
-        }
-      }
-    }
-
-    // Tell the button what to listen for and what to do once clicked (if there
-    // is anything to connect it will be set to false)
-    if (!firstPass)
-      connect(m_programMapper, SIGNAL(mapped(const QString &)), this,
-              SLOT(saveToProgram(const QString &)));
-
-    // Rename is valid for all workspace types
-    menu->addAction(m_rename);
-    // separate delete
-    menu->addSeparator();
-    menu->addAction(m_delete);
-  }
-
-  // Show the menu at the cursor's current position
-  menu->popup(QCursor::pos());
-}
-
-void MantidDockWidget::groupingButtonClick() {
-  if (m_groupButton) {
-    QString qButtonName = m_groupButton->text();
-    if (qButtonName == "Group") {
-      m_mantidUI->groupWorkspaces();
-    } else if (qButtonName == "Ungroup") {
-      m_mantidUI->ungroupWorkspaces();
-    }
-  }
-}
-
-/// Plots a single spectrum from each selected workspace
-void MantidDockWidget::plotSpectra() { doPlotSpectra(false); }
-
-/// Plots a single spectrum from each selected workspace with errors
-void MantidDockWidget::plotSpectraErr() { doPlotSpectra(true); }
-
-/**
- * Plots a single spectrum from each selected workspace.
- * Option to plot errors or not.
- * @param errors :: [input] True if errors should be plotted, else false
- */
-void MantidDockWidget::doPlotSpectra(bool errors) {
-  const auto userInput = m_tree->chooseSpectrumFromSelected();
-  // An empty map will be returned if the user clicks cancel in the spectrum
-  // selection
-  if (userInput.plots.empty())
-    return;
-
-  if (userInput.tiled) {
-    m_mantidUI->plotSubplots(userInput.plots, MantidQt::DistributionDefault,
-                             errors);
-  } else {
-    m_mantidUI->plot1D(userInput.plots, true, MantidQt::DistributionDefault,
-                       errors, nullptr, false, userInput.waterfall);
-  }
-}
-
-/**
-* Draw a color fill plot of the workspaces that are currently selected.
-* NOTE: The drawing of 2D plots is currently intimately linked with MantidMatrix
-* meaning
-* that one of these must be generated first!
-*/
-void MantidDockWidget::drawColorFillPlot() {
-  // Get the selected workspaces
-  const QStringList wsNames = m_tree->getSelectedWorkspaceNames();
-  if (wsNames.empty())
-    return;
-
-  // Extract child workspace names from any WorkspaceGroups selected.
-  // Use a list to preserve workspace order.
-  QStringList allWsNames;
-  foreach (const QString wsName, wsNames) {
-    const auto wsGroup = boost::dynamic_pointer_cast<const WorkspaceGroup>(
-        m_ads.retrieve(wsName.toStdString()));
-    if (wsGroup) {
-      const auto children = wsGroup->getNames();
-      for (auto childWsName = children.begin(); childWsName != children.end();
-           ++childWsName) {
-        auto name = QString::fromStdString(*childWsName);
-        if (allWsNames.contains(name))
-          continue;
-        allWsNames.append(name);
-      }
-    } else
-      allWsNames.append(wsName);
-  }
-
-  m_mantidUI->drawColorFillPlots(allWsNames);
-}
-
-void MantidDockWidget::treeSelectionChanged() {
-  // get selected workspaces
-  QList<QTreeWidgetItem *> Items = m_tree->selectedItems();
-
-  if (m_groupButton) {
-    if (Items.size() == 1) {
-      // check it's group
-      QList<QTreeWidgetItem *>::const_iterator itr = Items.begin();
-      std::string selectedWSName = (*itr)->text(0).toStdString();
-      if (m_ads.doesExist(selectedWSName)) {
-        Workspace_sptr wsSptr = m_ads.retrieve(selectedWSName);
-        WorkspaceGroup_sptr grpSptr =
-            boost::dynamic_pointer_cast<WorkspaceGroup>(wsSptr);
-        if (grpSptr) {
-          m_groupButton->setText("Ungroup");
-          m_groupButton->setEnabled(true);
-        } else
-          m_groupButton->setEnabled(false);
-      }
-
-    } else if (Items.size() >= 2) {
-      m_groupButton->setText("Group");
-      m_groupButton->setEnabled(true);
-    } else if (Items.size() == 0) {
-      m_groupButton->setText("Group");
-      m_groupButton->setEnabled(false);
-    }
-  }
-
-  if (m_deleteButton)
-    m_deleteButton->setEnabled(Items.size() > 0);
-
-  if (m_saveButton)
-    m_saveButton->setEnabled(Items.size() > 0);
-
-  if (Items.size() > 0) {
-    auto item = *(Items.begin());
-    m_mantidUI->enableSaveNexus(item->text(0));
-  } else {
-    m_mantidUI->disableSaveNexus();
-  }
-}
-
-/**
-* Convert selected TableWorkspace to a MatrixWorkspace.
-*/
-void MantidDockWidget::convertToMatrixWorkspace() {
-  m_mantidUI->showAlgorithmDialog(QString("ConvertTableToMatrixWorkspace"), -1);
-}
-
-/**
-* Convert selected MDHistoWorkspace to a MatrixWorkspace.
-*/
-void MantidDockWidget::convertMDHistoToMatrixWorkspace() {
-  m_mantidUI->showAlgorithmDialog(QString("ConvertMDHistoToMatrixWorkspace"),
-                                  -1);
-}
-
-/**
-* Handler for the clear the UB matrix event.
-*/
-void MantidDockWidget::clearUB() {
-  QList<QTreeWidgetItem *> selectedItems = m_tree->selectedItems();
-  QStringList selctedWSNames;
-  if (!selectedItems.empty()) {
-    for (int i = 0; i < selectedItems.size(); ++i) {
-      selctedWSNames.append(selectedItems[i]->text(0));
-    }
-  }
-  m_mantidUI->clearUB(selctedWSNames);
-}
-
-/**
-* Accept a drag drop event and process the data appropriately
-* @param de :: The drag drop event
-*/
-void MantidDockWidget::dropEvent(QDropEvent *de) { m_tree->dropEvent(de); }
-
-/**
- * Create a 3D surface plot from the selected workspace group
- */
-void MantidDockWidget::plotSurface() {
-  // find the workspace group clicked on
-  const QStringList wsNames = m_tree->getSelectedWorkspaceNames();
-  if (!wsNames.empty()) {
-    const auto wsName = wsNames[0];
-    const auto wsGroup = boost::dynamic_pointer_cast<const WorkspaceGroup>(
-        m_ads.retrieve(wsName.toStdString()));
-    if (wsGroup) {
-      auto options =
-          m_tree->chooseSurfacePlotOptions(wsGroup->getNumberOfEntries());
-
-      auto plotter =
-          Mantid::Kernel::make_unique<MantidGroupPlotGenerator>(m_mantidUI);
-      plotter->plotSurface(wsGroup, options);
-    }
-  }
-}
-
-/**
- * Create a contour plot from the selected workspace group
- */
-void MantidDockWidget::plotContour() {
-  const QStringList wsNames = m_tree->getSelectedWorkspaceNames();
-  if (!wsNames.empty()) {
-    const auto wsName = wsNames[0];
-    const auto wsGroup = boost::dynamic_pointer_cast<const WorkspaceGroup>(
-        m_ads.retrieve(wsName.toStdString()));
-    if (wsGroup) {
-      auto options =
-          m_tree->chooseContourPlotOptions(wsGroup->getNumberOfEntries());
-
-      auto plotter =
-          Mantid::Kernel::make_unique<MantidGroupPlotGenerator>(m_mantidUI);
-      plotter->plotContour(wsGroup, options);
-    }
-  }
-}
\ No newline at end of file
diff --git a/MantidPlot/src/Mantid/MantidDock.h b/MantidPlot/src/Mantid/MantidDock.h
deleted file mode 100644
index a1b9e26c290f172298c0e078b387253cb7daf2a1..0000000000000000000000000000000000000000
--- a/MantidPlot/src/Mantid/MantidDock.h
+++ /dev/null
@@ -1,162 +0,0 @@
-#ifndef MANTIDDOCK_H
-#define MANTIDDOCK_H
-
-#include "MantidAPI/ExperimentInfo.h"
-#include "MantidAPI/IMDEventWorkspace_fwd.h"
-#include "MantidAPI/IMDWorkspace.h"
-#include "MantidAPI/IPeaksWorkspace_fwd.h"
-#include "MantidAPI/ITableWorkspace_fwd.h"
-#include "MantidAPI/MatrixWorkspace_fwd.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
-
-#include <QActionGroup>
-#include <QAtomicInt>
-#include <QComboBox>
-#include <QDockWidget>
-#include <QList>
-#include <QPoint>
-#include <QSortFilterProxyModel>
-#include <QStringList>
-#include <QMap>
-
-#include <set>
-
-class MantidUI;
-class ApplicationWindow;
-class MantidTreeWidgetItem;
-class MantidTreeWidget;
-class QLabel;
-class QFileDialog;
-class QMenu;
-class QPushButton;
-class QTreeWidget;
-class QTreeWidgetItem;
-class QProgressBar;
-class QVBoxLayout;
-class QHBoxLayout;
-class QSignalMapper;
-class QSortFilterProxyModel;
-
-enum MantidItemSortScheme { ByName, ByLastModified };
-
-class MantidDockWidget : public QDockWidget {
-  Q_OBJECT
-public:
-  MantidDockWidget(MantidUI *mui, ApplicationWindow *parent);
-  ~MantidDockWidget() override;
-  QString getSelectedWorkspaceName() const;
-  Mantid::API::Workspace_sptr getSelectedWorkspace() const;
-  void dropEvent(QDropEvent *de) override;
-
-public slots:
-  void clickedWorkspace(QTreeWidgetItem *, int);
-  void saveWorkspaceGroup();
-  void deleteWorkspaces();
-  void renameWorkspace();
-  void populateChildData(QTreeWidgetItem *item);
-  void saveToProgram(const QString &name);
-  void sortAscending();
-  void sortDescending();
-  void chooseByName();
-  void chooseByLastModified();
-  void saveWorkspacesToFolder(const QString &folder);
-
-protected slots:
-  void popupMenu(const QPoint &pos);
-  void workspaceSelected();
-
-private slots:
-  void handleShowSaveAlgorithm();
-  void treeSelectionChanged();
-  void groupingButtonClick();
-  void plotSpectra();
-  void plotSpectraErr();
-  void drawColorFillPlot();
-  void showDetectorTable();
-  void convertToMatrixWorkspace();
-  void convertMDHistoToMatrixWorkspace();
-  void updateTreeOnADSUpdate();
-  void incrementUpdateCount();
-  void recordWorkspaceRename(QString, QString);
-  void clearUB();
-  void filterWorkspaceTree(const QString &text);
-  void plotSurface();
-  void plotContour();
-
-private:
-  void addSaveMenuOption(QString algorithmString, QString menuEntryName = "");
-  void setTreeUpdating(const bool state);
-  inline bool isTreeUpdating() const { return m_treeUpdating; }
-  void updateTree();
-  void populateTopLevel(
-      const std::map<std::string, Mantid::API::Workspace_sptr> &topLevelItems,
-      const QStringList &expanded);
-  MantidTreeWidgetItem *
-  addTreeEntry(const std::pair<std::string, Mantid::API::Workspace_sptr> &item,
-               QTreeWidgetItem *parent = NULL);
-  bool shouldBeSelected(QString name) const;
-  void createWorkspaceMenuActions();
-  void createSortMenuActions();
-  void setItemIcon(QTreeWidgetItem *item, const std::string &wsID);
-
-  void addMatrixWorkspaceMenuItems(
-      QMenu *menu,
-      const Mantid::API::MatrixWorkspace_const_sptr &matrixWS) const;
-  void addMDEventWorkspaceMenuItems(
-      QMenu *menu,
-      const Mantid::API::IMDEventWorkspace_const_sptr &mdeventWS) const;
-  void addMDHistoWorkspaceMenuItems(
-      QMenu *menu, const Mantid::API::IMDWorkspace_const_sptr &WS) const;
-  void addPeaksWorkspaceMenuItems(
-      QMenu *menu, const Mantid::API::IPeaksWorkspace_const_sptr &WS) const;
-  void addWorkspaceGroupMenuItems(
-      QMenu *menu, const Mantid::API::WorkspaceGroup_const_sptr &groupWS) const;
-  void addTableWorkspaceMenuItems(QMenu *menu) const;
-  void addClearMenuItems(QMenu *menu, const QString &wsName);
-
-  void excludeItemFromSort(MantidTreeWidgetItem *item);
-  void doPlotSpectra(bool errors);
-
-protected:
-  MantidTreeWidget *m_tree;
-  friend class MantidUI;
-
-private:
-  QString selectedWsName;
-
-  MantidUI *const m_mantidUI;
-
-  QPushButton *m_loadButton;
-  QPushButton *m_saveButton;
-  QMenu *m_loadMenu, *m_saveToProgram, *m_sortMenu, *m_saveMenu;
-  QPushButton *m_deleteButton;
-  QPushButton *m_groupButton;
-  QPushButton *m_sortButton;
-  QLineEdit *m_workspaceFilter;
-  QSignalMapper *m_loadMapper, *m_programMapper;
-  QActionGroup *m_sortChoiceGroup;
-  QFileDialog *m_saveFolderDialog;
-
-  // Context-menu actions
-  QAction *m_showData, *m_showInst, *m_plotSpec, *m_plotSpecErr,
-      *m_showDetectors, *m_showBoxData, *m_showVatesGui, *m_showSpectrumViewer,
-      *m_showSliceViewer, *m_colorFill, *m_showLogs, *m_showSampleMaterial,
-      *m_showHist, *m_showMDPlot, *m_showListData, *m_saveNexus, *m_rename,
-      *m_delete, *m_program, *m_ascendingSortAction, *m_descendingSortAction,
-      *m_byNameChoice, *m_byLastModifiedChoice, *m_showTransposed,
-      *m_convertToMatrixWorkspace, *m_convertMDHistoToMatrixWorkspace,
-      *m_clearUB, *m_plotSurface, *m_plotContour;
-
-  ApplicationWindow *m_appParent;
-
-  QAtomicInt m_updateCount;
-  bool m_treeUpdating;
-  Mantid::API::AnalysisDataServiceImpl &m_ads;
-  /// Temporarily keeps names of selected workspaces during tree update
-  /// in order to restore selection after update
-  QStringList m_selectedNames;
-  /// Keep a map of renamed workspaces between updates
-  QMap<QString, QString> m_renameMap;
-};
-
-#endif
diff --git a/MantidPlot/src/Mantid/MantidGroupPlotGenerator.cpp b/MantidPlot/src/Mantid/MantidGroupPlotGenerator.cpp
index 94f5a03c6492c22360b95443479747283e0acb7c..b2755fbde0233658dbbe4f398d29f4a9a2e1af5e 100644
--- a/MantidPlot/src/Mantid/MantidGroupPlotGenerator.cpp
+++ b/MantidPlot/src/Mantid/MantidGroupPlotGenerator.cpp
@@ -3,6 +3,8 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include <MantidQtMantidWidgets/MantidDisplayBase.h>
 
 using namespace MantidQt::MantidWidgets;
diff --git a/MantidPlot/src/Mantid/MantidGroupPlotGenerator.h b/MantidPlot/src/Mantid/MantidGroupPlotGenerator.h
index c4b8c8483d36621602b3555678e982c7ce262ecf..051ef36ce3c192bd20a09718043102cc9589554a 100644
--- a/MantidPlot/src/Mantid/MantidGroupPlotGenerator.h
+++ b/MantidPlot/src/Mantid/MantidGroupPlotGenerator.h
@@ -3,6 +3,7 @@
 
 #include "Graph3D.h"
 #include "MantidAPI/NumericAxis.h"
+#include "MantidAPI/WorkspaceGroup_fwd.h"
 #include "MantidMatrix.h"
 #include <MantidQtMantidWidgets/MantidSurfacePlotDialog.h>
 
diff --git a/MantidPlot/src/Mantid/MantidMatrixCurve.cpp b/MantidPlot/src/Mantid/MantidMatrixCurve.cpp
index bbb80525696f0e63eb499b84f6a8723adb230081..cf38b44252fdf94650efe1afe3b7a0c68b176227 100644
--- a/MantidPlot/src/Mantid/MantidMatrixCurve.cpp
+++ b/MantidPlot/src/Mantid/MantidMatrixCurve.cpp
@@ -15,6 +15,7 @@
 #include "../MultiLayer.h"
 #include "ErrorBarSettings.h"
 #include "MantidKernel/ReadLock.h"
+#include <sstream>
 
 using namespace Mantid::API;
 using namespace MantidQt::API;
diff --git a/MantidPlot/src/Mantid/MantidMatrixModel.cpp b/MantidPlot/src/Mantid/MantidMatrixModel.cpp
index 587384289951d93961f2425a693b217320d52459..88e71c41a5a0e34ed4bd293d5d32c7a3daad464f 100644
--- a/MantidPlot/src/Mantid/MantidMatrixModel.cpp
+++ b/MantidPlot/src/Mantid/MantidMatrixModel.cpp
@@ -3,12 +3,11 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/NumericAxis.h"
 #include "MantidAPI/SpectraAxis.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/RefAxis.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidKernel/ReadLock.h"
 
-#include "MantidGeometry/IDetector.h"
-
 #include <QApplication>
 #include <QObject>
 #include <QPalette>
@@ -282,15 +281,10 @@ bool MantidMatrixModel::checkMonitorCache(int row) const {
     if (m_monCache.contains(row)) {
       isMon = m_monCache.value(row);
     } else {
-      try {
-        size_t wsIndex = static_cast<size_t>(row);
-        auto det = m_workspace->getDetector(wsIndex);
-        isMon = det->isMonitor();
-        m_monCache.insert(row, isMon);
-      } catch (std::exception &) {
-        m_monCache.insert(row, false);
-        isMon = false;
-      }
+      const auto &specInfo = m_workspace->spectrumInfo();
+      size_t wsIndex = static_cast<size_t>(row);
+      isMon = specInfo.hasDetectors(wsIndex) && specInfo.isMonitor(wsIndex);
+      m_monCache.insert(row, isMon);
     }
     return isMon;
   } else {
@@ -310,15 +304,10 @@ bool MantidMatrixModel::checkMaskedCache(int row) const {
     if (m_maskCache.contains(row)) {
       isMasked = m_maskCache.value(row);
     } else {
-      try {
-        size_t wsIndex = static_cast<size_t>(row);
-        auto det = m_workspace->getDetector(wsIndex);
-        isMasked = det->isMasked();
-        m_maskCache.insert(row, isMasked);
-      } catch (std::exception &) {
-        m_maskCache.insert(row, false);
-        isMasked = false;
-      }
+      const auto &specInfo = m_workspace->spectrumInfo();
+      size_t wsIndex = static_cast<size_t>(row);
+      isMasked = specInfo.hasDetectors(wsIndex) && specInfo.isMasked(wsIndex);
+      m_maskCache.insert(row, isMasked);
     }
     return isMasked;
   } else {
diff --git a/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp b/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp
index 9d5cade184fdaa1a339374a1a3ee4c9233e25897..58d2cd19c3789fa0aa9f2db1b6c740c78859bec9 100644
--- a/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp
+++ b/MantidPlot/src/Mantid/MantidSampleLogDialog.cpp
@@ -48,15 +48,22 @@ MantidSampleLogDialog::MantidSampleLogDialog(const QString &wsname,
   filterPeriod = new QRadioButton("Period");
   filterStatusPeriod = new QRadioButton("Status + Period");
   filterStatusPeriod->setChecked(true);
+  const std::vector<QRadioButton *> filterRadioButtons{
+      filterNone, filterStatus, filterPeriod, filterStatusPeriod};
 
+  // Add options to layout
   QVBoxLayout *vbox = new QVBoxLayout;
-  vbox->addWidget(filterNone);
-  vbox->addWidget(filterStatus);
-  vbox->addWidget(filterPeriod);
-  vbox->addWidget(filterStatusPeriod);
-  // vbox->addStretch(1);
+  for (auto *radioButton : filterRadioButtons) {
+    vbox->addWidget(radioButton);
+  }
   groupBox->setLayout(vbox);
 
+  // Changing filter option updates stats
+  for (auto *radioButton : filterRadioButtons) {
+    connect(radioButton, SIGNAL(toggled(bool)), this,
+            SLOT(showLogStatistics()));
+  }
+
   // -------------- Statistics on logs ------------------------
   std::string stats[NUM_STATS] = {
       "Min:", "Max:", "Mean:", "Time Avg:", "Median:", "Std Dev:", "Duration:"};
@@ -144,3 +151,20 @@ void MantidSampleLogDialog::importItem(QTreeWidgetItem *item) {
     throw std::invalid_argument("Error importing log entry, wrong data type");
   }
 }
+
+/**
+ * Return filter type based on which radio button is selected
+ * @returns :: Filter type selected in UI
+ */
+Mantid::API::LogFilterGenerator::FilterType
+MantidSampleLogDialog::getFilterType() const {
+  if (filterStatus->isChecked()) {
+    return Mantid::API::LogFilterGenerator::FilterType::Status;
+  } else if (filterPeriod->isChecked()) {
+    return Mantid::API::LogFilterGenerator::FilterType::Period;
+  } else if (filterStatusPeriod->isChecked()) {
+    return Mantid::API::LogFilterGenerator::FilterType::StatusAndPeriod;
+  } else {
+    return Mantid::API::LogFilterGenerator::FilterType::None;
+  }
+}
diff --git a/MantidPlot/src/Mantid/MantidSampleLogDialog.h b/MantidPlot/src/Mantid/MantidSampleLogDialog.h
index dcc3eac881ae7ec9e6fed845e1f53d38a5a12551..53f66bef70f6fa3398d273084c7a556b1358d6b6 100644
--- a/MantidPlot/src/Mantid/MantidSampleLogDialog.h
+++ b/MantidPlot/src/Mantid/MantidSampleLogDialog.h
@@ -60,6 +60,9 @@ public:
   /// Destructor
   virtual ~MantidSampleLogDialog() override;
 
+  /// Which type of filtering is selected
+  Mantid::API::LogFilterGenerator::FilterType getFilterType() const override;
+
 protected slots:
 
   /// Import a single item
diff --git a/MantidPlot/src/Mantid/MantidUI.cpp b/MantidPlot/src/Mantid/MantidUI.cpp
index a50d9b3a2311f66ec9cc460bc63d268492ccf3d1..e78bf71d98c4977b7b4c49deaf09e4eb06af4e5d 100644
--- a/MantidPlot/src/Mantid/MantidUI.cpp
+++ b/MantidPlot/src/Mantid/MantidUI.cpp
@@ -53,7 +53,9 @@
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidAPI/LogFilterGenerator.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QListWidget>
 #include <QMdiArea>
@@ -843,8 +845,7 @@ void MantidUI::showVatesSimpleInterface() {
         connect(vsui, SIGNAL(requestClose()), m_vatesSubWindow, SLOT(close()));
         vsui->setParent(m_vatesSubWindow);
         m_vatesSubWindow->setWindowTitle("Vates Simple Interface");
-        vsui->setupPluginMode();
-        // m_appWindow->setGeometry(m_vatesSubWindow, vsui);
+        vsui->setupPluginMode(wsType, instrumentName);
         m_vatesSubWindow->setWidget(vsui);
         m_vatesSubWindow->widget()->show();
         vsui->renderWorkspace(wsName, wsType, instrumentName);
@@ -2400,12 +2401,29 @@ void MantidUI::importStrSeriesLog(const QString &logName, const QString &data,
 */
 void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
                                   int filter) {
-  // if you need to add a final filter valure to the end of the filter to match
+  // if you need to add a final filter value to the end of the filter to match
   // the extent of the data, then set this to the index of the row to add the
   // value
   int addFinalFilterValueIndex = 0;
   Mantid::Kernel::DateAndTime lastFilterTime;
 
+  // Convert input int into enum value
+  const Mantid::API::LogFilterGenerator::FilterType filterType = [&filter]() {
+    switch (filter) {
+    case 0:
+      return Mantid::API::LogFilterGenerator::FilterType::None;
+    case 1:
+      return Mantid::API::LogFilterGenerator::FilterType::Status;
+    case 2:
+      return Mantid::API::LogFilterGenerator::FilterType::Period;
+    case 3:
+      return Mantid::API::LogFilterGenerator::FilterType::StatusAndPeriod;
+    default:
+      return Mantid::API::LogFilterGenerator::FilterType::None;
+    }
+  }();
+
+  // Make sure the workspace exists and contains the log
   MatrixWorkspace_const_sptr ws =
       boost::dynamic_pointer_cast<const MatrixWorkspace>(getWorkspace(wsName));
   if (!ws)
@@ -2416,12 +2434,14 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
   if (!logData)
     return;
 
-  Mantid::Kernel::LogFilter flt(logData);
+  // Generate the filter
+  Mantid::API::LogFilterGenerator filterGenerator(filterType, ws);
+  const auto &flt = filterGenerator.generateFilter(logName.toStdString());
 
   // Get a map of time/value. This greatly speeds up display.
   // NOTE: valueAsMap() skips repeated values.
   std::map<DateAndTime, double> time_value_map =
-      flt.data()->valueAsCorrectMap();
+      flt->data()->valueAsCorrectMap();
   int rowcount = static_cast<int>(time_value_map.size());
   int colCount = 2;
 
@@ -2471,9 +2491,6 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
     t->setColumnType(0, Table::Numeric);
   }
 
-  // The time when the first data was recorded.
-  auto firstTime = time_value_map.begin()->first;
-
   // Make the column header with the units, if any
   QString column1 = label.section("-", 1);
   if (logData->units() != "")
@@ -2483,65 +2500,9 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
 
   int iValueCurve = 0;
 
-  // Applying filters
-  if (filter > 0) {
-    Mantid::Kernel::TimeSeriesProperty<bool> *f = 0;
-    if (filter == 1 || filter == 3) {
-      // one of the filters is the running status
-      try {
-        f = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<bool> *>(
-            ws->run().getLogData("running"));
-        if (f)
-          flt.addFilter(*f);
-        else {
-          t->setconfirmcloseFlag(false);
-          t->setAttribute(Qt::WA_DeleteOnClose);
-          t->close();
-          importNumSeriesLog(wsName, logName, 0);
-          return;
-        }
-        // If filter records start later than the data we add a value at the
-        // filter's front
-        if (f->firstTime() > firstTime) {
-          // add a "not running" value to the status filter
-          Mantid::Kernel::TimeSeriesProperty<bool> atStart("tmp");
-          atStart.addValue(firstTime, false);
-          atStart.addValue(f->firstTime(), f->firstValue());
-          flt.addFilter(atStart);
-        }
-      } catch (...) {
-        t->setconfirmcloseFlag(false);
-        t->setAttribute(Qt::WA_DeleteOnClose);
-        t->close();
-        importNumSeriesLog(wsName, logName, 0);
-        return;
-      }
-    }
-
-    if (filter == 2 || filter == 3) {
-      std::vector<Mantid::Kernel::Property *> ps = ws->run().getLogData();
-      for (std::vector<Mantid::Kernel::Property *>::const_iterator it =
-               ps.begin();
-           it != ps.end(); ++it)
-        if ((*it)->name().find("period ") == 0) {
-          try {
-            f = dynamic_cast<Mantid::Kernel::TimeSeriesProperty<bool> *>(*it);
-            if (f)
-              flt.addFilter(*f);
-            else {
-              importNumSeriesLog(wsName, logName, 0);
-              return;
-            }
-          } catch (...) {
-            importNumSeriesLog(wsName, logName, 0);
-            return;
-          }
-
-          break;
-        }
-    }
-
-    if (flt.filter()) {
+  // Applying filter column to table
+  if (filterType != Mantid::API::LogFilterGenerator::FilterType::None) {
+    if (flt->filter()) {
       // Valid filter was found
       t->addColumns(2);
       t->setColName(2, "FTime");
@@ -2557,29 +2518,30 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
       t->setColPlotDesignation(2, Table::X);
       t->setColName(3, "Filter");
 
-      if (flt.filter()->size() > rowcount) {
-        t->addRows(flt.filter()->size() - rowcount);
+      if (flt->filter()->size() > rowcount) {
+        t->addRows(flt->filter()->size() - rowcount);
       }
 
-      if (flt.data()->size() > rowcount) {
-        t->addRows(flt.data()->size() - rowcount);
+      if (flt->data()->size() > rowcount) {
+        t->addRows(flt->data()->size() - rowcount);
       }
 
-      for (int i = 0; i < flt.filter()->size(); i++) {
-        if (flt.filter()->nthInterval(i).begin() >
+      for (int i = 0; i < flt->filter()->size(); i++) {
+        if (flt->filter()->nthInterval(i).begin() >
             0) // protect against bizarre values we sometimes get
         {
-          std::string time_string = extractLogTime(
-              flt.filter()->nthInterval(i).begin(), useAbsoluteDate, startTime);
+          std::string time_string =
+              extractLogTime(flt->filter()->nthInterval(i).begin(),
+                             useAbsoluteDate, startTime);
 
           t->setText(i, 2, QString::fromStdString(time_string));
-          t->setCell(i, 3, !flt.filter()->nthValue(i));
-          if ((i + 1 == flt.filter()->size()) &&
-              (!flt.filter()->nthValue(
+          t->setCell(i, 3, !flt->filter()->nthValue(i));
+          if ((i + 1 == flt->filter()->size()) &&
+              (!flt->filter()->nthValue(
                   i))) // last filter value and set to be filtering
           {
             addFinalFilterValueIndex = i + 1;
-            lastFilterTime = flt.filter()->nthInterval(i).begin();
+            lastFilterTime = flt->filter()->nthInterval(i).begin();
           }
         }
       }
@@ -2607,13 +2569,13 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
 
   try {
     // Set the filter strings
-    if (filter && flt.filter() && lastTime < flt.filter()->lastTime()) {
+    if (filter && flt->filter() && lastTime < flt->filter()->lastTime()) {
       rowcount = static_cast<int>(time_value_map.size());
       if (rowcount == t->numRows())
         t->addRows(1);
 
       std::string time_string =
-          extractLogTime(flt.filter()->lastTime(), useAbsoluteDate, startTime);
+          extractLogTime(flt->filter()->lastTime(), useAbsoluteDate, startTime);
 
       t->setText(rowcount, 0, QString::fromStdString(time_string));
       t->setCell(rowcount, 1, lastValue);
@@ -2649,7 +2611,7 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
     return;
 
   QStringList colNames;
-  if (filter && flt.filter()) {
+  if (filter && flt->filter()) {
     colNames << t->colName(3);
   }
   colNames << t->colName(1);
@@ -2662,7 +2624,7 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
   // Set x-axis label format
   if (useAbsoluteDate) {
     Mantid::Kernel::DateAndTime label_as_ptime =
-        flt.data()->nthInterval(0).begin();
+        flt->data()->nthInterval(0).begin();
     QDateTime dt = QDateTime::fromTime_t(uint(label_as_ptime.to_localtime_t()));
     QString format = dt.toString(Qt::ISODate) + ";HH:mm:ss";
     g->setLabelsDateTimeFormat(2, ScaleDraw::Date, format);
@@ -2676,7 +2638,7 @@ void MantidUI::importNumSeriesLog(const QString &wsName, const QString &logName,
   QPen pn = QPen(Qt::black);
   g->setCurvePen(iValueCurve, pn);
 
-  if (filter && flt.filter()) {
+  if (filter && flt->filter()) {
     int iFilterCurve = 1;
     QwtPlotCurve *c = g->curve(iFilterCurve);
     if (c) {
diff --git a/MantidPlot/src/Mantid/PeakPickerTool.cpp b/MantidPlot/src/Mantid/PeakPickerTool.cpp
index 084ff8b1e0b6b1a27ed0e3778f8c9c7cd0ee0260..f81882e6262b174acb6f989471ea87b91161b259 100644
--- a/MantidPlot/src/Mantid/PeakPickerTool.cpp
+++ b/MantidPlot/src/Mantid/PeakPickerTool.cpp
@@ -654,7 +654,8 @@ void PeakPickerTool::replot(MantidQt::MantidWidgets::PropertyHandler *h) const {
       // fc->loadData();
       auto ws = boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
           m_fitPropertyBrowser->getWorkspace());
-      fc->loadMantidData(ws, m_fitPropertyBrowser->workspaceIndex());
+      fc->loadMantidData(ws, m_fitPropertyBrowser->workspaceIndex(),
+                         m_fitPropertyBrowser->getPeakRadius());
     }
   }
 }
@@ -886,7 +887,8 @@ void PeakPickerTool::plotFitFunction(
                    m_fitPropertyBrowser->endX());
       auto ws = boost::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(
           m_fitPropertyBrowser->getWorkspace());
-      fc->loadMantidData(ws, m_fitPropertyBrowser->workspaceIndex());
+      fc->loadMantidData(ws, m_fitPropertyBrowser->workspaceIndex(),
+                         m_fitPropertyBrowser->getPeakRadius());
       // Graph now owns m_curve. Use m_curve->removeMe() to remove (and delete)
       // from Graph
       d_graph->insertCurve(fc);
diff --git a/MantidPlot/src/Mantid/SampleLogDialogBase.cpp b/MantidPlot/src/Mantid/SampleLogDialogBase.cpp
index 0d1eebd072f40dcbe6c7e9e571e905beef37866c..06c5051001f540db926def34c826338d7637d40f 100644
--- a/MantidPlot/src/Mantid/SampleLogDialogBase.cpp
+++ b/MantidPlot/src/Mantid/SampleLogDialogBase.cpp
@@ -1,15 +1,13 @@
 #include "SampleLogDialogBase.h"
 
-// Mantid API
-#include <MantidAPI/MultipleExperimentInfos.h>
-#include <MantidAPI/IMDWorkspace.h>
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/IMDWorkspace.h"
+#include "MantidAPI/MultipleExperimentInfos.h"
 #include "MantidAPI/Run.h"
 
-// Mantid Kernel
-#include <MantidKernel/TimeSeriesProperty.h>
-#include <MantidKernel/ArrayProperty.h>
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Strings.h"
 
-// Qt
 #include <QMenu>
 #include <QFileInfo>
 #include <QHeaderView>
@@ -86,11 +84,14 @@ void SampleLogDialogBase::importSelectedLogs() {
 *	@date 05/11/2009
 */
 void SampleLogDialogBase::showLogStatistics() {
+
+  const auto &filter = this->getFilterType();
+
   QList<QTreeWidgetItem *> items = m_tree->selectedItems();
   QListIterator<QTreeWidgetItem *> pItr(items);
   if (pItr.hasNext()) {
     // Show only the first one
-    showLogStatisticsOfItem(pItr.next());
+    showLogStatisticsOfItem(pItr.next(), filter);
   }
 }
 
@@ -99,12 +100,14 @@ void SampleLogDialogBase::showLogStatistics() {
 * Show the stats of the log for the selected item
 *
 *	@param item :: The item to be imported
+* @param filter :: Type of filtering (default none)
 *	@throw invalid_argument if format identifier for the item is wrong
 *
 *	@author Martyn Gigg, Tessella Support Services plc
 *	@date 05/11/2009
 */
-void SampleLogDialogBase::showLogStatisticsOfItem(QTreeWidgetItem *item) {
+void SampleLogDialogBase::showLogStatisticsOfItem(
+    QTreeWidgetItem *item, const LogFilterGenerator::FilterType filter) {
   // Assume that you can't show the stats
   for (size_t i = 0; i < NUM_STATS; i++) {
     statValues[i]->setText(QString(""));
@@ -127,19 +130,23 @@ void SampleLogDialogBase::showLogStatisticsOfItem(QTreeWidgetItem *item) {
       return;
 
     // Now the log
+    const auto &logName = item->text(0).toStdString();
     Mantid::Kernel::TimeSeriesPropertyStatistics stats;
-    Mantid::Kernel::Property *logData =
-        m_ei->run().getLogData(item->text(0).toStdString());
-    // Get the stas if its a series of int or double; fail otherwise
+    Mantid::Kernel::Property *logData = m_ei->run().getLogData(logName);
+    // Get the stats if its a series of int or double; fail otherwise
     Mantid::Kernel::TimeSeriesProperty<double> *tspd =
         dynamic_cast<TimeSeriesProperty<double> *>(logData);
     Mantid::Kernel::TimeSeriesProperty<int> *tspi =
         dynamic_cast<TimeSeriesProperty<int> *>(logData);
     double timeAvg = 0.;
+    LogFilterGenerator generator(filter, m_ei->run());
+    const auto &logFilter = generator.generateFilter(logName);
     if (tspd) {
+      ScopedFilter<double> applyFilter(tspd, std::move(logFilter));
       stats = tspd->getStatistics();
       timeAvg = tspd->timeAverageValue();
     } else if (tspi) {
+      ScopedFilter<int> applyFilter(tspi, std::move(logFilter));
       stats = tspi->getStatistics();
       timeAvg = tspi->timeAverageValue();
     } else
diff --git a/MantidPlot/src/Mantid/SampleLogDialogBase.h b/MantidPlot/src/Mantid/SampleLogDialogBase.h
index 855028f6848298f1bf1d113001df50b789537199..4def7f419a815051192d276248be366706125ff1 100644
--- a/MantidPlot/src/Mantid/SampleLogDialogBase.h
+++ b/MantidPlot/src/Mantid/SampleLogDialogBase.h
@@ -5,8 +5,10 @@
 // Includes
 //----------------------------------
 #include <QDialog>
-#include <MantidAPI/ExperimentInfo.h>
-
+#include "MantidAPI/ExperimentInfo.h"
+#include "MantidAPI/LogFilterGenerator.h"
+#include "MantidKernel/TimeSeriesProperty.h"
+#include <memory>
 //----------------------------------
 // Forward declarations
 //----------------------------------
@@ -73,7 +75,10 @@ protected slots:
 
   /// Show the stats of the selected log
   virtual void showLogStatistics();
-  virtual void showLogStatisticsOfItem(QTreeWidgetItem *item);
+  virtual void showLogStatisticsOfItem(
+      QTreeWidgetItem *item,
+      const Mantid::API::LogFilterGenerator::FilterType
+          filter = Mantid::API::LogFilterGenerator::FilterType::None);
 
   /// Context menu popup
   virtual void popupMenu(const QPoint &pos);
@@ -104,6 +109,11 @@ protected:
   /// Sets up the QTreeWidget's connections for functionality
   void setUpTreeWidgetConnections();
 
+  /// Which type of filtering is selected - in base class case, none
+  virtual Mantid::API::LogFilterGenerator::FilterType getFilterType() const {
+    return Mantid::API::LogFilterGenerator::FilterType::None;
+  }
+
   /// A tree widget
   QTreeWidget *m_tree;
 
@@ -143,4 +153,21 @@ protected:
   };
 };
 
+/// Object that applies a filter to a property for as long as it is in scope.
+/// When scope ends, filter is cleared.
+template <typename T> class ScopedFilter {
+public:
+  ScopedFilter(Mantid::Kernel::TimeSeriesProperty<T> *prop,
+               const std::unique_ptr<Mantid::Kernel::LogFilter> &logFilter)
+      : m_prop(prop) {
+    if (logFilter && logFilter->filter()) {
+      m_prop->filterWith(logFilter->filter());
+    }
+  }
+  ~ScopedFilter() { m_prop->clearFilter(); }
+
+private:
+  Mantid::Kernel::TimeSeriesProperty<T> *m_prop;
+};
+
 #endif // SAMPLELOGDIALOGBASE_H_
\ No newline at end of file
diff --git a/MantidPlot/src/MultiLayer.cpp b/MantidPlot/src/MultiLayer.cpp
index 9c610df2093e9c1a7a68509a9097b6803564a0d6..b0e5c5163dc15f20b1b9618e83ea14e43b1a98c9 100644
--- a/MantidPlot/src/MultiLayer.cpp
+++ b/MantidPlot/src/MultiLayer.cpp
@@ -66,6 +66,7 @@
 
 #include "Mantid/MantidMDCurve.h"
 #include "Mantid/MantidMatrixCurve.h"
+#include "MantidKernel/Strings.h"
 #include <MantidQtMantidWidgets/MantidTreeWidget.h>
 
 #include "Mantid/MantidMDCurveDialog.h"
@@ -1811,18 +1812,7 @@ MultiLayer::loadFromProject(const std::string &lines, ApplicationWindow *app,
 
       if (gtsv.selectLine("ggeometry")) {
         int x = 0, y = 0, w = 0, h = 0;
-        gtsv >> x >> y;
-
-        w = multiLayer->canvas->width();
-        w -= multiLayer->left_margin;
-        w -= multiLayer->right_margin;
-        w -= (multiLayer->d_cols - 1) * multiLayer->colsSpace;
-
-        h = multiLayer->canvas->height();
-        h -= multiLayer->top_margin;
-        h -= multiLayer->left_margin;
-        h -= (multiLayer->d_rows - 1) * multiLayer->rowsSpace;
-        h -= LayerButton::btnSize();
+        gtsv >> x >> y >> w >> h;
 
         if (isWaterfall)
           h -= LayerButton::btnSize(); // need an extra offset for the buttons
diff --git a/MantidPlot/src/Note.cpp b/MantidPlot/src/Note.cpp
index 0bcb0a4f7a4b1174b908062fff4662a85829b409..17d1dda76fff8779569357edaa7adece93cce554 100644
--- a/MantidPlot/src/Note.cpp
+++ b/MantidPlot/src/Note.cpp
@@ -35,15 +35,14 @@
 
 #include <QFileDialog>
 #include <QMessageBox>
+#include <QPrintDialog>
 #include <QTextCodec>
 #include <QTextStream>
 #include <Qsci/qsciprinter.h>
-#include <QPrintDialog>
 
 #include "ApplicationWindow.h"
 #include "MantidQtAPI/TSVSerialiser.h"
 #include "MantidKernel/ConfigService.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 
 // Register the window into the WindowFactory
 DECLARE_WINDOW(Note)
@@ -99,8 +98,8 @@ QString Note::exportASCII(const QString &filename) {
     QString dir(Mantid::Kernel::ConfigService::Instance()
                     .getString("defaultsave.directory")
                     .c_str());
-    fn = MantidQt::API::FileDialogHandler::getSaveFileName(
-        this, tr("Save Text to File"), dir, filter, &selectedFilter);
+    fn = QFileDialog::getSaveFileName(this, tr("Save Text to File"), dir,
+                                      filter, &selectedFilter);
   } else
     fn = filename;
 
diff --git a/MantidPlot/src/Plot3DDialog.cpp b/MantidPlot/src/Plot3DDialog.cpp
index 95f6eefff0a752f107a4cb3387d830d3796c5d96..6c5bc1536a9b967cc36b4583afec07b591233bdb 100644
--- a/MantidPlot/src/Plot3DDialog.cpp
+++ b/MantidPlot/src/Plot3DDialog.cpp
@@ -47,7 +47,6 @@
 #include <QMessageBox>
 #include <QComboBox>
 #include <QWidgetList>
-#include <QFileDialog>
 #include <QGroupBox>
 #include <QFontDialog>
 #include <QApplication>
diff --git a/MantidPlot/src/PlotDialog.cpp b/MantidPlot/src/PlotDialog.cpp
index cebc468f8f45f53042c4421336d7e9e85a3feec6..1626c4116b57644c4b77362c511793d890cfc9ff 100644
--- a/MantidPlot/src/PlotDialog.cpp
+++ b/MantidPlot/src/PlotDialog.cpp
@@ -54,7 +54,7 @@
 #include <QComboBox>
 #include <QDateTime>
 #include <QDoubleSpinBox>
-#include <QFileDialog>
+#include <QFileInfo>
 #include <QFontDialog>
 #include <QGroupBox>
 #include <QKeySequence>
diff --git a/MantidPlot/src/ProjectSerialiser.cpp b/MantidPlot/src/ProjectSerialiser.cpp
index 03c50f250f0f24f681b0e05559b51101281931b1..7c8f2022bfff5101120eba7d9385a62c98fc2eb2 100644
--- a/MantidPlot/src/ProjectSerialiser.cpp
+++ b/MantidPlot/src/ProjectSerialiser.cpp
@@ -12,6 +12,7 @@
 #include "Mantid/MantidMatrixFunction.h"
 #include "Mantid/MantidUI.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/MantidVersion.h"
 #include "MantidQtAPI/PlotAxis.h"
 #include "MantidQtAPI/VatesViewerInterface.h"
diff --git a/MantidPlot/src/ScriptOutputDisplay.cpp b/MantidPlot/src/ScriptOutputDisplay.cpp
index 39825ddb9f186efc474904ded0d1f9daec0b33d0..a87e936e17e1610cdd4e7edc7e7503f08fb479f6 100644
--- a/MantidPlot/src/ScriptOutputDisplay.cpp
+++ b/MantidPlot/src/ScriptOutputDisplay.cpp
@@ -4,7 +4,6 @@
 #include <MantidQtAPI/pixmaps.h>
 
 #include <QDateTime>
-#include <QFileDialog>
 #include <QKeyEvent>
 #include <QMenu>
 #include <QPrintDialog>
diff --git a/MantidPlot/src/ScriptingWindow.cpp b/MantidPlot/src/ScriptingWindow.cpp
index 646be1e419741ee2e7a7d1694c5e66a61cef1bb9..9f0ddfb2161b9e3ed6fd9425ea25dd57e83058c0 100644
--- a/MantidPlot/src/ScriptingWindow.cpp
+++ b/MantidPlot/src/ScriptingWindow.cpp
@@ -23,7 +23,7 @@
 #include <QApplication>
 #include <QCloseEvent>
 #include <QDateTime>
-#include <QFileDialog>
+#include <QFileInfo>
 #include <QList>
 #include <QMenu>
 #include <QMenuBar>
diff --git a/MantidPlot/src/Spectrogram.cpp b/MantidPlot/src/Spectrogram.cpp
index 1e543976b0c0415d6ddb354492322105e526c855..d4f536954234eba4f20bf318d0dff6627342dd96 100644
--- a/MantidPlot/src/Spectrogram.cpp
+++ b/MantidPlot/src/Spectrogram.cpp
@@ -39,6 +39,7 @@
 #include "Mantid/MantidMatrix.h"
 #include "Mantid/MantidMatrixFunction.h"
 #include "MantidAPI/IMDIterator.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidQtAPI/PlotAxis.h"
 #include "MantidQtAPI/QwtRasterDataMD.h"
diff --git a/MantidPlot/src/TextFileIO.cpp b/MantidPlot/src/TextFileIO.cpp
index 48a221a59613aebbe038c35294e3d52a6742659f..c6da8829961cb600c8cb85d07fd22bde0b0d69b8 100644
--- a/MantidPlot/src/TextFileIO.cpp
+++ b/MantidPlot/src/TextFileIO.cpp
@@ -1,13 +1,11 @@
 #include "TextFileIO.h"
+#include "MantidQtAPI/FileDialogHandler.h"
 
+#include <QApplication>
 #include <QFile>
 #include <QFileDialog>
-#include <QFileInfo>
 #include <QMessageBox>
 #include <QTextStream>
-#include <QApplication>
-
-#include "MantidQtAPI/FileDialogHandler.h"
 
 /**
  * Construct an object with a list of file filters
@@ -47,15 +45,8 @@ bool TextFileIO::save(const QString &txt, const QString &filename) const {
 QString TextFileIO::askWhereToSave() const {
   QString selectedFilter;
   QString filter = m_filters.join(";;");
-  QString filename = MantidQt::API::FileDialogHandler::getSaveFileName(
-      NULL, "MantidPlot - Save", "", filter, &selectedFilter);
-  if (filename.isEmpty())
-    return QString();
-  if (QFileInfo(filename).suffix().isEmpty()) {
-    QString ext = selectedFilter.section('(', 1).section(' ', 0, 0);
-    ext.remove(0, 1);
-    if (ext != ")")
-      filename += ext;
-  }
-  return filename;
+  QString filename = QFileDialog::getSaveFileName(NULL, "MantidPlot - Save", "",
+                                                  filter, &selectedFilter);
+  return MantidQt::API::FileDialogHandler::addExtension(filename,
+                                                        selectedFilter);
 }
diff --git a/MantidQt/API/CMakeLists.txt b/MantidQt/API/CMakeLists.txt
index f6cdaa1ed48eb1eae067d824aeece59f653ea6b8..4146c5d0fbcf1261bf700e327fe019f25dc586bc 100644
--- a/MantidQt/API/CMakeLists.txt
+++ b/MantidQt/API/CMakeLists.txt
@@ -5,6 +5,7 @@
 	src/AlgorithmRunner.cpp
 	src/BatchAlgorithmRunner.cpp
 	src/BoolPropertyWidget.cpp
+        src/FileDialogHandler.cpp
 	src/FilePropertyWidget.cpp
 	src/GenericDialog.cpp
 	src/HelpWindow.cpp
@@ -133,6 +134,7 @@ set ( UI_FILES
 
 set( TEST_FILES
    BatchAlgorithmRunnerTest.h
+   FileDialogHandlerTest.h
    InterfaceManagerTest.h
    MantidColorMapTest.h
    PlotAxisTest.h
diff --git a/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h b/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h
index 0e0ac3bd7249b3b946c162c27b9c428ff0b98e43..5e51a0644492fa49cfd1ecd549b82f7b65d20616 100644
--- a/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h
+++ b/MantidQt/API/inc/MantidQtAPI/BatchAlgorithmRunner.h
@@ -11,6 +11,8 @@
 #include <Poco/NObserver.h>
 #include <Poco/Void.h>
 
+#include <deque>
+
 namespace MantidQt {
 namespace API {
 /**
diff --git a/MantidQt/API/inc/MantidQtAPI/FileDialogHandler.h b/MantidQt/API/inc/MantidQtAPI/FileDialogHandler.h
index d11d77e47399815c75d8e5029f964ab416411ba8..f53bb16def2991340ed5631058d0375817fbd81e 100644
--- a/MantidQt/API/inc/MantidQtAPI/FileDialogHandler.h
+++ b/MantidQt/API/inc/MantidQtAPI/FileDialogHandler.h
@@ -1,12 +1,19 @@
 #ifndef MANTIDQT_API_FILEDIALOGHANDLER_H_
 #define MANTIDQT_API_FILEDIALOGHANDLER_H_
 
+#include "MantidKernel/DllConfig.h"
 #include <QFileDialog>
 #ifdef Q_OS_DARWIN
 #include <errno.h>
 #include <sys/sysctl.h>
 #endif
 
+namespace Mantid {
+namespace Kernel {
+class Property;
+}
+}
+
 namespace MantidQt {
 namespace API {
 /**
@@ -35,33 +42,41 @@ namespace API {
     File change history is stored at: <https://github.com/mantidproject/mantid>
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-struct FileDialogHandler {
-  /** The MacOS's native save dialog crashes when running a 10.6 package on 10.8
-  * so this function, which takes
-  *  the same arguments as the Qt function, ensures a nonnative object is used
-  * on the Mac when necessary.
-  *  If compiled on 10.8 the native will be used
-  *  @param parent :: the dialog will be shown centered over this parent widget
-  *  @param caption :: The dialog's caption
-  *  @param dir :: The file dialog's working directory will be set to dir. If
-  * dir includes a file name, the file will be selected
-  *  @param filter :: extensions of files to look for
-  *  @param selectedFilter :: pass a pointer an existing string that will be
-  * filled with the extension the user selected
-  *  @param options :: The options argument holds various options about how to
-  * run the dialog
+namespace FileDialogHandler {
+/**
+ * @param parent :: the dialog will be shown centered over this parent
+ * widget
+ * @param baseProp :: The property that the dialog parameters will be extracted
+ * from.
+ * @param options :: The options argument holds various options about how
+ * to run the dialog
   */
-  static QString getSaveFileName(QWidget *parent = 0,
-                                 const QString &caption = QString(),
-                                 const QString &dir = QString(),
-                                 const QString &filter = QString(),
-                                 QString *selectedFilter = 0,
-                                 QFileDialog::Options options = 0) {
-    options = options | QFileDialog::DontUseNativeDialog;
-    return QFileDialog::getSaveFileName(parent, caption, dir, filter,
-                                        selectedFilter, options);
-  }
-};
+DLLExport QString getSaveFileName(QWidget *parent = 0,
+                                  const Mantid::Kernel::Property *baseProp = 0,
+                                  QFileDialog::Options options = 0);
+
+/**
+ * For file dialogs. This will add the selected extension if an extension
+ * doesn't
+ * already exist.
+ */
+DLLExport QString
+addExtension(const QString &filename, const QString &selectedFilter);
+
+DLLExport QString getFilter(const Mantid::Kernel::Property *baseProp);
+
+/** For file dialogs
+ *
+ * @param exts :: vector of extensions
+ * @param defaultExt :: default extension to use
+ * @return a string that filters files by extenstions
+ */
+DLLExport QString
+getFilter(const std::vector<std::string> &exts, const std::string &defaultExt);
+
+DLLExport QString
+getCaption(const std::string &dialogName, const Mantid::Kernel::Property *prop);
+}
 }
 }
 
diff --git a/MantidQt/API/inc/MantidQtAPI/VatesViewerInterface.h b/MantidQt/API/inc/MantidQtAPI/VatesViewerInterface.h
index 900937d14358e19d99f5f2e106efe7da02b7fe46..038a863c0aa8bb2438c0aa6ca936a08d1093f22e 100644
--- a/MantidQt/API/inc/MantidQtAPI/VatesViewerInterface.h
+++ b/MantidQt/API/inc/MantidQtAPI/VatesViewerInterface.h
@@ -68,7 +68,7 @@ public:
   /**
    * Special function of correct widget invocation for plugin mode.
    */
-  virtual void setupPluginMode();
+  virtual void setupPluginMode(int WsType, const std::string &instrumentName);
 
   /// Static method to create a handle to new window instance
   static IProjectSerialisable *loadFromProject(const std::string &lines,
diff --git a/MantidQt/API/src/AlgorithmDialog.cpp b/MantidQt/API/src/AlgorithmDialog.cpp
index 0addeb5985764e8228fa348cb75a35922c8b0f28..f4f0cbee9259fda500af5aaccd3fde30ceaf75a1 100644
--- a/MantidQt/API/src/AlgorithmDialog.cpp
+++ b/MantidQt/API/src/AlgorithmDialog.cpp
@@ -1,9 +1,7 @@
-//----------------------------------
-// Includes
-//----------------------------------
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidKernel/DateAndTime.h"
+#include "MantidKernel/IPropertySettings.h"
 #include "MantidKernel/Logger.h"
 
 #include "MantidQtAPI/AlgorithmDialog.h"
diff --git a/MantidQt/API/src/AlgorithmPropertiesWidget.cpp b/MantidQt/API/src/AlgorithmPropertiesWidget.cpp
index 9ad793f078832ccd64e222a860d922d051f81590..5f1a75078960660c3bda06d67f5caab26570ab31 100644
--- a/MantidQt/API/src/AlgorithmPropertiesWidget.cpp
+++ b/MantidQt/API/src/AlgorithmPropertiesWidget.cpp
@@ -1,3 +1,4 @@
+#include "MantidKernel/IPropertySettings.h"
 #include "MantidKernel/Property.h"
 #include "MantidKernel/System.h"
 #include "MantidQtAPI/AlgorithmPropertiesWidget.h"
diff --git a/MantidQt/API/src/FileDialogHandler.cpp b/MantidQt/API/src/FileDialogHandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b355c1765da484a4982676101d92d8a96d153a02
--- /dev/null
+++ b/MantidQt/API/src/FileDialogHandler.cpp
@@ -0,0 +1,167 @@
+#include "MantidQtAPI/FileDialogHandler.h"
+#include "MantidAPI/FileProperty.h"
+#include "MantidAPI/MultipleFileProperty.h"
+#include "MantidQtAPI/AlgorithmInputHistory.h"
+#include <boost/regex.hpp>
+
+namespace { // anonymous namespace
+const boost::regex FILE_EXT_REG_EXP{"^.+\\s+\\((\\S+)\\)$"};
+const QString ALL_FILES("All Files (*)");
+
+QString getExtensionFromFilter(const QString &selectedFilter) {
+  // empty returns empty
+  if (selectedFilter.isEmpty()) {
+    return QString("");
+  }
+
+  // search for single extension
+  boost::smatch result;
+  if (boost::regex_search(selectedFilter.toStdString(), result,
+                          FILE_EXT_REG_EXP) &&
+      result.size() == 2) {
+    auto extension = QString::fromStdString(result[1]);
+    if (extension.startsWith("*"))
+      return extension.remove(0, 1);
+    else
+      return extension;
+  } else {
+    // failure to match suggests multi-extension filter
+    std::stringstream msg;
+    msg << "Failed to determine single extension from \""
+        << selectedFilter.toStdString() << "\"";
+    throw std::runtime_error(msg.str());
+  }
+}
+} // anonymous namespace
+
+namespace MantidQt {
+namespace API {
+namespace FileDialogHandler {
+/**
+    Contains modifications to Qt functions where problems have been found
+    on certain operating systems
+
+    Copyright &copy; 2009-2010 ISIS Rutherford Appleton Laboratory, NScD Oak
+   Ridge National Laboratory & European Spallation Source
+    @date 17/09/2010
+
+    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>
+*/
+QString getSaveFileName(QWidget *parent,
+                        const Mantid::Kernel::Property *baseProp,
+                        QFileDialog::Options options) {
+  // set up filters and dialog title
+  const auto filter = getFilter(baseProp);
+  const auto caption = getCaption("Save file", baseProp);
+
+  QString selectedFilter;
+
+  // create the file browser
+  QString filename = QFileDialog::getSaveFileName(
+      parent, caption, AlgorithmInputHistory::Instance().getPreviousDirectory(),
+      filter, &selectedFilter, options);
+
+  return addExtension(filename, selectedFilter);
+}
+
+QString addExtension(const QString &filename, const QString &selectedFilter) {
+  // just return an empty string if that is what was given
+  if (filename.isEmpty())
+    return filename;
+
+  // Check the filename and append the selected filter if necessary
+  if (QFileInfo(filename).completeSuffix().isEmpty()) {
+    auto ext = getExtensionFromFilter(selectedFilter);
+    if (filename.endsWith(".") && ext.startsWith(".")) {
+      ext = ext.remove(0, 1);
+    }
+    return filename + ext;
+  } else {
+    return filename;
+  }
+}
+
+QString getFilter(const Mantid::Kernel::Property *baseProp) {
+  if (!baseProp)
+    return ALL_FILES;
+
+  // multiple file version
+  const auto *multiProp =
+      dynamic_cast<const Mantid::API::MultipleFileProperty *>(baseProp);
+  if (bool(multiProp))
+    return getFilter(multiProp->getExts(), multiProp->getDefaultExt());
+
+  // regular file version
+  const auto *singleProp =
+      dynamic_cast<const Mantid::API::FileProperty *>(baseProp);
+  // The allowed values in this context are file extensions
+  if (bool(singleProp))
+    return getFilter(singleProp->allowedValues(), singleProp->getDefaultExt());
+
+  // otherwise only the all files exists
+  return ALL_FILES;
+}
+
+/** For file dialogs. Have each filter on a separate line with the default as
+ * the first.
+ *
+ * @param exts :: vector of extensions
+ * @param defaultExt :: default extension to use
+ * @return a string that filters files by extenstions
+ */
+QString getFilter(const std::vector<std::string> &exts,
+                  const std::string &defaultExt) {
+  QString filter("");
+
+  if (!defaultExt.empty()) {
+    filter.append(QString::fromStdString(defaultExt) + " (*" +
+                  QString::fromStdString(defaultExt) + ");;");
+  }
+
+  if (!exts.empty()) {
+    // Push a wild-card onto the front of each file suffix
+    for (auto &itr : exts) {
+      if (itr != defaultExt) {
+        filter.append(QString::fromStdString(itr) + " (*" +
+                      QString::fromStdString(itr) + ");;");
+      }
+    }
+    filter = filter.trimmed();
+  }
+  filter.append(ALL_FILES);
+  return filter;
+}
+
+QString getCaption(const std::string &dialogName,
+                   const Mantid::Kernel::Property *prop) {
+  // generate the dialog title
+  auto dialogTitle = QString::fromStdString(dialogName);
+  if (bool(prop)) {
+    const auto name = prop->name();
+    if (name != "Filename" && prop->name() != "Directory" &&
+        prop->name() != "Dir") {
+      dialogTitle.append(" - ");
+      dialogTitle.append(QString::fromStdString(name));
+    }
+  }
+  return dialogTitle;
+}
+}
+}
+}
diff --git a/MantidQt/API/src/FilePropertyWidget.cpp b/MantidQt/API/src/FilePropertyWidget.cpp
index 4e84296181e106943e33dfdbf808ae1f526bcc92..f640f64cd3c4127b028faf25d270ed1473d4b11b 100644
--- a/MantidQt/API/src/FilePropertyWidget.cpp
+++ b/MantidQt/API/src/FilePropertyWidget.cpp
@@ -77,38 +77,6 @@ void FilePropertyWidget::browseClicked() {
   }
 }
 
-//-------------------------------------------------------------------------------------------------
-/** For file dialogs
- *
- * @param exts :: vector of extensions
- * @param defaultExt :: default extension to use
- * @return a string that filters files by extenstions
- */
-QString getFileDialogFilter(const std::vector<std::string> &exts,
-                            const std::string &defaultExt) {
-  QString filter("");
-
-  if (!defaultExt.empty()) {
-    filter.append(QString::fromStdString(defaultExt) + " (*" +
-                  QString::fromStdString(defaultExt) + ");;");
-  }
-
-  if (!exts.empty()) {
-    // --------- Load a File -------------
-    auto iend = exts.end();
-    // Push a wild-card onto the front of each file suffix
-    for (auto itr = exts.begin(); itr != iend; ++itr) {
-      if ((*itr) != defaultExt) {
-        filter.append(QString::fromStdString(*itr) + " (*" +
-                      QString::fromStdString(*itr) + ");;");
-      }
-    }
-    filter = filter.trimmed();
-  }
-  filter.append("All Files (*)");
-  return filter;
-}
-
 //----------------------------------------------------------------------------------------------
 /** Open the file dialog for a given property
  *
@@ -121,10 +89,6 @@ QString FilePropertyWidget::openFileDialog(Mantid::Kernel::Property *baseProp) {
   if (!prop)
     return "";
 
-  // The allowed values in this context are file extensions
-  std::vector<std::string> exts = prop->allowedValues();
-  std::string defaultExt = prop->getDefaultExt();
-
   /* MG 20/07/09: Static functions such as these that use native Windows and MAC
      dialogs
      in those environments are alot faster. This is unforunately at the expense
@@ -133,55 +97,18 @@ QString FilePropertyWidget::openFileDialog(Mantid::Kernel::Property *baseProp) {
   */
   QString filename;
   if (prop->isLoadProperty()) {
-    QString filter = getFileDialogFilter(exts, defaultExt);
+    const auto filter = FileDialogHandler::getFilter(baseProp);
+    const auto caption = FileDialogHandler::getCaption("Open file", baseProp);
     filename = QFileDialog::getOpenFileName(
-        NULL, "Open file",
+        nullptr, caption,
         AlgorithmInputHistory::Instance().getPreviousDirectory(), filter);
   } else if (prop->isSaveProperty()) {
-    // --------- Save a File -------------
-    // Have each filter on a separate line with the default as the first
-    QString filter;
-    if (!defaultExt.empty()) {
-      filter = "*" + QString::fromStdString(defaultExt) + ";;";
-    }
-    auto iend = exts.end();
-    for (auto itr = exts.begin(); itr != iend; ++itr) {
-      if ((*itr) != defaultExt) {
-        filter.append("*" + QString::fromStdString(*itr) + ";;");
-      }
-    }
-    // Remove last two semi-colons or else we get an extra empty option in the
-    // box
-    filter.chop(2);
-    // Prepend the default filter
-    QString selectedFilter;
-    filename = MantidQt::API::FileDialogHandler::getSaveFileName(
-        NULL, "Save file",
-        AlgorithmInputHistory::Instance().getPreviousDirectory(), filter,
-        &selectedFilter);
-
-    // Check the filename and append the selected filter if necessary
-    if (QFileInfo(filename).completeSuffix().isEmpty()) {
-      // Hack off the first star that the filter returns
-      QString ext = selectedFilter;
-
-      if (selectedFilter.startsWith("*.")) {
-        // 1 character from the start
-        ext = ext.remove(0, 1);
-      } else {
-        ext = "";
-      }
-
-      if (filename.endsWith(".") && ext.startsWith(".")) {
-        ext = ext.remove(0, 1);
-      }
-
-      // Construct the full file name
-      filename += ext;
-    }
+    filename = FileDialogHandler::getSaveFileName(nullptr, prop);
   } else if (prop->isDirectoryProperty()) {
+    const auto caption =
+        FileDialogHandler::getCaption("Choose a Directory", baseProp);
     filename = QFileDialog::getExistingDirectory(
-        NULL, "Choose a Directory",
+        nullptr, caption,
         AlgorithmInputHistory::Instance().getPreviousDirectory());
   } else {
     throw std::runtime_error(
@@ -211,9 +138,9 @@ FilePropertyWidget::openMultipleFileDialog(Mantid::Kernel::Property *baseProp) {
   if (!prop)
     return QStringList();
 
-  QString filter = getFileDialogFilter(prop->getExts(), prop->getDefaultExt());
+  const auto filter = FileDialogHandler::getFilter(baseProp);
   QStringList files = QFileDialog::getOpenFileNames(
-      NULL, "Open Multiple Files",
+      nullptr, "Open Multiple Files",
       AlgorithmInputHistory::Instance().getPreviousDirectory(), filter);
 
   return files;
diff --git a/MantidQt/API/src/PlotAxis.cpp b/MantidQt/API/src/PlotAxis.cpp
index a0a4989db8b221c856283b5130e02d099487b42e..5e3e3a9200a037d9531193a768f0aeafb2becb66 100644
--- a/MantidQt/API/src/PlotAxis.cpp
+++ b/MantidQt/API/src/PlotAxis.cpp
@@ -4,6 +4,8 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidKernel/Unit.h"
 
+#include <boost/lexical_cast.hpp>
+
 namespace MantidQt {
 namespace API {
 
diff --git a/MantidQt/API/src/PropertyWidget.cpp b/MantidQt/API/src/PropertyWidget.cpp
index d8d1beb69364acb1d379828772c42a99920fc554..d107b81aebe7a7e137a547d16153c232c972dfe1 100644
--- a/MantidQt/API/src/PropertyWidget.cpp
+++ b/MantidQt/API/src/PropertyWidget.cpp
@@ -11,6 +11,7 @@
 #include <cfloat>
 
 #include <algorithm>
+#include <sstream>
 
 #include <QLineEdit>
 
diff --git a/MantidQt/API/src/QwtWorkspaceBinData.cpp b/MantidQt/API/src/QwtWorkspaceBinData.cpp
index 37e9454000f0557cbe4283efdcd90a9ea2f5d786..1408a915bf058796e1eab73bbab25a4042fc90eb 100644
--- a/MantidQt/API/src/QwtWorkspaceBinData.cpp
+++ b/MantidQt/API/src/QwtWorkspaceBinData.cpp
@@ -5,6 +5,7 @@
 #include "MantidQtAPI/PlotAxis.h"
 
 #include <QStringBuilder>
+#include <sstream>
 
 /// Constructor
 QwtWorkspaceBinData::QwtWorkspaceBinData(
@@ -121,4 +122,4 @@ void QwtWorkspaceBinData::init(const Mantid::API::MatrixWorkspace &workspace) {
 
   // Calculate the min and max values
   calculateYMinAndMax();
-}
\ No newline at end of file
+}
diff --git a/MantidQt/API/src/UserSubWindow.cpp b/MantidQt/API/src/UserSubWindow.cpp
index 33b432775f22cba222e244e8103e813d19cc006f..13eb293f1d2edcbef273dfd101c55a535704ec3a 100644
--- a/MantidQt/API/src/UserSubWindow.cpp
+++ b/MantidQt/API/src/UserSubWindow.cpp
@@ -2,7 +2,6 @@
 // Includes
 //----------------------------------
 #include "MantidQtAPI/AlgorithmInputHistory.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/UserSubWindow.h"
 #include "MantidKernel/UsageService.h"
 
@@ -129,7 +128,7 @@ QString UserSubWindow::openFileDialog(const bool save,
 
   QString filename;
   if (save) {
-    filename = MantidQt::API::FileDialogHandler::getSaveFileName(
+    filename = QFileDialog::getSaveFileName(
         this, "Save file",
         AlgorithmInputHistory::Instance().getPreviousDirectory(), filter);
   } else {
diff --git a/MantidQt/API/src/VatesViewerInterface.cpp b/MantidQt/API/src/VatesViewerInterface.cpp
index e4f07009c47d62f250650714b113b303d71b46e1..02ead09c5a0df0910fdf3b4c466ecb2e078319bf 100644
--- a/MantidQt/API/src/VatesViewerInterface.cpp
+++ b/MantidQt/API/src/VatesViewerInterface.cpp
@@ -9,7 +9,8 @@ VatesViewerInterface::VatesViewerInterface(QWidget *parent) : QWidget(parent) {}
 
 VatesViewerInterface::~VatesViewerInterface() {}
 
-void VatesViewerInterface::setupPluginMode() {}
+void VatesViewerInterface::setupPluginMode(
+    int /*WsType*/, const std::string & /*instrumentName*/) {}
 
 void VatesViewerInterface::renderWorkspace(QString workSpaceName,
                                            int workspaceType,
diff --git a/MantidQt/API/test/BatchAlgorithmRunnerTest.h b/MantidQt/API/test/BatchAlgorithmRunnerTest.h
index 9cf971a861c70378b834ac85b11d3ffe23ccc9b8..4ef631fb1868c0530d04ae162121719cefdfe6da 100644
--- a/MantidQt/API/test/BatchAlgorithmRunnerTest.h
+++ b/MantidQt/API/test/BatchAlgorithmRunnerTest.h
@@ -4,8 +4,10 @@
 #include <cxxtest/TestSuite.h>
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceHistory.h"
 #include "MantidQtAPI/BatchAlgorithmRunner.h"
 
 using namespace Mantid::API;
diff --git a/MantidQt/API/test/FileDialogHandlerTest.h b/MantidQt/API/test/FileDialogHandlerTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..b73532723f792817ea44594532f5c5cffb925694
--- /dev/null
+++ b/MantidQt/API/test/FileDialogHandlerTest.h
@@ -0,0 +1,66 @@
+#ifndef MANTIDQT_API_FILEDIALOGHANDLERTEST_H_
+#define MANTIDQT_API_FILEDIALOGHANDLERTEST_H_
+
+#include "MantidQtAPI/FileDialogHandler.h"
+#include <cxxtest/TestSuite.h>
+
+class FileDialogHandlerTest : public CxxTest::TestSuite {
+public:
+  void test_addExtension() {
+    // --- single extensions
+    const QString singleExt(".nxs (*.nxs)");
+    const QString nexusResult("/tmp/testing.nxs");
+
+    auto result1 = MantidQt::API::FileDialogHandler::addExtension(
+        QString::fromStdString("/tmp/testing"), singleExt);
+    TS_ASSERT_EQUALS(nexusResult.toStdString(), result1.toStdString());
+
+    auto result2 = MantidQt::API::FileDialogHandler::addExtension(
+        QString::fromStdString("/tmp/testing."), singleExt);
+    TS_ASSERT_EQUALS(nexusResult.toStdString(), result2.toStdString());
+
+    auto result3 =
+        MantidQt::API::FileDialogHandler::addExtension(nexusResult, singleExt);
+    TS_ASSERT_EQUALS(nexusResult.toStdString(), result3.toStdString());
+
+    // don't override if it is already specified
+    const QString singleH5("/tmp/testing.h5");
+    auto result4 =
+        MantidQt::API::FileDialogHandler::addExtension(singleH5, singleExt);
+    TS_ASSERT_EQUALS(singleH5.toStdString(), result4.toStdString());
+
+    // --- double extensions
+    const QString doubleExt("JPEG (*.jpg *.jpeg)");
+    const QString jpegResult("/tmp/testing.jpg");
+
+    // this can't work because you can't determine one extension
+    TS_ASSERT_THROWS(MantidQt::API::FileDialogHandler::addExtension(
+                         QString::fromStdString("/tmp/testing"), doubleExt),
+                     std::runtime_error);
+
+    // this shouldn't do anything
+    auto result5 =
+        MantidQt::API::FileDialogHandler::addExtension(jpegResult, doubleExt);
+    TS_ASSERT_EQUALS(jpegResult.toStdString(), result5.toStdString());
+  }
+
+  void test_getFileDialogFilter() {
+    std::vector<std::string> exts({"*.h5", "*.nxs"});
+
+    const auto result1 = MantidQt::API::FileDialogHandler::getFilter(
+        std::vector<std::string>(), std::string(""));
+    TS_ASSERT_EQUALS(std::string("All Files (*)"), result1.toStdString());
+
+    const auto result2 =
+        MantidQt::API::FileDialogHandler::getFilter(exts, std::string(""));
+    TS_ASSERT_EQUALS(std::string("*.h5 (**.h5);;*.nxs (**.nxs);;All Files (*)"),
+                     result2.toStdString());
+
+    const auto result3 =
+        MantidQt::API::FileDialogHandler::getFilter(exts, std::string("*.nxs"));
+    TS_ASSERT_EQUALS(std::string("*.nxs (**.nxs);;*.h5 (**.h5);;All Files (*)"),
+                     result3.toStdString());
+  }
+};
+
+#endif /* MANTIDQT_API_FILEDIALOGHANDLERTEST_H_ */
diff --git a/MantidQt/API/test/PlotAxisTest.h b/MantidQt/API/test/PlotAxisTest.h
index d130313dd3032e75f832fd581019b28f5cd9f098..f1a0d9721789457a211b8d89df10b055e0ae6d72 100644
--- a/MantidQt/API/test/PlotAxisTest.h
+++ b/MantidQt/API/test/PlotAxisTest.h
@@ -43,7 +43,7 @@ public:
 
   void test_NoUnit_On_Indexed_Axis_Prints_Default() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->replaceAxis(1, new Mantid::API::NumericAxis(1));
     TS_ASSERT_EQUALS("X axis", PlotAxis(*ws, 0).title());
     TS_ASSERT_EQUALS("Y axis", PlotAxis(*ws, 1).title());
@@ -51,7 +51,7 @@ public:
 
   void test_Empty_Unit_And_Empty_Axis_Title_On_Indexed_Axis_Prints_Default() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->getAxis(0)->setUnit("Empty");
     ws->replaceAxis(1, new Mantid::API::NumericAxis(1));
     ws->getAxis(1)->setUnit("Empty");
@@ -61,7 +61,7 @@ public:
 
   void test_Empty_Unit_And_Non_Empty_Title_On_Indexed_Axis_Prints_Title() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->getAxis(0)->setUnit("Empty");
     auto *ax0 = ws->getAxis(0);
     ax0->setUnit("Empty");
@@ -76,7 +76,7 @@ public:
 
   void test_Axis_With_Unit_Has_Label_In_Parentheses() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->getAxis(0)->setUnit("TOF");
     ws->replaceAxis(1, new Mantid::API::NumericAxis(1));
     ws->getAxis(1)->setUnit("TOF");
@@ -88,7 +88,7 @@ public:
   void test_Axis_With_Y_Axis_Normalised_By_X_Axis_Unit() {
     using MantidQt::API::PlotAxis;
     using Mantid::Kernel::UnitLabel;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->getAxis(0)->setUnit("TOF");
     const auto xunit = ws->getAxis(0)->unit();
     const auto lbl = xunit->label();
@@ -102,14 +102,14 @@ public:
   void test_Axis_With_Unit_But_Empty_Utf8_Lable_Uses_Ascii_In_Parentheses() {
     using MantidQt::API::PlotAxis;
     using Mantid::Kernel::Units::Degrees;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->getAxis(0)->unit() = boost::make_shared<EmptyUtf8Label>();
     TS_ASSERT_EQUALS("Caption (unittext)", PlotAxis(*ws, 0).title());
   }
 
   void test_SpectraAxis_Gives_Standard_Text() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->replaceAxis(0, new Mantid::API::SpectraAxis(ws.get()));
     TS_ASSERT_EQUALS("Spectrum", PlotAxis(*ws, 0).title());
     TS_ASSERT_EQUALS("Spectrum", PlotAxis(*ws, 1).title());
@@ -118,7 +118,7 @@ public:
   void
   test_Passing_Workspace_Not_Plotting_As_Distribution_Creates_UnitLess_Title_For_Y_Data() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->setYUnit("Counts");
     TS_ASSERT_EQUALS("Counts", PlotAxis(false, *ws).title());
   }
@@ -126,7 +126,7 @@ public:
   void
   test_Passing_Workspace_And_Plotting_As_Distribution_Creates_UnitLess_Title_For_Y_Data() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     ws->setYUnit("Counts");
     TS_ASSERT_EQUALS("Counts", PlotAxis(true, *ws).title());
   }
@@ -148,7 +148,7 @@ public:
   void
   test_Index_Greater_Than_numDims_Or_Less_Than_Zero_Throws_Invalid_Argument() {
     using MantidQt::API::PlotAxis;
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace(1, 1);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace(1, 1);
     TS_ASSERT_THROWS(PlotAxis(*ws, 2), std::invalid_argument);
     TS_ASSERT_THROWS(PlotAxis(*ws, -1), std::invalid_argument);
   }
diff --git a/MantidQt/API/test/QwtWorkspaceBinDataTest.h b/MantidQt/API/test/QwtWorkspaceBinDataTest.h
index 5a7cab60963beba78c2a10d3b8e92312bd848fe6..421b54d022e954fa70c802e73bac0f6b62a00c7a 100644
--- a/MantidQt/API/test/QwtWorkspaceBinDataTest.h
+++ b/MantidQt/API/test/QwtWorkspaceBinDataTest.h
@@ -13,7 +13,7 @@ class QwtWorkspaceBinDataTest : public CxxTest::TestSuite {
 
 public:
   void setUp() override {
-    ws = WorkspaceCreationHelper::Create2DWorkspace(3, 4);
+    ws = WorkspaceCreationHelper::create2DWorkspace(3, 4);
     auto *ax1 = new Mantid::API::NumericAxis(3);
     ws->replaceAxis(1, ax1);
     for (size_t i = 0; i < 3; i++) {
diff --git a/MantidQt/API/test/QwtWorkspaceSpectrumDataTest.h b/MantidQt/API/test/QwtWorkspaceSpectrumDataTest.h
index fab0e833a7799958bd72c324c781563263fce52e..f16528cb86eb8aea6c4ce09fc2e28ce51dbbde77 100644
--- a/MantidQt/API/test/QwtWorkspaceSpectrumDataTest.h
+++ b/MantidQt/API/test/QwtWorkspaceSpectrumDataTest.h
@@ -13,7 +13,7 @@ class QwtWorkspaceSpectrumDataTest : public CxxTest::TestSuite {
 
 public:
   void setUp() override {
-    ws = WorkspaceCreationHelper::Create2DWorkspace(3, 4);
+    ws = WorkspaceCreationHelper::create2DWorkspace(3, 4);
     for (size_t i = 0; i < 3; i++) {
       for (size_t j = 0; j < 5; j++)
         ws->dataX(i)[j] = double(i) + double(j);
diff --git a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.h b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.h
index 47968140a5856630940a4c19a488f4e7dda9b4da..7a1572dc07940a7ec82f46282e3bc17cf89811ec 100644
--- a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.h
+++ b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.h
@@ -34,6 +34,8 @@ private slots:
   void updateUiElements(const QString &);
   void accept() override;
   void initListenerPropLayout(const QString &);
+  void updateConnectionChoices(const QString &inst_name);
+  void updateConnectionDetails(const QString &connection);
 
 private:
   /// Initialize the layout
@@ -63,6 +65,9 @@ private:
 
   /// The algorithm for processing the accumulated workspace
   Mantid::API::Algorithm_sptr m_postProcessingAlg;
+
+  /// Constant used for custom listener connection setups
+  static const QString CUSTOM_CONNECTION;
 };
 }
 }
diff --git a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.ui b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.ui
index f472b6b467df1ac6f5b9b05b8588109d6f739609..3e8796f7c606b5af30a946fc1090a267d5696183 100644
--- a/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.ui
+++ b/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/StartLiveDataDialog.ui
@@ -28,80 +28,118 @@
       </property>
       <layout class="QVBoxLayout" name="widgetLeftLayout">
        <item>
-        <layout class="QHBoxLayout" name="horizontalLayout_5">
-         <item>
+        <layout class="QGridLayout" name="gridLayout_3">
+         <item row="0" column="0">
           <widget class="QLabel" name="lblInstrument">
            <property name="text">
             <string>Instrument:</string>
            </property>
           </widget>
          </item>
-         <item>
+         <item row="1" column="1">
+          <widget class="QComboBox" name="cmbConnection"/>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="lblConnection">
+           <property name="text">
+            <string>Connection:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1">
           <widget class="QComboBox" name="cmbInstrument"/>
          </item>
         </layout>
        </item>
        <item>
-        <widget class="QGroupBox" name="groupBox">
+        <widget class="QGroupBox" name="grpConnection">
          <property name="styleSheet">
           <string notr="true">QGroupBox { border: 1px solid gray;  border-radius: 4px; font-weight: bold; margin-top: 4px; margin-bottom: 4px; padding-top: 16px; }
 QGroupBox::title { background-color: transparent;  subcontrol-position: top center;  padding-top:4px; padding-bottom:4px; } 
 </string>
          </property>
          <property name="title">
-          <string>Starting Time</string>
+          <string>Connection Parameters</string>
          </property>
-         <layout class="QVBoxLayout" name="verticalLayout_4">
+         <layout class="QVBoxLayout" name="verticalLayout">
           <item>
-           <layout class="QHBoxLayout" name="horizontalLayout">
-            <item>
-             <widget class="QRadioButton" name="radNow">
-              <property name="toolTip">
-               <string>Start collecting data from current time</string>
-              </property>
+           <layout class="QGridLayout" name="gridLayout_2">
+            <item row="0" column="1">
+             <widget class="QComboBox" name="cmbConnListener"/>
+            </item>
+            <item row="0" column="0">
+             <widget class="QLabel" name="lblConnListener">
               <property name="text">
-               <string>Now</string>
-              </property>
-              <property name="checked">
-               <bool>true</bool>
+               <string>Listener Type:</string>
               </property>
              </widget>
             </item>
-            <item>
-             <widget class="QRadioButton" name="radStartOfRun">
-              <property name="toolTip">
-               <string>Start processing data from the beginning of the current run</string>
-              </property>
+            <item row="1" column="0">
+             <widget class="QLabel" name="lblConnAddress">
               <property name="text">
-               <string>Start of Run</string>
+               <string>Address String:</string>
               </property>
              </widget>
             </item>
-            <item>
-             <spacer name="horizontalSpacer">
-              <property name="orientation">
-               <enum>Qt::Horizontal</enum>
-              </property>
-              <property name="sizeHint" stdset="0">
-               <size>
-                <width>40</width>
-                <height>20</height>
-               </size>
+            <item row="1" column="1">
+             <widget class="QLineEdit" name="edtConnAddress">
+              <property name="sizePolicy">
+               <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                <horstretch>0</horstretch>
+                <verstretch>0</verstretch>
+               </sizepolicy>
               </property>
-             </spacer>
+             </widget>
             </item>
            </layout>
           </item>
+         </layout>
+        </widget>
+       </item>
+       <item>
+        <widget class="QGroupBox" name="groupBox">
+         <property name="styleSheet">
+          <string notr="true">QGroupBox { border: 1px solid gray;  border-radius: 4px; font-weight: bold; margin-top: 4px; margin-bottom: 4px; padding-top: 16px; }
+QGroupBox::title { background-color: transparent;  subcontrol-position: top center;  padding-top:4px; padding-bottom:4px; } 
+</string>
+         </property>
+         <property name="title">
+          <string>Starting Time</string>
+         </property>
+         <layout class="QVBoxLayout" name="verticalLayout_4">
+          <property name="spacing">
+           <number>2</number>
+          </property>
+          <item>
+           <widget class="QRadioButton" name="radNow">
+            <property name="toolTip">
+             <string>Start collecting data from current time</string>
+            </property>
+            <property name="text">
+             <string>Now</string>
+            </property>
+            <property name="checked">
+             <bool>true</bool>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QRadioButton" name="radStartOfRun">
+            <property name="toolTip">
+             <string>Start processing data from the beginning of the current run</string>
+            </property>
+            <property name="text">
+             <string>Start of Run</string>
+            </property>
+           </widget>
+          </item>
           <item>
            <layout class="QHBoxLayout" name="horizontalLayout_4">
+            <property name="spacing">
+             <number>6</number>
+            </property>
             <item>
              <widget class="QRadioButton" name="radAbsoluteTime">
-              <property name="maximumSize">
-               <size>
-                <width>17</width>
-                <height>16777215</height>
-               </size>
-              </property>
               <property name="toolTip">
                <string>Start collecting data from a specific time:</string>
               </property>
@@ -174,19 +212,6 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_8">
-         <item>
-          <spacer name="horizontalSpacer_4">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item>
           <widget class="QGroupBox" name="grpProcess">
            <property name="styleSheet">
@@ -198,6 +223,9 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
             <string>Processing</string>
            </property>
            <layout class="QVBoxLayout" name="verticalLayout_5">
+            <property name="spacing">
+             <number>2</number>
+            </property>
             <item>
              <widget class="QRadioButton" name="radProcessNone">
               <property name="toolTip">
@@ -234,36 +262,10 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
            </layout>
           </widget>
          </item>
-         <item>
-          <spacer name="horizontalSpacer_3">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_3">
-         <item>
-          <spacer name="horizontalSpacer_9">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item>
           <widget class="QCheckBox" name="chkPreserveEvents">
            <property name="text">
@@ -271,19 +273,6 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
            </property>
           </widget>
          </item>
-         <item>
-          <spacer name="horizontalSpacer_10">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </item>
        <item>
@@ -302,19 +291,6 @@ p, li { white-space: pre-wrap; }
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_7">
-         <item>
-          <spacer name="horizontalSpacer_8">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item>
           <widget class="QLabel" name="lblInstrument_2">
            <property name="text">
@@ -325,36 +301,10 @@ p, li { white-space: pre-wrap; }
          <item>
           <widget class="QComboBox" name="cmbAccumulationMethod"/>
          </item>
-         <item>
-          <spacer name="horizontalSpacer_7">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_9">
-         <item>
-          <spacer name="horizontalSpacer_5">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item>
           <widget class="QGroupBox" name="grpPostProcessing">
            <property name="styleSheet">
@@ -366,6 +316,9 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
             <string>Post Processing</string>
            </property>
            <layout class="QVBoxLayout" name="verticalLayout_7">
+            <property name="spacing">
+             <number>2</number>
+            </property>
             <item>
              <widget class="QRadioButton" name="radPostProcessNone">
               <property name="toolTip">
@@ -402,36 +355,10 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
            </layout>
           </widget>
          </item>
-         <item>
-          <spacer name="horizontalSpacer_6">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </item>
        <item>
         <layout class="QHBoxLayout" name="horizontalLayout_6">
-         <item>
-          <spacer name="horizontalSpacer_11">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
          <item>
           <widget class="QLabel" name="lblRunTransitionBehavior">
            <property name="text">
@@ -442,19 +369,6 @@ QGroupBox::title { background-color: transparent;  subcontrol-position: top cent
          <item>
           <widget class="QComboBox" name="cmbRunTransitionBehavior"/>
          </item>
-         <item>
-          <spacer name="horizontalSpacer_12">
-           <property name="orientation">
-            <enum>Qt::Horizontal</enum>
-           </property>
-           <property name="sizeHint" stdset="0">
-            <size>
-             <width>40</width>
-             <height>20</height>
-            </size>
-           </property>
-          </spacer>
-         </item>
         </layout>
        </item>
        <item>
diff --git a/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp b/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp
index 4af8ab2f443508bdf32fd7a968a15b1ab7308ce8..3287aba559e39b0531d769261294dc3db4980caa 100644
--- a/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp
+++ b/MantidQt/CustomDialogs/src/ConvertTableToMatrixWorkspaceDialog.cpp
@@ -1,6 +1,3 @@
-//------------------------------------------------------------------------------
-// Includes
-//------------------------------------------------------------------------------
 #include "MantidQtCustomDialogs/ConvertTableToMatrixWorkspaceDialog.h"
 #include "MantidQtAPI/AlgorithmInputHistory.h"
 // Qt
@@ -12,6 +9,7 @@
 
 // Mantid
 #include "MantidKernel/Property.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IWorkspaceProperty.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/ITableWorkspace.h"
@@ -21,19 +19,11 @@ namespace CustomDialogs {
 // Declare the dialog. Name must match the class name
 DECLARE_DIALOG(ConvertTableToMatrixWorkspaceDialog)
 
-//--------------------------------------------------------------------------
-// Public methods
-//---------------------------------------------------------------------------
-
 /// Default constructor
 ConvertTableToMatrixWorkspaceDialog::ConvertTableToMatrixWorkspaceDialog(
     QWidget *parent)
     : API::AlgorithmDialog(parent), m_form() {}
 
-//--------------------------------------------------------------------------
-// Private methods (slot)
-//---------------------------------------------------------------------------
-
 /**
 * When the input workspace changes the column name comboboxes have to
 * be updated.
diff --git a/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp b/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp
index 4e4407a53ece915e1b558deb53925b72db5c74d5..1f23d623eefa79be0205514619a189099d78b520 100644
--- a/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp
+++ b/MantidQt/CustomDialogs/src/PlotAsymmetryByLogValueDialog.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QLabel>
 #include <QLineEdit>
diff --git a/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp b/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp
index f71d5c8021fa70900c2ebe54aff0d9c5094ff563..8b1541ce8ecbe82c7c7465f04a127f8a6e1aafa6 100644
--- a/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp
+++ b/MantidQt/CustomDialogs/src/StartLiveDataDialog.cpp
@@ -12,7 +12,9 @@
 #include "MantidAPI/LiveListenerFactory.h"
 #include "MantidKernel/DateAndTime.h"
 #include "MantidKernel/SingletonHolder.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/InstrumentInfo.h"
+#include "MantidKernel/LiveListenerInfo.h"
 #include <QtGui>
 #include "MantidQtAPI/AlgorithmInputHistory.h"
 
@@ -21,6 +23,7 @@ using namespace MantidQt::API;
 using Mantid::API::AlgorithmManager;
 using Mantid::API::Algorithm_sptr;
 using Mantid::Kernel::DateAndTime;
+using Mantid::Kernel::ConfigService;
 
 namespace {
 class LiveDataAlgInputHistoryImpl : public AbstractAlgorithmInputHistory {
@@ -69,6 +72,9 @@ namespace MantidQt {
 namespace CustomDialogs {
 DECLARE_DIALOG(StartLiveDataDialog)
 
+// Initialize static members
+const QString StartLiveDataDialog::CUSTOM_CONNECTION = "[Custom]";
+
 //----------------------
 // Public member functions
 //----------------------
@@ -174,13 +180,22 @@ void StartLiveDataDialog::initLayout() {
     }
   }
 
+  //=========== Load Listener Class Names =============
+  // Add available listeners to combo box
+  ui.cmbConnListener->clear();
+  std::vector<std::string> listeners =
+      Mantid::API::LiveListenerFactory::Instance().getKeys();
+  for (const auto &listener : listeners) {
+    ui.cmbConnListener->addItem(QString::fromStdString(listener));
+  }
+
+  //=========== Update UI Elements =============
   radioPostProcessClicked();
-  setDefaultAccumulationMethod(ui.cmbInstrument->currentText());
   updateUiElements(ui.cmbInstrument->currentText());
-
-  //=========== Listener's properties =============
-
-  initListenerPropLayout(ui.cmbInstrument->currentText());
+  updateConnectionChoices(ui.cmbInstrument->currentText());
+  updateConnectionDetails(ui.cmbConnection->currentText());
+  setDefaultAccumulationMethod(ui.cmbConnListener->currentText());
+  initListenerPropLayout(ui.cmbConnListener->currentText());
 
   //=========== SLOTS =============
   connect(ui.processingAlgo, SIGNAL(changedAlgorithm()), this,
@@ -211,12 +226,17 @@ void StartLiveDataDialog::initLayout() {
   connect(ui.chkPreserveEvents, SIGNAL(toggled(bool)), this,
           SLOT(chkPreserveEventsToggled()));
 
-  connect(ui.cmbInstrument, SIGNAL(currentIndexChanged(const QString &)), this,
-          SLOT(setDefaultAccumulationMethod(const QString &)));
-  connect(ui.cmbInstrument, SIGNAL(currentIndexChanged(const QString &)), this,
-          SLOT(initListenerPropLayout(const QString &)));
+  connect(ui.cmbConnListener, SIGNAL(currentIndexChanged(const QString &)),
+          this, SLOT(setDefaultAccumulationMethod(const QString &)));
+  connect(ui.cmbConnListener, SIGNAL(currentIndexChanged(const QString &)),
+          this, SLOT(initListenerPropLayout(const QString &)));
   connect(ui.cmbInstrument, SIGNAL(currentIndexChanged(const QString &)), this,
           SLOT(updateUiElements(const QString &)));
+  connect(ui.cmbInstrument, SIGNAL(currentIndexChanged(const QString &)), this,
+          SLOT(updateConnectionChoices(const QString &)));
+
+  connect(ui.cmbConnection, SIGNAL(currentIndexChanged(const QString &)), this,
+          SLOT(updateConnectionDetails(const QString &)));
 
   QLayout *buttonLayout = this->createDefaultButtonLayout();
   ui.mainLayout->addLayout(buttonLayout);
@@ -226,6 +246,11 @@ void StartLiveDataDialog::initLayout() {
 /// Parse input when the dialog is accepted
 void StartLiveDataDialog::parseInput() {
   storePropertyValue("Instrument", ui.cmbInstrument->currentText());
+
+  // "Connection" property does not need to be set, since these override it
+  storePropertyValue("Listener", ui.cmbConnListener->currentText());
+  storePropertyValue("Address", ui.edtConnAddress->text());
+
   storePropertyValue("AccumulationMethod",
                      ui.cmbAccumulationMethod->currentText());
 
@@ -323,10 +348,11 @@ void StartLiveDataDialog::changePostProcessingAlgorithm() {
 //------------------------------------------------------------------------------
 /** Slot called when picking a different instrument.
  *  Disables the 'Add' option if the listener is going to pass back histograms.
- *  @param inst :: The instrument name.
+ *  @param listener :: The listener class name.
  */
-void StartLiveDataDialog::setDefaultAccumulationMethod(const QString &inst) {
-  if (inst.isEmpty())
+void StartLiveDataDialog::setDefaultAccumulationMethod(
+    const QString &listener) {
+  if (listener.isEmpty())
     return;
   try {
     // Make sure 'Add' is enabled ahead of the check (the check may throw)
@@ -338,12 +364,14 @@ void StartLiveDataDialog::setDefaultAccumulationMethod(const QString &inst) {
     // Check whether this listener will give back events. If not, disable 'Add'
     // as an option
     // The 'false' 2nd argument means don't connect the created listener
+    Mantid::Kernel::LiveListenerInfo info(listener.toStdString());
     if (!Mantid::API::LiveListenerFactory::Instance()
-             .create(inst.toStdString(), false)
+             .create(info, false)
              ->buffersEvents()) {
       // If 'Add' is currently selected, select 'Replace' instead
       if (ui.cmbAccumulationMethod->currentIndex() == addIndex) {
-        ui.cmbAccumulationMethod->setItemText(-1, "Replace");
+        int replaceIndex = ui.cmbAccumulationMethod->findText("Replace");
+        ui.cmbAccumulationMethod->setCurrentIndex(replaceIndex);
       }
       // Disable the 'Add' option in the combobox. It just wouldn't make sense.
       ui.cmbAccumulationMethod->setItemData(addIndex, false, Qt::UserRole - 1);
@@ -390,7 +418,12 @@ void StartLiveDataDialog::accept() {
   AlgorithmDialog::accept(); // accept executes the algorithm
 }
 
-void StartLiveDataDialog::initListenerPropLayout(const QString &inst) {
+/**
+ * Update the Listener Properties group box for the current LiveListener.
+ *
+ * @param listener Name of the LiveListener class that is selected
+ */
+void StartLiveDataDialog::initListenerPropLayout(const QString &listener) {
   // remove previous listener's properties
   auto props = m_algorithm->getPropertiesInGroup("ListenerProperties");
   for (auto prop = props.begin(); prop != props.end(); ++prop) {
@@ -401,7 +434,9 @@ void StartLiveDataDialog::initListenerPropLayout(const QString &inst) {
   }
 
   // update algorithm's properties
-  m_algorithm->setPropertyValue("Instrument", inst.toStdString());
+  m_algorithm->setPropertyValue("Instrument",
+                                ui.cmbInstrument->currentText().toStdString());
+  m_algorithm->setPropertyValue("Listener", listener.toStdString());
   // create or clear the layout
   QLayout *layout = ui.listenerProps->layout();
   if (!layout) {
@@ -439,5 +474,61 @@ void StartLiveDataDialog::initListenerPropLayout(const QString &inst) {
   }
   ui.listenerProps->setVisible(true);
 }
+
+/**
+ * Slot to update list of available connections when instrument is changed
+ *
+ * @param inst_name Name of selected instrument
+ */
+void StartLiveDataDialog::updateConnectionChoices(const QString &inst_name) {
+  // Reset the connections listed
+  ui.cmbConnection->clear();
+  ui.cmbConnection->addItem(CUSTOM_CONNECTION);
+
+  // Add available LiveListenerInfo names based on selected instrument
+  const auto &inst =
+      ConfigService::Instance().getInstrument(inst_name.toStdString());
+  for (const auto &listener : inst.liveListenerInfoList()) {
+    ui.cmbConnection->addItem(QString::fromStdString(listener.name()));
+  }
+
+  // Select default item
+  auto selectName = QString::fromStdString(inst.liveListenerInfo().name());
+  auto index = ui.cmbConnection->findText(selectName);
+  ui.cmbConnection->setCurrentIndex(index);
+}
+
+/**
+ * Slot to update connection parameters when connection selected
+ *
+ * @param connection Name of selected live listener connection
+ */
+void StartLiveDataDialog::updateConnectionDetails(const QString &connection) {
+  // Custom connections just enable editting connection parameters
+  if (connection == CUSTOM_CONNECTION) {
+    ui.cmbConnListener->setEnabled(true);
+    ui.edtConnAddress->setEnabled(true);
+    return;
+  }
+
+  // User shouldn't be able to edit values loaded from Facilities.xml
+  ui.cmbConnListener->setEnabled(false);
+  ui.edtConnAddress->setEnabled(false);
+
+  // Get live listener for select instrument and connection
+  const auto &inst = ConfigService::Instance().getInstrument(
+      ui.cmbInstrument->currentText().toStdString());
+  const auto &info = inst.liveListenerInfo(connection.toStdString());
+
+  // Select correct listener
+  auto listener = QString::fromStdString(info.listener());
+  auto index = ui.cmbConnListener->findText(listener);
+  ui.cmbConnListener->setCurrentIndex(index);
+
+  // Set address text box
+  auto address = QString::fromStdString(info.address());
+  ui.edtConnAddress->setText(address);
+  ui.edtConnAddress->home(false); // display long lines from beginning, not end
+}
 }
 }
diff --git a/MantidQt/CustomInterfaces/CMakeLists.txt b/MantidQt/CustomInterfaces/CMakeLists.txt
index b4b5f0d6bf36d3cb06849fb20ba49ef853b59d47..9c7fdbd87df9589f72c042084f7268408de82523 100644
--- a/MantidQt/CustomInterfaces/CMakeLists.txt
+++ b/MantidQt/CustomInterfaces/CMakeLists.txt
@@ -94,6 +94,7 @@ set ( SRC_FILES
 	src/Reflectometry/QtReflRunsTabView.cpp
 	src/Reflectometry/QtReflSaveTabView.cpp
 	src/Reflectometry/QtReflSettingsTabView.cpp
+	src/Reflectometry/QtReflSettingsView.cpp
 	src/Reflectometry/ReflCatalogSearcher.cpp
 	src/Reflectometry/ReflGenericDataProcessorPresenterFactory.cpp
 	src/Reflectometry/ReflLegacyTransferStrategy.cpp
@@ -103,6 +104,7 @@ set ( SRC_FILES
 	src/Reflectometry/ReflRunsTabPresenter.cpp
 	src/Reflectometry/ReflSearchModel.cpp
 	src/Reflectometry/ReflSaveTabPresenter.cpp
+	src/Reflectometry/ReflSettingsPresenter.cpp
 	src/Reflectometry/ReflSettingsTabPresenter.cpp
 	src/Reflectometry/ReflTableSchema.cpp
 	src/Reflectometry/TransferResults.cpp
@@ -257,8 +259,9 @@ set ( INC_FILES
 	inc/MantidQtCustomInterfaces/Reflectometry/IReflSearcher.h
 	inc/MantidQtCustomInterfaces/Reflectometry/IReflSaveTabPresenter.h
 	inc/MantidQtCustomInterfaces/Reflectometry/IReflSaveTabView.h
+	inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h
 	inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h
-	inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h
+	inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h
 	inc/MantidQtCustomInterfaces/Reflectometry/MeasurementItem.h
 	inc/MantidQtCustomInterfaces/Reflectometry/QtReflMainWindowView.h
 	inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h
@@ -270,6 +273,8 @@ set ( INC_FILES
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflMeasurementItemSource.h
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflNexusMeasurementItemSource.h
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabPresenter.h
+	inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h
+	inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflSearchModel.h
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflTableSchema.h
 	inc/MantidQtCustomInterfaces/Reflectometry/ReflTransferStrategy.h
@@ -313,6 +318,8 @@ set ( INC_FILES
 	inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h
 	inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h
 	inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h
+	inc/MantidQtCustomInterfaces/Tomography/TomographyThread.h
+	inc/MantidQtCustomInterfaces/Tomography/TomographyProcess.h
 	inc/MantidQtCustomInterfaces/Tomography/ToolConfigAstraToolbox.h
 	inc/MantidQtCustomInterfaces/Tomography/ToolConfigCustom.h
 	inc/MantidQtCustomInterfaces/Tomography/ToolConfigTomoPy.h
@@ -412,6 +419,7 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h
                 inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h
                 inc/MantidQtCustomInterfaces/Reflectometry/QtReflSaveTabView.h
                 inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h
+                inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h
                 inc/MantidQtCustomInterfaces/SampleTransmission.h
                 inc/MantidQtCustomInterfaces/SANSBackgroundCorrectionWidget.h
                 inc/MantidQtCustomInterfaces/SANSAddFiles.h
@@ -426,6 +434,8 @@ set ( MOC_FILES inc/MantidQtCustomInterfaces/Background.h
                 inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h
                 inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h
                 inc/MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h								
+                inc/MantidQtCustomInterfaces/Tomography/TomographyProcess.h								
+                inc/MantidQtCustomInterfaces/Tomography/TomographyThread.h
 )
 
 set ( UI_FILES inc/MantidQtCustomInterfaces/DataComparison.ui
@@ -489,6 +499,7 @@ set ( UI_FILES inc/MantidQtCustomInterfaces/DataComparison.ui
                inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
                inc/MantidQtCustomInterfaces/Reflectometry/ReflSaveTabWidget.ui
                inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabWidget.ui
+               inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsWidget.ui
                inc/MantidQtCustomInterfaces/Reflectometry/ReflWindow.ui
                inc/MantidQtCustomInterfaces/SampleTransmission.ui
                inc/MantidQtCustomInterfaces/SANSBackgroundCorrectionWidget.ui
@@ -536,6 +547,7 @@ set ( TEST_FILES
 	ReflNexusMeasurementItemSourceTest.h
 	ReflRunsTabPresenterTest.h
 	ReflSaveTabPresenterTest.h
+	ReflSettingsPresenterTest.h
 	ReflSettingsTabPresenterTest.h
 	StackOfImagesDirsTest.h
 	TomographyIfaceModelTest.h
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmissionCalc.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmissionCalc.ui
index 0ead455b0cb85e44c6734292992991639f619a3a..1500fb6bf8b69599ef7607d3ca108751fe34f87b 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmissionCalc.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTransmissionCalc.ui
@@ -33,6 +33,7 @@
           <property name="techniques" stdset="0">
            <stringlist>
             <string>TOF Indirect Geometry Spectroscopy</string>
+            <string>Reactor Indirect Geometry Spectroscopy</string>
            </stringlist>
           </property>
           <property name="disabledInstruments" stdset="0">
@@ -57,9 +58,6 @@
         <string>Sample Details</string>
        </property>
        <layout class="QGridLayout" name="gridLayout_2">
-        <property name="margin">
-         <number>9</number>
-        </property>
         <item row="0" column="0">
          <widget class="QLabel" name="lbChemicalFormula">
           <property name="text">
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisDataLoader.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisDataLoader.h
index a610a841cfb7db3420ecc5cbf15151f3acf3d721..5c0c23eacc11bf127d0c2ddc974c65ce90b2af96 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisDataLoader.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Muon/MuonAnalysisDataLoader.h
@@ -9,6 +9,7 @@
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidAPI/Workspace_fwd.h"
 #include <QMap>
+#include <QRegExp>
 #include <QStringList>
 
 namespace MantidQt {
@@ -39,7 +40,7 @@ struct AnalysisOptions {
   std::string groupPairName; /// Name of group or pair to use
   const Mantid::API::Grouping grouping; /// Grouping to use
   PlotType plotType = {};               /// Type of analysis to perform
-  explicit AnalysisOptions(const Mantid::API::Grouping &g) : grouping(g){};
+  explicit AnalysisOptions(const Mantid::API::Grouping &g) : grouping(g) {}
 };
 } // namespace Muon
 
@@ -77,6 +78,7 @@ public:
                         const std::string &deadTimesFile = "");
   /// change list of supported instruments
   void setSupportedInstruments(const QStringList &instruments);
+
   /// load files
   Muon::LoadResult loadFiles(const QStringList &files) const;
   /// correct and group loaded data
@@ -106,6 +108,9 @@ private:
   /// Get instrument name from workspace
   std::string
   getInstrumentName(const Mantid::API::Workspace_sptr workspace) const;
+  /// Check if we should cache result of a load of the given files
+  bool shouldBeCached(const QStringList &filenames) const;
+
   /// Dead times type
   Muon::DeadTimesType m_deadTimesType;
   /// Dead times file
@@ -114,9 +119,11 @@ private:
   QStringList m_instruments;
   /// Cache of previously loaded data
   mutable std::map<std::string, Muon::LoadResult> m_loadedDataCache;
+  /// Regex blacklisting certain files from being cached
+  QRegExp m_cacheBlacklist;
 };
 
 } // namespace CustomInterfaces
 } // namespace MantidQt
 
-#endif /* MANTIDQt_CUSTOMINTERFACES_MUONANALYSISDATALOADER_H_ */
\ No newline at end of file
+#endif /* MANTIDQt_CUSTOMINTERFACES_MUONANALYSISDATALOADER_H_ */
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflMainWindowPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflMainWindowPresenter.h
index e3c84ecf44274434ffa031361594b6614f4abd2d..7b6b9e136e96780472997e7db3fb8125e1716392 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflMainWindowPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflMainWindowPresenter.h
@@ -39,11 +39,11 @@ public:
   /// Destructor
   virtual ~IReflMainWindowPresenter(){};
   /// Pre-processing
-  virtual std::string getTransmissionOptions() const = 0;
+  virtual std::string getTransmissionOptions(int group) const = 0;
   /// Processing
-  virtual std::string getReductionOptions() const = 0;
+  virtual std::string getReductionOptions(int group) const = 0;
   /// Post-processing
-  virtual std::string getStitchOptions() const = 0;
+  virtual std::string getStitchOptions(int group) const = 0;
   /// Dialog/Prompt methods
   virtual std::string askUserString(const std::string &prompt,
                                     const std::string &title,
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabPresenter.h
index 77a0380e22dc57e0693aac8cd3533de216f3e8e9..50bbcf9ea26345d99015e8400f203dee611de2d1 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabPresenter.h
@@ -42,7 +42,8 @@ public:
     SearchFlag,
     ICATSearchCompleteFlag,
     TransferFlag,
-    InstrumentChangedFlag
+    InstrumentChangedFlag,
+    GroupChangedFlag
   };
 
   // Tell the presenter something happened
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabView.h
index 3249d5926ab3bb7c2c4ae37267633daa9c4a384d..8fcc04d7f951c699c457feace4aafa34cf8372d0 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabView.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflRunsTabView.h
@@ -71,6 +71,7 @@ public:
   virtual std::string getSearchInstrument() const = 0;
   virtual std::string getSearchString() const = 0;
   virtual std::string getTransferMethod() const = 0;
+  virtual int getSelectedGroup() const = 0;
 
   virtual IReflRunsTabPresenter *getPresenter() const = 0;
   virtual boost::shared_ptr<MantidQt::API::AlgorithmRunner>
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h
new file mode 100644
index 0000000000000000000000000000000000000000..25d6b7ff8db957657b5e4d039b790f7bdbf96c21
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h
@@ -0,0 +1,56 @@
+#ifndef MANTID_CUSTOMINTERFACES_IREFLSETTINGSPRESENTER_H
+#define MANTID_CUSTOMINTERFACES_IREFLSETTINGSPRESENTER_H
+
+#include <string>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+class IReflMainWindowPresenter;
+
+/** @class IReflSettingsPresenter
+
+IReflSettingsPresenter is an interface which defines the functions that need
+to be implemented by a concrete 'Settings' presenter
+
+Copyright &copy; 2011-16 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 IReflSettingsPresenter {
+public:
+  virtual ~IReflSettingsPresenter(){};
+  /// Pre-processing
+  virtual std::string getTransmissionOptions() const = 0;
+  /// Processing
+  virtual std::string getReductionOptions() const = 0;
+  /// Post-processing
+  virtual std::string getStitchOptions() const = 0;
+
+  enum Flag { ExpDefaultsFlag, InstDefaultsFlag };
+
+  /// Tell the presenter something happened
+  virtual void notify(IReflSettingsPresenter::Flag flag) = 0;
+  /// Set current instrument name
+  virtual void setInstrumentName(const std::string &instName) = 0;
+};
+}
+}
+#endif /* MANTID_CUSTOMINTERFACES_IREFLSETTINGSPRESENTER_H */
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h
index f00b18d1476ff9d35ae313d8849add441d4d74fc..89845e59a881531f4264d2360acf639255bc5e0a 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h
@@ -37,21 +37,14 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class IReflSettingsTabPresenter {
 public:
   virtual ~IReflSettingsTabPresenter(){};
-  /// Accept a main presenter
-  virtual void acceptMainPresenter(IReflMainWindowPresenter *mainPresenter) = 0;
   /// Pre-processing
-  virtual std::string getTransmissionOptions() const = 0;
+  virtual std::string getTransmissionOptions(int group) const = 0;
   /// Processing
-  virtual std::string getReductionOptions() const = 0;
+  virtual std::string getReductionOptions(int group) const = 0;
   /// Post-processing
-  virtual std::string getStitchOptions() const = 0;
-
-  enum Flag { ExpDefaultsFlag, InstDefaultsFlag };
-
-  /// Tell the presenter something happened
-  virtual void notify(IReflSettingsTabPresenter::Flag flag) = 0;
+  virtual std::string getStitchOptions(int group) const = 0;
   /// Set current instrument name
-  virtual void setInstrumentName(const std::string instName) = 0;
+  virtual void setInstrumentName(const std::string &instName) = 0;
 };
 }
 }
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h
similarity index 82%
rename from MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h
rename to MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h
index ff159575cb1d63dce69385112f208d956d332925..7d87dab566cb7dc80baa59880712a0690c110c06 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h
@@ -1,5 +1,5 @@
-#ifndef MANTID_CUSTOMINTERFACES_IREFLSETTINGSTABVIEW_H
-#define MANTID_CUSTOMINTERFACES_IREFLSETTINGSTABVIEW_H
+#ifndef MANTID_CUSTOMINTERFACES_IREFLSETTINGSVIEW_H
+#define MANTID_CUSTOMINTERFACES_IREFLSETTINGSVIEW_H
 
 #include "MantidQtCustomInterfaces/DllConfig.h"
 #include <vector>
@@ -9,13 +9,12 @@ namespace MantidQt {
 
 namespace CustomInterfaces {
 
-class IReflSettingsTabPresenter;
+class IReflSettingsPresenter;
 
-/** @class IReflSettingsTabView
+/** @class IReflSettingsView
 
-IReflSettingsTabView is the base view class for the Reflectometry Interface. It
-contains
-no QT specific functionality as that should be handled by a subclass.
+IReflSettingsView is the base view class for the Reflectometry settings. It
+contains no QT specific functionality as that should be handled by a subclass.
 
 Copyright &copy; 2011-16 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
 National Laboratory & European Spallation Source
@@ -39,14 +38,14 @@ File change history is stored at: <https://github.com/mantidproject/mantid>.
 Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 
-class DLLExport IReflSettingsTabView {
+class DLLExport IReflSettingsView {
 public:
   /// Constructor
-  IReflSettingsTabView(){};
+  IReflSettingsView(){};
   /// Destructor
-  virtual ~IReflSettingsTabView(){};
+  virtual ~IReflSettingsView(){};
   /// Returns the presenter managing this view
-  virtual IReflSettingsTabPresenter *getPresenter() const = 0;
+  virtual IReflSettingsPresenter *getPresenter() const = 0;
 
   /// Post-processing
   virtual std::string getStitchOptions() const = 0;
@@ -84,4 +83,4 @@ public:
 };
 }
 }
-#endif /* MANTID_CUSTOMINTERFACES_IREFLRUNSTABVIEW_H */
+#endif /* MANTID_CUSTOMINTERFACES_IREFLSETTINGSVIEW_H */
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/MeasurementItem.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/MeasurementItem.h
index 25576f0180bc74aa98fe42594018b60e873ca38a..85b6b21f58f13ddb8cedac316d37e802c9336466 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/MeasurementItem.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/MeasurementItem.h
@@ -38,7 +38,8 @@ public:
   /// Constructor
   MeasurementItem(const IDType &measurementItemId, const IDType &subId,
                   const std::string &label, const std::string &type,
-                  const double angle, const std::string &run);
+                  const double angle, const std::string &run,
+                  const std::string &title);
 
   /// Constructional method
   static MeasurementItem InvalidMeasurementItem(const std::string &why);
@@ -55,6 +56,7 @@ public:
   IDType subId() const;
   std::string run() const;
   std::string type() const;
+  std::string title() const;
   std::string label() const;
   double angle() const;
   std::string angleStr() const;
@@ -69,6 +71,7 @@ private:
   std::string m_type;
   double m_angle;
   std::string m_run;
+  std::string m_title;
   std::string m_whyUnuseable;
   /// Not assignable
 };
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h
index deff40d87bf60fa744e2120c315771cc5702fa84..50f2e7a11992fbcd896881590fa4a8086f66b135 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflRunsTabView.h
@@ -88,6 +88,7 @@ public:
   std::string getSearchInstrument() const override;
   std::string getSearchString() const override;
   std::string getTransferMethod() const override;
+  int getSelectedGroup() const override;
 
   IReflRunsTabPresenter *getPresenter() const override;
   boost::shared_ptr<MantidQt::API::AlgorithmRunner>
@@ -118,6 +119,7 @@ private slots:
   void slitCalculatorTriggered();
   void icatSearchComplete();
   void instrumentChanged(int index);
+  void groupChanged();
   void showSearchContextMenu(const QPoint &pos);
 };
 
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h
index 4ba8ca4437a98f76bc59633e6647fefe8ed28c76..3f0df4151e6efbb778cdbeee07e056eb32e06596 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h
@@ -1,7 +1,7 @@
 #ifndef MANTID_CUSTOMINTERFACES_QTREFLSETTINGSTABVIEW_H_
 #define MANTID_CUSTOMINTERFACES_QTREFLSETTINGSTABVIEW_H_
 
-#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h"
+#include "MantidQtCustomInterfaces/DllConfig.h"
 #include "ui_ReflSettingsTabWidget.h"
 #include <memory>
 
@@ -35,7 +35,7 @@ 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 QtReflSettingsTabView : public QWidget, public IReflSettingsTabView {
+class MANTIDQT_CUSTOMINTERFACES_DLL QtReflSettingsTabView : public QWidget {
   Q_OBJECT
 public:
   /// Constructor
@@ -43,61 +43,7 @@ public:
   /// Destructor
   ~QtReflSettingsTabView() override;
   /// Returns the presenter managing this view
-  IReflSettingsTabPresenter *getPresenter() const override;
-  /// Returns global options for 'Stitch1DMany'
-  std::string getStitchOptions() const override;
-  /// Return selected analysis mode
-  std::string getAnalysisMode() const override;
-  /// Return direct beam
-  std::string getDirectBeam() const override;
-  /// Return transmission runs
-  std::string getTransmissionRuns() const override;
-  /// Return selected polarisation corrections
-  std::string getPolarisationCorrections() const override;
-  /// Return CRho
-  std::string getCRho() const override;
-  /// Return CAlpha
-  std::string getCAlpha() const override;
-  /// Return CAp
-  std::string getCAp() const override;
-  /// Return Cpp
-  std::string getCPp() const override;
-  /// Return momentum transfer limits
-  std::string getMomentumTransferStep() const override;
-  /// Return scale factor
-  std::string getScaleFactor() const override;
-  /// Return integrated monitors option
-  std::string getIntMonCheck() const override;
-  /// Return monitor integral wavelength min
-  std::string getMonitorIntegralMin() const override;
-  /// Return monitor integral wavelength max
-  std::string getMonitorIntegralMax() const override;
-  /// Return monitor background wavelength min
-  std::string getMonitorBackgroundMin() const override;
-  /// Return monitor background wavelength max
-  std::string getMonitorBackgroundMax() const override;
-  /// Return wavelength min
-  std::string getLambdaMin() const override;
-  /// Return wavelength max
-  std::string getLambdaMax() const override;
-  /// Return I0MonitorIndex
-  std::string getI0MonitorIndex() const override;
-  /// Return processing instructions
-  std::string getProcessingInstructions() const override;
-  /// Set default values for experiment and instrument settings
-  void setExpDefaults(const std::vector<std::string> &) const override;
-  void setInstDefaults(const std::vector<double> &) const override;
-
-  /// Creates hints for 'Stitch1DMany'
-  void
-  createStitchHints(const std::map<std::string, std::string> &hints) override;
-  /// Sets enabled status for polarisation corrections and parameters
-  void setPolarisationOptionsEnabled(bool enable) const override;
-
-public slots:
-  /// Request presenter to obtain default values for settings
-  void requestExpDefaults() const;
-  void requestInstDefaults() const;
+  IReflSettingsTabPresenter *getPresenter() const;
 
 private:
   /// Initialise the interface
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h
new file mode 100644
index 0000000000000000000000000000000000000000..8df499be3be7e380e04c85cf831307d10cecddcb
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h
@@ -0,0 +1,115 @@
+#ifndef MANTID_CUSTOMINTERFACES_QTREFLSETTINGSVIEW_H_
+#define MANTID_CUSTOMINTERFACES_QTREFLSETTINGSVIEW_H_
+
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h"
+#include "ui_ReflSettingsWidget.h"
+#include <memory>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+// Forward decs
+class IReflSettingsPresenter;
+
+/** QtReflSettingsView : Provides an interface for the "Settings" widget in the
+Reflectometry (Polref) interface.
+
+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 QtReflSettingsView : public QWidget, public IReflSettingsView {
+  Q_OBJECT
+public:
+  /// Constructor
+  QtReflSettingsView(QWidget *parent = 0);
+  /// Destructor
+  ~QtReflSettingsView() override;
+  /// Returns the presenter managing this view
+  IReflSettingsPresenter *getPresenter() const override;
+  /// Returns global options for 'Stitch1DMany'
+  std::string getStitchOptions() const override;
+  /// Return selected analysis mode
+  std::string getAnalysisMode() const override;
+  /// Return direct beam
+  std::string getDirectBeam() const override;
+  /// Return transmission runs
+  std::string getTransmissionRuns() const override;
+  /// Return selected polarisation corrections
+  std::string getPolarisationCorrections() const override;
+  /// Return CRho
+  std::string getCRho() const override;
+  /// Return CAlpha
+  std::string getCAlpha() const override;
+  /// Return CAp
+  std::string getCAp() const override;
+  /// Return Cpp
+  std::string getCPp() const override;
+  /// Return momentum transfer limits
+  std::string getMomentumTransferStep() const override;
+  /// Return scale factor
+  std::string getScaleFactor() const override;
+  /// Return integrated monitors option
+  std::string getIntMonCheck() const override;
+  /// Return monitor integral wavelength min
+  std::string getMonitorIntegralMin() const override;
+  /// Return monitor integral wavelength max
+  std::string getMonitorIntegralMax() const override;
+  /// Return monitor background wavelength min
+  std::string getMonitorBackgroundMin() const override;
+  /// Return monitor background wavelength max
+  std::string getMonitorBackgroundMax() const override;
+  /// Return wavelength min
+  std::string getLambdaMin() const override;
+  /// Return wavelength max
+  std::string getLambdaMax() const override;
+  /// Return I0MonitorIndex
+  std::string getI0MonitorIndex() const override;
+  /// Return processing instructions
+  std::string getProcessingInstructions() const override;
+  /// Set default values for experiment and instrument settings
+  void setExpDefaults(const std::vector<std::string> &) const override;
+  void setInstDefaults(const std::vector<double> &) const override;
+
+  /// Creates hints for 'Stitch1DMany'
+  void
+  createStitchHints(const std::map<std::string, std::string> &hints) override;
+  /// Sets enabled status for polarisation corrections and parameters
+  void setPolarisationOptionsEnabled(bool enable) const override;
+
+public slots:
+  /// Request presenter to obtain default values for settings
+  void requestExpDefaults() const;
+  void requestInstDefaults() const;
+
+private:
+  /// Initialise the interface
+  void initLayout();
+
+  /// The widget
+  Ui::ReflSettingsWidget m_ui;
+  /// The presenter
+  std::unique_ptr<IReflSettingsPresenter> m_presenter;
+};
+
+} // namespace Mantid
+} // namespace CustomInterfaces
+
+#endif /* MANTID_CUSTOMINTERFACES_QTREFLSETTINGSVIEW_H_ */
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflMainWindowPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflMainWindowPresenter.h
index f833788dc3cf5d08cbc40a9a80a5562005daf1ac..fca9cb6c204b7f69fc70064322234b5be1d98d19 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflMainWindowPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflMainWindowPresenter.h
@@ -49,11 +49,11 @@ public:
   /// Destructor
   ~ReflMainWindowPresenter() override;
   /// Returns global options for 'CreateTransmissionWorkspaceAuto'
-  std::string getTransmissionOptions() const override;
+  std::string getTransmissionOptions(int group) const override;
   /// Returns global options for 'ReflectometryReductionOneAuto'
-  std::string getReductionOptions() const override;
+  std::string getReductionOptions(int group) const override;
   /// Returns global options for 'Stitch1DMany'
-  std::string getStitchOptions() const override;
+  std::string getStitchOptions(int group) const override;
 
   /// Dialog/Prompt methods
   std::string askUserString(const std::string &prompt, const std::string &title,
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabPresenter.h
index 4c859f25e3068f75f33a4ca7169b4283537dc60e..7696f2e002a7d5ff9870dd918b62dea2e7011ee0 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabPresenter.h
@@ -59,7 +59,7 @@ class MANTIDQT_CUSTOMINTERFACES_DLL ReflRunsTabPresenter
 public:
   ReflRunsTabPresenter(IReflRunsTabView *mainView,
                        ProgressableView *progressView,
-                       DataProcessorPresenter *tablePresenter,
+                       std::vector<DataProcessorPresenter *> tablePresenter,
                        boost::shared_ptr<IReflSearcher> searcher =
                            boost::shared_ptr<IReflSearcher>());
   ~ReflRunsTabPresenter() override;
@@ -85,8 +85,8 @@ protected:
   IReflRunsTabView *m_view;
   /// The progress view
   ProgressableView *m_progressView;
-  /// The data processor presenter
-  DataProcessorPresenter *m_tablePresenter;
+  /// The data processor presenters stored in a vector
+  std::vector<DataProcessorPresenter *> m_tablePresenters;
   /// The main presenter
   IReflMainWindowPresenter *m_mainPresenter;
   /// The search implementation
@@ -98,6 +98,8 @@ protected:
   void pushCommands();
 
 private:
+  std::string m_currentTransferMethod;
+
   static const std::string LegacyTransferMethod;
   static const std::string MeasureTransferMethod;
 
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
index 402378410e06a608daae5babb22c2070978a844a..0b93c3bb4b7974d0fd459cf4dc0a6b74b26bab4d 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflRunsTabWidget.ui
@@ -246,6 +246,10 @@
            <property name="margin">
              <number>1</number>
            </property>
+           <item>
+             <widget class="QToolBox" name="toolbox">
+             </widget>
+           </item>
          </layout>
        </widget>
        </widget>
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h
new file mode 100644
index 0000000000000000000000000000000000000000..3d2daf0bb1dd99e74446e23f38114ae3cc5f94b4
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h
@@ -0,0 +1,74 @@
+#ifndef MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTER_H
+#define MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTER_H
+
+#include "MantidQtCustomInterfaces/DllConfig.h"
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h"
+#include "MantidAPI/IAlgorithm_fwd.h"
+#include "MantidGeometry/Instrument_fwd.h"
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+// Forward decs
+class IReflSettingsView;
+
+/** @class ReflSettingsPresenter
+
+ReflSettingsPresenter is a presenter class for the widget 'Settings' in the
+Reflectometry (Polref) Interface.
+
+Copyright &copy; 2011-16 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 MANTIDQT_CUSTOMINTERFACES_DLL ReflSettingsPresenter
+    : public IReflSettingsPresenter {
+public:
+  /// Constructor
+  ReflSettingsPresenter(IReflSettingsView *view);
+  /// Destructor
+  ~ReflSettingsPresenter() override;
+  void notify(IReflSettingsPresenter::Flag flag) override;
+  void setInstrumentName(const std::string &instName) override;
+
+  /// Returns global options for 'CreateTransmissionWorkspaceAuto'
+  std::string getTransmissionOptions() const override;
+  /// Returns global options for 'ReflectometryReductionOneAuto'
+  std::string getReductionOptions() const override;
+  /// Returns global options for 'Stitch1DMany'
+  std::string getStitchOptions() const override;
+
+private:
+  void createStitchHints();
+  void getExpDefaults();
+  void getInstDefaults();
+  Mantid::API::IAlgorithm_sptr createReductionAlg();
+  Mantid::Geometry::Instrument_const_sptr
+  createEmptyInstrument(const std::string &instName);
+  std::string getTransmissionRuns() const;
+
+  /// The view we are managing
+  IReflSettingsView *m_view;
+  /// Name of the current instrument in use
+  std::string m_currentInstrumentName;
+};
+}
+}
+#endif /* MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTER_H */
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h
index 185428ebee3fa6dcd490f52a84428b78443309d2..ce53514041ff2775d080ea874c8a1bc85702873b 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h
@@ -3,18 +3,14 @@
 
 #include "MantidQtCustomInterfaces/DllConfig.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h"
-#include "MantidAPI/IAlgorithm.h"
-#include "MantidGeometry/Instrument.h"
+#include <vector>
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
-using namespace Mantid::API;
-using namespace Mantid::Geometry;
-
 // Forward decs
 class IReflMainWindowPresenter;
-class IReflSettingsTabView;
+class IReflSettingsPresenter;
 
 /** @class ReflSettingsTabPresenter
 
@@ -46,35 +42,22 @@ class MANTIDQT_CUSTOMINTERFACES_DLL ReflSettingsTabPresenter
     : public IReflSettingsTabPresenter {
 public:
   /// Constructor
-  ReflSettingsTabPresenter(IReflSettingsTabView *view);
+  ReflSettingsTabPresenter(std::vector<IReflSettingsPresenter *> presenters);
   /// Destructor
   ~ReflSettingsTabPresenter() override;
-  /// Accept a main presenter
-  void acceptMainPresenter(IReflMainWindowPresenter *mainPresenter) override;
-  void notify(IReflSettingsTabPresenter::Flag flag) override;
-  void setInstrumentName(const std::string instName) override;
+  /// Set the instrument name
+  void setInstrumentName(const std::string &instName) override;
 
   /// Returns global options for 'CreateTransmissionWorkspaceAuto'
-  std::string getTransmissionOptions() const override;
+  std::string getTransmissionOptions(int group) const override;
   /// Returns global options for 'ReflectometryReductionOneAuto'
-  std::string getReductionOptions() const override;
+  std::string getReductionOptions(int group) const override;
   /// Returns global options for 'Stitch1DMany'
-  std::string getStitchOptions() const override;
+  std::string getStitchOptions(int group) const override;
 
 private:
-  void createStitchHints();
-  void getExpDefaults();
-  void getInstDefaults();
-  IAlgorithm_sptr createReductionAlg();
-  Instrument_const_sptr createEmptyInstrument(std::string instName);
-  std::string getTransmissionRuns() const;
-
-  /// The view we are managing
-  IReflSettingsTabView *m_view;
-  /// The main presenter
-  IReflMainWindowPresenter *m_mainPresenter;
-  /// Name of the current instrument in use
-  std::string m_currentInstrumentName;
+  /// The presenters for each group as a vector
+  std::vector<IReflSettingsPresenter *> m_settingsPresenters;
 };
 }
 }
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabWidget.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabWidget.ui
index 968b04ed0635dcf8cad15aaebe0925fe5dbbd8da..f015e7a8a514ad8074580efb0827432b7106399d 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabWidget.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabWidget.ui
@@ -18,522 +18,7 @@
         <number>5</number>
       </property>
       <item>
-        <widget class="QGroupBox" name="expSettingsGroup">
-          <property name="title">
-            <string>Experiment Settings</string>
-          </property>
-          <property name="checkable">
-            <bool>true</bool>
-          </property>
-          <layout class="QHBoxLayout" name="expSettingsLayoutContainer">
-            <item>
-              <layout class="QGridLayout" name="expSettingsLayout0">
-                <property name="margin">
-                  <number>10</number>
-                </property>
-                <item row="0" column="0">
-                  <widget class="QLabel" name="analysisModeLabel">
-                    <property name="text">
-                      <string>AnalysisMode</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="0" column="1">
-                  <widget class="QComboBox" name="analysisModeComboBox">
-                    <item>
-                      <property name="text">
-                        <string>PointDetectorAnalysis</string>
-                      </property>
-                    </item>
-                    <item>
-                      <property name="text">
-                        <string>MultiDetectorAnalysis</string>
-                      </property>
-                    </item>
-                  </widget>
-                </item>
-                <item row="0" column="2">
-                  <widget class="QLabel" name="expSettingsDirectBeamLabel">
-                    <property name="text">
-                      <string>DirectBeam</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="0" column="3">
-                  <widget class="QLineEdit" name="directBeamEdit"/>
-                </item>
-                <item row="0" column="4">
-                  <spacer name="expSettings0Spacer0">
-                    <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">
-                  <widget class="QLabel" name="transmissionRunsLabel">
-                    <property name="text">
-                      <string>Transmission run(s)</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="1" column="1">
-                  <widget class="QLineEdit" name="transmissionRunsEdit"/>
-                </item>
-                <item row="1" column="2">
-                  <spacer name="expSettings0Spacer1">
-                    <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="2" column="0">
-                  <widget class="QLabel" name="startOverlapLabel">
-                    <property name="text">
-                      <string>StartOverlap</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="2" column="1">
-                  <widget class="QLineEdit" name="startOverlapEdit"/>
-                </item>
-                <item row="2" column="2">
-                  <widget class="QLabel" name="endOverlapLabel">
-                    <property name="text">
-                      <string>EndOverlap</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="2" column="3">
-                  <widget class="QLineEdit" name="endOverlapEdit"/>
-                </item>
-                <item row="2" column="4">
-                  <spacer name="expSettings0Spacer2">
-                    <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="3" column="0">
-                  <widget class="QLabel" name="polCorrLabel">
-                    <property name="text">
-                      <string>PolarisationCorrections</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="3" column="1">
-                  <widget class="QComboBox" name="polCorrComboBox">
-                    <item>
-                      <property name="text">
-                        <string>None</string>
-                      </property>
-                    </item>
-                    <item>
-                      <property name="text">
-                        <string>PA</string>
-                      </property>
-                    </item>
-                    <item>
-                      <property name="text">
-                        <string>PNR</string>
-                      </property>
-                    </item>
-                  </widget>
-                </item>
-                <item row="3" column="2">
-                  <spacer name="expSettings0Spacer3">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-                <item row="4" column="0">
-                  <widget class="QLabel" name="CRhoLabel">
-                    <property name="text">
-                      <string>CRho</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="4" column="1">
-                  <widget class="QLineEdit" name="CRhoEdit"/>
-                </item>
-                <item row="4" column="2">
-                  <widget class="QLabel" name="CAlphaLabel">
-                    <property name="text">
-                      <string>CAlpha</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="4" column="3">
-                  <widget class="QLineEdit" name="CAlphaEdit"/>
-                </item>
-                <item row="4" column="4">
-                  <spacer name="expSettings0Spacer4">
-                    <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="5" column="0">
-                  <widget class="QLabel" name="CApLabel">
-                    <property name="text">
-                      <string>CAp</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="5" column="1">
-                  <widget class="QLineEdit" name="CApEdit"/>
-                </item>
-                <item row="5" column="2">
-                  <widget class="QLabel" name="CPpLabel">
-                    <property name="text">
-                      <string>CPp</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="5" column="3">
-                  <widget class="QLineEdit" name="CPpEdit"/>
-                </item>
-                <item row="5" column="4">
-                  <spacer name="expSettings0Spacer5">
-                    <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="6" column="0">
-                  <widget class="QLabel" name="momentumTransferStepLabel">
-                    <property name="text">
-                      <string>dQ/Q</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="6" column="1">
-                  <widget class="QLineEdit" name="momentumTransferStepEdit"/>
-                </item>
-                <item row="6" column="2">
-                  <widget class="QLabel" name="scaleFactorLabel">
-                    <property name="text">
-                      <string>Scale</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="6" column="3">
-                  <widget class="QLineEdit" name="scaleFactorEdit"/>
-                </item>
-                <item row="6" column="4">
-                  <spacer name="expSettings0Spacer6">
-                    <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="7" column="0">
-                  <widget class="QLabel" name="stitchLabel">
-                    <property name="text">
-                      <string>Stitch1DMany</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="7" column="4">
-                  <spacer name="expSettings0Spacer7">
-                    <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>
-            </item>
-            <item>
-              <layout class="QGridLayout" name="expSettingsLayout1">
-                <property name="margin">
-                  <number>10</number>
-                </property>
-                <item row="0" column="0">
-                  <widget class="QPushButton" name="getExpDefaultsButton">
-                    <property name="fixedWidth">
-                      <number>70</number>
-                    </property>
-                    <property name="fixedHeight">
-                      <number>100</number>
-                    </property>
-                    <layout class="QHBoxLayout" name="getExpDefaultsButtonLayout">
-                      <item>
-                        <widget class="QLabel" name="getExpDefaultsButtonLabel">
-                          <property name="wordWrap">
-                            <bool>true</bool>
-                          </property>
-                          <property name="alignment">
-                            <set>Qt::AlignCenter</set>
-                          </property>
-                          <property name="text">
-                            <string>Get Defaults</string>
-                          </property>
-                        </widget>
-                      </item>
-                    </layout>
-                  </widget>
-                </item>
-              </layout>
-            </item>
-          </layout>
-        </widget>
-      </item>
-      <item>
-        <widget class="QGroupBox" name="instSettingsGroup">
-          <property name="title">
-            <string>Instrument Settings</string>
-          </property>
-          <property name="checkable">
-            <bool>true</bool>
-          </property>
-          <layout class="QHBoxLayout" name="instSettingsLayoutContainer">
-            <item>
-              <layout class="QGridLayout" name="instSettingsLayout0">
-                <property name="margin">
-                  <number>10</number>
-                </property>
-                <item row="0" column="0">
-                  <widget class="QLabel" name="intMonCheckLabel">
-                    <property name="text">
-                      <string>IntegratedMonitors</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="0" column="1">
-                  <widget class="QCheckBox" name="intMonCheckBox">
-                    <property name="checkState">
-                      <set>Qt::Checked</set>
-                    </property>
-                  </widget>
-                </item>
-                <item row="0" column="2">
-                  <spacer name="instSettings0Spacer0">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-                <item row="1" column="0">
-                  <widget class="QLabel" name="monIntMinLabel">
-                    <property name="text">
-                      <string>MonitorIntegralMin</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="1" column="1">
-                  <widget class="QLineEdit" name="monIntMinEdit"/>
-                </item>
-                <item row="1" column="2">
-                  <widget class="QLabel" name="monIntMaxLabel">
-                    <property name="text">
-                      <string>MonitorIntegralMax</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="1" column="3">
-                  <widget class="QLineEdit" name="monIntMaxEdit"/>
-                </item>
-                <item row="1" column="4">
-                  <spacer name="instSettings0Spacer1">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-                <item row="2" column="0">
-                  <widget class="QLabel" name="monBgMinLabel">
-                    <property name="text">
-                      <string>MonitorBackgroundMin</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="2" column="1">
-                  <widget class="QLineEdit" name="monBgMinEdit"/>
-                </item>
-                <item row="2" column="2">
-                  <widget class="QLabel" name="monBgMaxLabel">
-                    <property name="text">
-                      <string>MonitorBackgroundMax</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="2" column="3">
-                  <widget class="QLineEdit" name="monBgMaxEdit"/>
-                </item>
-                <item row="2" column="4">
-                  <spacer name="instSettings0Spacer2">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-                <item row="3" column="0">
-                  <widget class="QLabel" name="lamMinLabel">
-                    <property name="text">
-                      <string>LambdaMin</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="3" column="1">
-                  <widget class="QLineEdit" name="lamMinEdit"/>
-                </item>
-                <item row="3" column="2">
-                  <widget class="QLabel" name="lamMaxLabel">
-                    <property name="text">
-                      <string>LambdaMax</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="3" column="3">
-                  <widget class="QLineEdit" name="lamMaxEdit"/>
-                </item>
-                <item row="3" column="4">
-                  <spacer name="instSettings0Spacer3">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-                <item row="4" column="0">
-                  <widget class="QLabel" name="I0MonIndexLabel">
-                    <property name="text">
-                      <string>I0MonitorIndex</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="4" column="1">
-                  <widget class="QLineEdit" name="I0MonIndexEdit"/>
-                </item>
-                <item row="4" column="2">
-                  <widget class="QLabel" name="procInstLabel">
-                    <property name="text">
-                      <string>ProcessingInstructions</string>
-                    </property>
-                  </widget>
-                </item>
-                <item row="4" column="3">
-                  <widget class="QLineEdit" name="procInstEdit"/>
-                </item>
-                <item row="4" column="4">
-                  <spacer name="instSettings0Spacer4">
-                    <property name="orientation">
-                      <enum>Qt::Horizontal</enum>
-                    </property>
-                    <property name="sizeHint" stdset="0">
-                      <size>
-                        <width>40</width>
-                        <height>20</height>
-                      </size>
-                    </property>
-                  </spacer>
-                </item>
-              </layout>
-            </item>
-            <item>
-              <layout class="QGridLayout" name="instSettingsLayout1">
-                <property name="margin">
-                  <number>10</number>
-                </property>
-                <item row="0" column="0">
-                  <widget class="QPushButton" name="getInstDefaultsButton">
-                    <property name="fixedWidth">
-                      <number>70</number>
-                    </property>
-                    <property name="fixedHeight">
-                      <number>100</number>
-                    </property>
-                    <layout class="QHBoxLayout" name="getInstDefaultsButtonLayout">
-                      <item>
-                        <widget class="QLabel" name="getInstDefaultsButtonLabel">
-                          <property name="wordWrap">
-                            <bool>true</bool>
-                          </property>
-                          <property name="alignment">
-                            <set>Qt::AlignCenter</set>
-                          </property>
-                          <property name="text">
-                            <string>Get Defaults</string>
-                          </property>
-                        </widget>
-                      </item>
-                    </layout>
-                  </widget>
-                </item>
-              </layout>
-            </item>
-          </layout>
+        <widget class="QToolBox" name="toolbox">
         </widget>
       </item>
     </layout>
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsWidget.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsWidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..ce85e5f7ca844b38d4ef757327190194dbb603f3
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Reflectometry/ReflSettingsWidget.ui
@@ -0,0 +1,545 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+  <class>ReflSettingsWidget</class>
+  <widget class="QWidget" name="ReflSettingsWidget">
+    <property name="geometry">
+      <rect>
+        <x>0</x>
+        <y>0</y>
+        <width>959</width>
+        <height>346</height>
+      </rect>
+    </property>
+    <property name="windowTitle">
+      <string>Settings Tab</string>
+    </property>
+    <layout class="QVBoxLayout" name="settingsMainLayout">
+      <property name="margin">
+        <number>5</number>
+      </property>
+      <item>
+        <widget class="QGroupBox" name="expSettingsGroup">
+          <property name="title">
+            <string>Experiment Settings</string>
+          </property>
+          <property name="checkable">
+            <bool>true</bool>
+          </property>
+          <layout class="QHBoxLayout" name="expSettingsLayoutContainer">
+            <item>
+              <layout class="QGridLayout" name="expSettingsLayout0">
+                <property name="margin">
+                  <number>10</number>
+                </property>
+                <item row="0" column="0">
+                  <widget class="QLabel" name="analysisModeLabel">
+                    <property name="text">
+                      <string>AnalysisMode</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="0" column="1">
+                  <widget class="QComboBox" name="analysisModeComboBox">
+                    <item>
+                      <property name="text">
+                        <string>PointDetectorAnalysis</string>
+                      </property>
+                    </item>
+                    <item>
+                      <property name="text">
+                        <string>MultiDetectorAnalysis</string>
+                      </property>
+                    </item>
+                  </widget>
+                </item>
+                <item row="0" column="2">
+                  <widget class="QLabel" name="expSettingsDirectBeamLabel">
+                    <property name="text">
+                      <string>DirectBeam</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="0" column="3">
+                  <widget class="QLineEdit" name="directBeamEdit"/>
+                </item>
+                <item row="0" column="4">
+                  <spacer name="expSettings0Spacer0">
+                    <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">
+                  <widget class="QLabel" name="transmissionRunsLabel">
+                    <property name="text">
+                      <string>Transmission run(s)</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="1" column="1">
+                  <widget class="QLineEdit" name="transmissionRunsEdit"/>
+                </item>
+                <item row="1" column="2">
+                  <spacer name="expSettings0Spacer1">
+                    <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="2" column="0">
+                  <widget class="QLabel" name="startOverlapLabel">
+                    <property name="text">
+                      <string>StartOverlap</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="2" column="1">
+                  <widget class="QLineEdit" name="startOverlapEdit"/>
+                </item>
+                <item row="2" column="2">
+                  <widget class="QLabel" name="endOverlapLabel">
+                    <property name="text">
+                      <string>EndOverlap</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="2" column="3">
+                  <widget class="QLineEdit" name="endOverlapEdit"/>
+                </item>
+                <item row="2" column="4">
+                  <spacer name="expSettings0Spacer2">
+                    <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="3" column="0">
+                  <widget class="QLabel" name="polCorrLabel">
+                    <property name="text">
+                      <string>PolarisationCorrections</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="3" column="1">
+                  <widget class="QComboBox" name="polCorrComboBox">
+                    <item>
+                      <property name="text">
+                        <string>None</string>
+                      </property>
+                    </item>
+                    <item>
+                      <property name="text">
+                        <string>PA</string>
+                      </property>
+                    </item>
+                    <item>
+                      <property name="text">
+                        <string>PNR</string>
+                      </property>
+                    </item>
+                  </widget>
+                </item>
+                <item row="3" column="2">
+                  <spacer name="expSettings0Spacer3">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+                <item row="4" column="0">
+                  <widget class="QLabel" name="CRhoLabel">
+                    <property name="text">
+                      <string>CRho</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="4" column="1">
+                  <widget class="QLineEdit" name="CRhoEdit"/>
+                </item>
+                <item row="4" column="2">
+                  <widget class="QLabel" name="CAlphaLabel">
+                    <property name="text">
+                      <string>CAlpha</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="4" column="3">
+                  <widget class="QLineEdit" name="CAlphaEdit"/>
+                </item>
+                <item row="4" column="4">
+                  <spacer name="expSettings0Spacer4">
+                    <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="5" column="0">
+                  <widget class="QLabel" name="CApLabel">
+                    <property name="text">
+                      <string>CAp</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="5" column="1">
+                  <widget class="QLineEdit" name="CApEdit"/>
+                </item>
+                <item row="5" column="2">
+                  <widget class="QLabel" name="CPpLabel">
+                    <property name="text">
+                      <string>CPp</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="5" column="3">
+                  <widget class="QLineEdit" name="CPpEdit"/>
+                </item>
+                <item row="5" column="4">
+                  <spacer name="expSettings0Spacer5">
+                    <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="6" column="0">
+                  <widget class="QLabel" name="momentumTransferStepLabel">
+                    <property name="text">
+                      <string>dQ/Q</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="6" column="1">
+                  <widget class="QLineEdit" name="momentumTransferStepEdit"/>
+                </item>
+                <item row="6" column="2">
+                  <widget class="QLabel" name="scaleFactorLabel">
+                    <property name="text">
+                      <string>Scale</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="6" column="3">
+                  <widget class="QLineEdit" name="scaleFactorEdit"/>
+                </item>
+                <item row="6" column="4">
+                  <spacer name="expSettings0Spacer6">
+                    <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="7" column="0">
+                  <widget class="QLabel" name="stitchLabel">
+                    <property name="text">
+                      <string>Stitch1DMany</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="7" column="4">
+                  <spacer name="expSettings0Spacer7">
+                    <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>
+            </item>
+            <item>
+              <layout class="QGridLayout" name="expSettingsLayout1">
+                <property name="margin">
+                  <number>10</number>
+                </property>
+                <item row="0" column="0">
+                  <widget class="QPushButton" name="getExpDefaultsButton">
+                    <property name="fixedWidth">
+                      <number>70</number>
+                    </property>
+                    <property name="fixedHeight">
+                      <number>100</number>
+                    </property>
+                    <layout class="QHBoxLayout" name="getExpDefaultsButtonLayout">
+                      <item>
+                        <widget class="QLabel" name="getExpDefaultsButtonLabel">
+                          <property name="wordWrap">
+                            <bool>true</bool>
+                          </property>
+                          <property name="alignment">
+                            <set>Qt::AlignCenter</set>
+                          </property>
+                          <property name="text">
+                            <string>Get Defaults</string>
+                          </property>
+                        </widget>
+                      </item>
+                    </layout>
+                  </widget>
+                </item>
+              </layout>
+            </item>
+          </layout>
+        </widget>
+      </item>
+      <item>
+        <widget class="QGroupBox" name="instSettingsGroup">
+          <property name="title">
+            <string>Instrument Settings</string>
+          </property>
+          <property name="checkable">
+            <bool>true</bool>
+          </property>
+          <layout class="QHBoxLayout" name="instSettingsLayoutContainer">
+            <item>
+              <layout class="QGridLayout" name="instSettingsLayout0">
+                <property name="margin">
+                  <number>10</number>
+                </property>
+                <item row="0" column="0">
+                  <widget class="QLabel" name="intMonCheckLabel">
+                    <property name="text">
+                      <string>IntegratedMonitors</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="0" column="1">
+                  <widget class="QCheckBox" name="intMonCheckBox">
+                    <property name="checkState">
+                      <set>Qt::Checked</set>
+                    </property>
+                  </widget>
+                </item>
+                <item row="0" column="2">
+                  <spacer name="instSettings0Spacer0">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+                <item row="1" column="0">
+                  <widget class="QLabel" name="monIntMinLabel">
+                    <property name="text">
+                      <string>MonitorIntegralMin</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="1" column="1">
+                  <widget class="QLineEdit" name="monIntMinEdit"/>
+                </item>
+                <item row="1" column="2">
+                  <widget class="QLabel" name="monIntMaxLabel">
+                    <property name="text">
+                      <string>MonitorIntegralMax</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="1" column="3">
+                  <widget class="QLineEdit" name="monIntMaxEdit"/>
+                </item>
+                <item row="1" column="4">
+                  <spacer name="instSettings0Spacer1">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+                <item row="2" column="0">
+                  <widget class="QLabel" name="monBgMinLabel">
+                    <property name="text">
+                      <string>MonitorBackgroundMin</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="2" column="1">
+                  <widget class="QLineEdit" name="monBgMinEdit"/>
+                </item>
+                <item row="2" column="2">
+                  <widget class="QLabel" name="monBgMaxLabel">
+                    <property name="text">
+                      <string>MonitorBackgroundMax</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="2" column="3">
+                  <widget class="QLineEdit" name="monBgMaxEdit"/>
+                </item>
+                <item row="2" column="4">
+                  <spacer name="instSettings0Spacer2">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+                <item row="3" column="0">
+                  <widget class="QLabel" name="lamMinLabel">
+                    <property name="text">
+                      <string>LambdaMin</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="3" column="1">
+                  <widget class="QLineEdit" name="lamMinEdit"/>
+                </item>
+                <item row="3" column="2">
+                  <widget class="QLabel" name="lamMaxLabel">
+                    <property name="text">
+                      <string>LambdaMax</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="3" column="3">
+                  <widget class="QLineEdit" name="lamMaxEdit"/>
+                </item>
+                <item row="3" column="4">
+                  <spacer name="instSettings0Spacer3">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+                <item row="4" column="0">
+                  <widget class="QLabel" name="I0MonIndexLabel">
+                    <property name="text">
+                      <string>I0MonitorIndex</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="4" column="1">
+                  <widget class="QLineEdit" name="I0MonIndexEdit"/>
+                </item>
+                <item row="4" column="2">
+                  <widget class="QLabel" name="procInstLabel">
+                    <property name="text">
+                      <string>ProcessingInstructions</string>
+                    </property>
+                  </widget>
+                </item>
+                <item row="4" column="3">
+                  <widget class="QLineEdit" name="procInstEdit"/>
+                </item>
+                <item row="4" column="4">
+                  <spacer name="instSettings0Spacer4">
+                    <property name="orientation">
+                      <enum>Qt::Horizontal</enum>
+                    </property>
+                    <property name="sizeHint" stdset="0">
+                      <size>
+                        <width>40</width>
+                        <height>20</height>
+                      </size>
+                    </property>
+                  </spacer>
+                </item>
+              </layout>
+            </item>
+            <item>
+              <layout class="QGridLayout" name="instSettingsLayout1">
+                <property name="margin">
+                  <number>10</number>
+                </property>
+                <item row="0" column="0">
+                  <widget class="QPushButton" name="getInstDefaultsButton">
+                    <property name="fixedWidth">
+                      <number>70</number>
+                    </property>
+                    <property name="fixedHeight">
+                      <number>100</number>
+                    </property>
+                    <layout class="QHBoxLayout" name="getInstDefaultsButtonLayout">
+                      <item>
+                        <widget class="QLabel" name="getInstDefaultsButtonLabel">
+                          <property name="wordWrap">
+                            <bool>true</bool>
+                          </property>
+                          <property name="alignment">
+                            <set>Qt::AlignCenter</set>
+                          </property>
+                          <property name="text">
+                            <string>Get Defaults</string>
+                          </property>
+                        </widget>
+                      </item>
+                    </layout>
+                  </widget>
+                </item>
+              </layout>
+            </item>
+          </layout>
+        </widget>
+      </item>
+    </layout>
+  </widget>
+  <tabstops/>
+  <customwidgets/>
+  <resources/>
+  <connections/>
+</ui>
\ No newline at end of file
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui
index 7f5bb741455901791e2b8e10cc0de10ee6715316..0d418b6b63db50702e1c583152f908ab1d4d104c 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/StepScan.ui
@@ -37,7 +37,7 @@
         </stringlist>
        </property>
        <property name="liveButton" stdset="0">
-        <enum>MantidQt::MantidWidgets::MWRunFiles::AlwaysShow</enum>
+        <enum>MantidQt::MantidWidgets::MWRunFiles::Show</enum>
        </property>
       </widget>
      </item>
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h
index a895e6de746feb2f7bbac64a4678945cca842ce3..d9e1bd342083e2bc1b6fcb5cb9e26b99548de539 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h
@@ -6,8 +6,8 @@
 #include "MantidAPI/MatrixWorkspace_fwd.h"
 #include "MantidQtCustomInterfaces/Tomography/ImageStackPreParams.h"
 #include "MantidQtCustomInterfaces/Tomography/TomoPathsConfig.h"
-#include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h"
 #include "MantidQtCustomInterfaces/Tomography/TomoReconFiltersSettings.h"
+#include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h"
 #include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h"
 
 #include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h"
@@ -319,6 +319,16 @@ public:
    * @param alg algorithm initialized and ready to run.
    */
   virtual void runAggregateBands(Mantid::API::IAlgorithm_sptr alg) = 0;
+
+  /**
+   * Prompts the user for confirmation with a yes/no dialogue.
+   * The body can use HTML formatting.
+   *
+   * @param title The title that the message has
+   * @param body The body that the message has. This CAN use HTML formatting
+   */
+  virtual bool userConfirmation(const std::string &title,
+                                const std::string &body) = 0;
 };
 
 } // namespace CustomInterfaces
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageROIPresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageROIPresenter.h
index f4853d99f45c73564d3289d56bdd7ff6a2f9b5bc..bb601de9f8b3b0e97c20aaaacb3eb99515327183 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageROIPresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/ImageROIPresenter.h
@@ -74,6 +74,9 @@ protected:
   void processBrowseImage();
   void processBrowseStack();
   void processNewStack(bool singleImage);
+  void processLoadSingleImage();
+  void processLoadStackOfImages();
+  void setupAlgorithmRunnerAfterLoad();
   void processChangeImageType();
   void processChangeRotation();
   void processPlayStartStop();
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h
index aa603d6ac9695724ef6d6fdd84a795dba419228a..3c64d78ed5772872e0ab569882ad6196b3ad014d 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h
@@ -12,16 +12,14 @@
 #include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h"
 #include "MantidQtCustomInterfaces/Tomography/TomoSystemSettings.h"
 
-// Qt classes forward declarations
-class QMutex;
-
-namespace Poco {
-class Pipe;
-}
+// Include instead of forward declare so we have definition of qint64
+#include <QMutex>
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
+class TomographyProcess;
+class TomographyThread;
 /**
 Tomography GUI. Model for the interface (as in the MVP
 (Model-View-Presenter) pattern). In principle, in a strict MVP setup,
@@ -149,11 +147,26 @@ public:
                         std::vector<std::string> &status,
                         std::vector<std::string> &cmds);
   /// Submit a new job to the (remote or local) compute resource
-  void doSubmitReconstructionJob(const std::string &compRes);
+  void prepareSubmissionArguments(const bool local, std::string &runnable,
+                                  std::vector<std::string> &args,
+                                  std::string &allOpts);
+
+  void doLocalRunReconstructionJob(
+      const std::string &runnable, const std::vector<std::string> &args,
+      const std::string &allOpts,
+      MantidQt::CustomInterfaces::TomographyThread &thread,
+      MantidQt::CustomInterfaces::TomographyProcess &worker);
+
+  void doRemoteRunReconstructionJob(const std::string &compRes,
+                                    const std::string &runnable,
+                                    const std::string &allOpts);
 
   /// Cancel a previously submitted job
   void doCancelJobs(const std::string &compRes,
                     const std::vector<std::string> &id);
+
+  void addJobToStatus(const qint64 pid, const std::string &runnable,
+                      const std::string &allOpts);
   /// Get fresh status information on running/recent jobs
   void doRefreshJobsInfo(const std::string &compRes);
 
@@ -179,6 +192,7 @@ public:
 
   /// Log this message through the system logging
   void logMsg(const std::string &msg);
+  void logErrMsg(const std::string &msg);
 
   /// for clean destruction
   void cleanup();
@@ -186,6 +200,8 @@ public:
   std::string localComputeResource() const { return g_LocalResourceName; }
 
   void setTomoPathsConfig(const TomoPathsConfig &tc) { m_pathsConfig = tc; }
+  void updateProcessInJobList(const qint64 pid, const int exitCode);
+  void terminateProcess();
 
   // Names of reconstruction tools
   static const std::string g_TomoPyTool;
@@ -208,25 +224,14 @@ protected: // protected to expose everything to testing
   std::string
   constructSingleStringFromVector(const std::vector<std::string> args) const;
 
-  void doRunReconstructionJobLocal(const std::string &run,
-                                   const std::string &allOpts,
-                                   const std::vector<std::string> &args);
-
-  void doRunReconstructionJobRemote(const std::string &compRes,
-                                    const std::string &run,
-                                    const std::string &allOpts);
-
   /// retrieve info from compute resource into status table
   void getJobStatusInfo(const std::string &compRes);
 
   std::string validateCompResource(const std::string &res) const;
 
-  /// makes the command line string to run on the remote/local
-  void makeRunnableWithOptions(const std::string &comp, std::string &run,
-                               std::vector<std::string> &opt) const;
-
   bool checkIfToolIsSetupProperly(const std::string &tool,
-                                  const std::string &cmd) const;
+                                  const std::string &cmd,
+                                  const std::vector<std::string> &args) const;
 
   void makeTomoRecScriptOptions(const bool local,
                                 std::vector<std::string> &opts) const;
@@ -236,7 +241,7 @@ protected: // protected to expose everything to testing
                            const bool local,
                            std::vector<std::string> &opts) const;
 
-  void splitCmdLine(const std::string &cmd, std::string &run,
+  void splitCmdLine(const std::string &cmd, std::string &runnable,
                     std::string &opts) const;
 
   /// process the tool name to be appropriate for the command line arg
@@ -250,7 +255,7 @@ protected: // protected to expose everything to testing
   std::string buildOutReconstructionDir(const std::string &samplesDir,
                                         bool) const;
 
-  bool processIsRunning(int pid);
+  bool processIsRunning(qint64 pid) const;
 
   std::string
   buildOutReconstructionDirFromSystemRoot(const std::string &samplesDir,
@@ -259,10 +264,6 @@ protected: // protected to expose everything to testing
   std::string
   buildOutReconstructionDirFromSamplesDir(const std::string &samplesDir) const;
 
-  /// Prints the streams from the Poco::launch process into mantid
-  void printProcessStreamsToMantidLog(const Poco::Pipe &outPipe,
-                                      const Poco::Pipe &errPipe);
-
 private:
   /// facility for the remote compute resource
   const std::string m_facility;
@@ -291,6 +292,7 @@ private:
   /// reconstruction tools available on SCARF
   std::vector<std::string> m_SCARFtools;
 
+  // Paths for the sample, flat and dark images
   TomoPathsConfig m_pathsConfig;
 
   // System settting including several paths and parameters (local and remote)
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h
index 874f6587f3c90b40a97871cf7f4cc635c1605625..6665302ba8fe5613bebaa98f1df0c596bf838d8e 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h
@@ -6,9 +6,9 @@
 #include "MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h"
 #include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
 
-#include <boost/scoped_ptr.hpp>
 #include <QMutex>
 #include <QObject>
+#include <boost/scoped_ptr.hpp>
 
 // Qt classes forward declarations
 class QThread;
@@ -50,7 +50,6 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class MANTIDQT_CUSTOMINTERFACES_DLL TomographyIfacePresenter
     : public QObject,
       public ITomographyIfacePresenter {
-  // Q_OBJECT for the 'keep alive' signals
   Q_OBJECT
 
 public:
@@ -66,6 +65,7 @@ protected:
   /// clean shut down of model, view, etc.
   void cleanup();
 
+  // notification methods
   void processSystemSettingsUpdated();
   void processSetupResourcesAndTools();
   void processCompResourceChanged();
@@ -76,12 +76,6 @@ protected:
   void processLogout();
   void processSetupReconTool();
   void processRunRecon();
-
-protected slots:
-  /// It may be run on user request, or periodically from a timer/thread
-  void processRefreshJobs();
-
-protected:
   void processCancelJobs();
   void processVisualizeJobs();
   void processViewImg();
@@ -91,10 +85,6 @@ protected:
 
   void doVisualize(const std::vector<std::string> &ids);
 
-  /// To prepare a local run
-  void makeRunnableWithOptionsLocal(const std::string &comp, std::string &run,
-                                    std::string &opt);
-
   /// auto-guess additional directories when the user gives the samples path
   void findFlatsDarksFromSampleGivenByUser(TomoPathsConfig &cfg);
 
@@ -108,8 +98,24 @@ protected:
   void killKeepAliveMechanism();
 
   bool isLocalResourceSelected() const;
+signals:
+  void terminated();
+
+protected slots:
+  /// It may be run on user request, or periodically from a timer/thread
+  void processRefreshJobs();
+  void readWorkerStdOut(const QString &s);
+  void readWorkerStdErr(const QString &s);
+  void addProcessToJobList();
+  void reconProcessFailedToStart();
+  void workerFinished(const qint64 pid, const int exitCode);
 
 private:
+  /// Asks the user for permission to cancel the running reconstruction
+  bool userConfirmationToCancelRecon();
+  void setupAndRunLocalReconstruction(const std::string &runnable,
+                                      const std::vector<std::string> &args,
+                                      const std::string &allOpts);
   /// creates the correct dialog pointer and sets it to the member variable
   void createConfigDialogUsingToolName(const std::string &toolName);
 
@@ -150,12 +156,15 @@ private:
 
   // for periodic update of the job status table/tree
   QTimer *m_keepAliveTimer;
-  QThread *m_keepAliveThread;
+
+  std::unique_ptr<TomographyThread> m_workerThread;
 
   std::unique_ptr<TomoToolConfigDialogBase> m_configDialog;
 
   static const std::string g_defOutPathLocal;
   static const std::string g_defOutPathRemote;
+
+  bool m_reconRunning = false;
 };
 
 } // namespace CustomInterfaces
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceQtTabRun.ui b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceQtTabRun.ui
index b01dccc1e18272912bf6eb9db659638520878a07..2f41dd946e6d0b32a0cbfeae38d88ac7864cd26b 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceQtTabRun.ui
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceQtTabRun.ui
@@ -86,7 +86,16 @@
            <enum>QFrame::Raised</enum>
           </property>
           <layout class="QGridLayout" name="gridLayout_13">
-           <property name="margin">
+           <property name="leftMargin">
+            <number>3</number>
+           </property>
+           <property name="topMargin">
+            <number>3</number>
+           </property>
+           <property name="rightMargin">
+            <number>3</number>
+           </property>
+           <property name="bottomMargin">
             <number>3</number>
            </property>
            <property name="spacing">
@@ -105,7 +114,7 @@
                <rect>
                 <x>0</x>
                 <y>0</y>
-                <width>273</width>
+                <width>268</width>
                 <height>256</height>
                </rect>
               </property>
@@ -116,7 +125,16 @@
                </sizepolicy>
               </property>
               <layout class="QGridLayout" name="gridLayout_5">
-               <property name="margin">
+               <property name="leftMargin">
+                <number>0</number>
+               </property>
+               <property name="topMargin">
+                <number>0</number>
+               </property>
+               <property name="rightMargin">
+                <number>0</number>
+               </property>
+               <property name="bottomMargin">
                 <number>0</number>
                </property>
                <property name="spacing">
@@ -412,9 +430,15 @@
             <verstretch>1</verstretch>
            </sizepolicy>
           </property>
+          <property name="editTriggers">
+           <set>QAbstractItemView::NoEditTriggers</set>
+          </property>
           <property name="selectionBehavior">
            <enum>QAbstractItemView::SelectRows</enum>
           </property>
+          <property name="sortingEnabled">
+           <bool>false</bool>
+          </property>
           <attribute name="horizontalHeaderStretchLastSection">
            <bool>true</bool>
           </attribute>
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h
index 0b81d276d5f507ecf84a48ce803325f0e3a4642e..03b0df36b5e9ee1c4e941ed26e93d01118a74492 100644
--- a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h
@@ -157,6 +157,9 @@ public:
 
   void runAggregateBands(Mantid::API::IAlgorithm_sptr alg) override;
 
+  bool userConfirmation(const std::string &title,
+                        const std::string &body) override;
+
 private slots:
   /// for buttons, run tab, and similar
   void reconstructClicked();
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyProcess.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyProcess.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ec67be58ab763754e43acd570e234159030ec59
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyProcess.h
@@ -0,0 +1,93 @@
+#ifndef MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOMOGRAPHYPROCESS_H_
+#define MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOMOGRAPHYPROCESS_H_
+
+#include <QProcess>
+#include <QString>
+#include <QStringList>
+#include <vector>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+/*
+TomographyProcess class that run external processes and provides some helper
+functions. This class was designed to be used with TomographyThread to run
+external processes asyncronously to the main thread 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 TomographyProcess : public QProcess {
+  Q_OBJECT
+public:
+  // we want a nullptr for parent so we can move it to a thread
+  TomographyProcess() : QProcess(nullptr) {}
+
+  // intentionally copy the vector
+  void setup(const std::string &runnable, const std::vector<std::string> &args,
+             const std::string &allOpts) {
+    m_allArgs = allOpts;
+    m_runnable = QString::fromStdString(runnable);
+    m_args = buildArguments(args);
+  }
+
+  std::string getRunnable() const { return m_runnable.toStdString(); }
+  std::string getArgs() const { return m_allArgs; }
+
+  qint64 getPID() const {
+    auto pid = this->pid();
+
+    // qt connect could sometimes try to read the terminated process' PID
+    if (!pid) {
+      return 0;
+    }
+
+#ifdef _WIN32
+    // windows gets a struct object with more info
+    auto actualpid = static_cast<qint64>(pid->dwProcessId);
+#else
+    // linux just gets the PID
+    auto actualpid = static_cast<qint64>(pid);
+#endif
+    return actualpid;
+  }
+
+public slots:
+  /** This method should be used to start the worker as it passes the setup
+   * runnable and args parameters into the base start method
+  */
+  void startWorker() { start(m_runnable, m_args); }
+
+private:
+  QStringList buildArguments(const std::vector<std::string> &args) const {
+    QStringList list;
+    list.reserve(static_cast<int>(args.size()));
+
+    for (const auto &arg : args) {
+      list << QString::fromStdString(arg);
+    }
+
+    return list;
+  }
+
+  QString m_runnable;
+  QStringList m_args;
+
+  std::string m_allArgs;
+};
+} // CustomInterfaces
+} // MantidQt
+#endif
diff --git a/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyThread.h b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyThread.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8add9afeb49aee3c37e512703bfeb50237705d3
--- /dev/null
+++ b/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Tomography/TomographyThread.h
@@ -0,0 +1,113 @@
+#ifndef MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOMOGRAPHYTHREAD_H_
+#define MANTIDQTCUSTOMINTERFACES_TOMOGRAPHY_TOMOGRAPHYTHREAD_H_
+
+// included for UNUSED_ARG
+#include "MantidKernel/System.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyProcess.h"
+#include <QString>
+#include <QThread>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+/*
+TomographyThread class that can handle a single worker, and get all the standard
+output and standard error content from the process.
+
+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 TomographyThread : public QThread {
+  Q_OBJECT
+public:
+  TomographyThread(QObject *parent, TomographyProcess *worker)
+      : QThread(parent), m_worker(worker) {
+    // interactions between the thread and the worker are defined here
+    connect(this, SIGNAL(started()), worker, SLOT(startWorker()));
+    connect(this, SIGNAL(started()), this, SLOT(startWorker()));
+
+    connect(worker, SIGNAL(readyReadStandardOutput()), this,
+            SLOT(readWorkerStdOut()));
+    connect(worker, SIGNAL(readyReadStandardError()), this,
+            SLOT(readWorkerStdErr()));
+
+    connect(worker, SIGNAL(finished(int)), this, SLOT(finished(int)));
+
+    connect(this, SIGNAL(finished()), this, SLOT(deleteLater()),
+            Qt::DirectConnection);
+
+    connect(this, SIGNAL(terminated()), worker, SLOT(terminate()));
+    m_worker->moveToThread(this);
+  }
+
+  ~TomographyThread() override {
+    // this will terminate the process if another reconstruction is started,
+    // thus not allowing to have multiple reconstructions running at the same
+    // time
+    emit terminated();
+
+    // this causes segfault in processRefreshJobs if the check isnt here
+    if (m_workerRunning || !m_worker) {
+      // emit that the worker has been forcefully closed, exit with error code 1
+      // this is bad, find a way to notify without an explicit emit on thread
+      // destroy
+      emit workerFinished(m_workerPID, 1);
+    }
+  }
+
+  void setProcessPID(const qint64 pid) { m_workerPID = pid; }
+
+  qint64 getProcessPID() const { return m_workerPID; }
+
+public slots:
+  void finished(const int exitCode) {
+    // queue up object deletion
+    m_worker->deleteLater();
+    m_workerRunning = false;
+    // emit the exit code to the presenter so the process info can be updated
+    emit workerFinished(m_workerPID, exitCode);
+  }
+
+  void readWorkerStdOut() const {
+    auto *worker = qobject_cast<TomographyProcess *>(sender());
+    QString out(worker->readAllStandardOutput());
+    if (!out.isEmpty())
+      emit stdOutReady(out.trimmed());
+  }
+
+  void readWorkerStdErr() const {
+    auto *worker = qobject_cast<TomographyProcess *>(sender());
+    QString out(worker->readAllStandardError());
+
+    if (!out.isEmpty())
+      emit stdErrReady(out.trimmed());
+  }
+
+  void startWorker() { m_workerRunning = true; }
+
+signals:
+  void workerFinished(const qint64, const int);
+  void stdOutReady(const QString &s) const;
+  void stdErrReady(const QString &s) const;
+
+private:
+  bool m_workerRunning = false;
+  /// Holder for the current running process' PID
+  qint64 m_workerPID;
+  TomographyProcess *const m_worker;
+};
+} // CustomInterfaces
+} // MantidQt
+#endif
diff --git a/MantidQt/CustomInterfaces/src/DataComparison.cpp b/MantidQt/CustomInterfaces/src/DataComparison.cpp
index a40d74aab6ad751ca0f8447b32f9356bbbabdce2..465dfa3d430d368f739ef16539aaf90f65d78e9b 100644
--- a/MantidQt/CustomInterfaces/src/DataComparison.cpp
+++ b/MantidQt/CustomInterfaces/src/DataComparison.cpp
@@ -1,11 +1,9 @@
-//----------------------
-// Includes
-//----------------------
 #include "MantidQtCustomInterfaces/DataComparison.h"
 
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidQtAPI/QwtWorkspaceSpectrumData.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 namespace {
 Mantid::Kernel::Logger g_log("DataComparison");
diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffFittingPresenter.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffFittingPresenter.cpp
index 6f7f31fe0f0b2635d76388c5f805a8bd64631f58..b3c2a6acd6472dbb438f479e9e53ebbe8bc4686e 100644
--- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffFittingPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffFittingPresenter.cpp
@@ -1,5 +1,6 @@
 #include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffFittingPresenter.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -10,6 +11,7 @@
 
 #include <boost/lexical_cast.hpp>
 #include <fstream>
+#include <cctype>
 
 #include <Poco/DirectoryIterator.h>
 #include <Poco/File.h>
diff --git a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp
index 6e4c80731e3659b74c66d398b5213804d8c6a9de..5c8e7b74c17ace268e1248ed2e496b5ad50bf767 100644
--- a/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/EnggDiffraction/EnggDiffractionPresenter.cpp
@@ -1,16 +1,17 @@
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidKernel/Property.h"
 #include "MantidKernel/StringTokenizer.h"
 #include "MantidQtAPI/PythonRunner.h"
-// #include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionModel.h"
 #include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresWorker.h"
 #include "MantidQtCustomInterfaces/EnggDiffraction/EnggDiffractionPresenter.h"
 #include "MantidQtCustomInterfaces/EnggDiffraction/IEnggDiffractionView.h"
 
 #include <algorithm>
+#include <cctype>
 #include <fstream>
 
 #include <boost/lexical_cast.hpp>
@@ -182,14 +183,12 @@ void EnggDiffractionPresenter::notify(
 void EnggDiffractionPresenter::processStart() {
   EnggDiffCalibSettings cs = m_view->currentCalibSettings();
   m_view->showStatus("Ready");
-
-  updateNewCalib(m_view->currentCalibFile());
 }
 
 void EnggDiffractionPresenter::processLoadExistingCalib() {
   EnggDiffCalibSettings cs = m_view->currentCalibSettings();
 
-  std::string fname = m_view->askExistingCalibFilename();
+  const std::string fname = m_view->askExistingCalibFilename();
   if (fname.empty()) {
     return;
   }
diff --git a/MantidQt/CustomInterfaces/src/Homer.cpp b/MantidQt/CustomInterfaces/src/Homer.cpp
index 19effc35cdceb15fdf1e7b72b24f415a09e6492c..2a7a8b141b87392c5f56cd813d42064def8245d7 100644
--- a/MantidQt/CustomInterfaces/src/Homer.cpp
+++ b/MantidQt/CustomInterfaces/src/Homer.cpp
@@ -2,7 +2,6 @@
 #include "MantidQtCustomInterfaces/Background.h"
 #include "MantidQtCustomInterfaces/deltaECalc.h"
 #include "MantidQtMantidWidgets/MWDiag.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/MantidDesktopServices.h"
 
 #include "MantidKernel/ConfigService.h"
@@ -392,8 +391,8 @@ QString Homer::openFileDia(const bool save, const QStringList &exts) {
 
   QString filename;
   if (save) {
-    filename = API::FileDialogHandler::getSaveFileName(this, "Save file",
-                                                       m_lastSaveDir, filter);
+    filename =
+        QFileDialog::getSaveFileName(this, "Save file", m_lastSaveDir, filter);
     if (!filename.isEmpty()) {
       m_lastSaveDir = QFileInfo(filename).absoluteDir().path();
     }
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp b/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp
index 5806df93a0c5fb7e052a763eec7b0b2c6b8396c2..d74bd9d0a46be05a88ad4c51b3ae9a4591c45d13 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ApplyPaalmanPings.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/TextAxis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QStringList>
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp b/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp
index e870bf063f7ee59a0ed55939988e91f64bd325e4..8415d58a36cbdbb1eade1ec1151e01ccc636ae72 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/CalculatePaalmanPings.cpp
@@ -3,6 +3,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/Unit.h"
 #include "MantidKernel/Material.h"
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
index f4ce56d9d490971dbe31f0d4214d2464ff41a283..840e0e01b301e99a00055e9770453ef8d2e3f4dd 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
@@ -8,6 +8,7 @@
 #include "MantidAPI/FunctionDomain1D.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/TextAxis.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 
 #include <QDoubleValidator>
@@ -323,6 +324,11 @@ void ConvFit::plotClicked() {
         const auto specNumber = m_uiForm.cbPlotType->currentIndex();
         IndirectTab::plotSpectrum(QString::fromStdString(resultWs->getName()),
                                   specNumber, specNumber);
+        // Plot results for both Lorentzians if "Two Lorentzians"
+        if (m_uiForm.cbFitType->currentIndex() == 2) {
+          IndirectTab::plotSpectrum(QString::fromStdString(resultWs->getName()),
+                                    specNumber + 2, specNumber + 2);
+        }
       }
     }
   } else {
@@ -1539,18 +1545,17 @@ QStringList ConvFit::getFunctionParameters(QString functionName) {
     }
   }
   // Add another Lorentzian function parameter for two Lorentzian fit
-  if (functionName.compare("Two Lorentzian") == 0) {
+  if (functionName.compare("Two Lorentzians") == 0) {
     currentFitFunction = "Lorentzian";
-  }
-  if (functionName.compare("Zero Lorentzians") == 0) {
-    parameters.append("Zero");
-  } else {
     IFunction_sptr func = FunctionFactory::Instance().createFunction(
         currentFitFunction.toStdString());
     for (size_t i = 0; i < func->nParams(); i++) {
       parameters << QString::fromStdString(func->parameterName(i));
     }
   }
+  if (functionName.compare("Zero Lorentzians") == 0) {
+    parameters.append("Zero");
+  }
   return parameters;
 }
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp b/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
index 43e40be299f454234983cfb68a9975a91dca426f..cb842494b4026b234f68d30d9aa458c5a2335778 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
@@ -2,6 +2,7 @@
 
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/Logger.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QFileInfo>
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp b/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
index eaec3581f4ed5d4147d8c32bef4579205bcadf28..b1be2a407b582a5e11a7e0205eff227cbb1a5e1e 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtCustomInterfaces/Indirect/ISISDiagnostics.h"
 
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/Logger.h"
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp b/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp
index 6897dc29bac22bbe7e35feebc5e1204ff846b0ae..c426cb03763e8a2b4e3e61c6942ad1f9d0b42859 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ISISEnergyTransfer.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtCustomInterfaces/Indirect/ISISEnergyTransfer.h"
 
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/IDTypes.h"
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
index d4e8a6def74e16390210dbb8ee81ba4be4ef408b..d7b5c2b663a2d60626a8fd31bdc9e4d24fe8fb60 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectDiffractionReduction.cpp
@@ -1,10 +1,8 @@
-//----------------------
-// Includes
-//----------------------
 #include "MantidQtCustomInterfaces/Indirect/IndirectDiffractionReduction.h"
 
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/MultiFileNameParser.h"
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectMolDyn.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectMolDyn.cpp
index b0266ef1caa3d94b5d7e712d69888cd012d94071..95e26d66dff575ec7768357b47af74d566568a2f 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectMolDyn.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectMolDyn.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtCustomInterfaces/Indirect/IndirectMolDyn.h"
 
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QFileInfo>
 #include <QString>
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
index e5f9af1d7495ecd60d026e59c64f302529e38c69..592e7d27242f45cdfeb5e0361b97783ea0a317cc 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtCustomInterfaces/Indirect/IndirectMoments.h"
 
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QDoubleValidator>
 #include <QFileInfo>
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
index b33af6c3fd39db5a001dd29b02905114dd226c66..96a489bface68f9a6362220a0f26c41c7e4e8915 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
@@ -265,11 +265,11 @@ void IndirectTab::plotSpectrum(const QStringList &workspaceNames, int specStart,
 
   pyInput += "plotSpectrum(['";
   pyInput += workspaceNames.join("','");
-  pyInput += "'], range(";
+  pyInput += "'], list(range(";
   pyInput += QString::number(specStart);
   pyInput += ",";
   pyInput += QString::number(specEnd + 1);
-  pyInput += "), error_bars = True)\n";
+  pyInput += ")), error_bars = True)\n";
 
   m_pythonRunner.runPythonCode(pyInput);
 }
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IndirectTransmission.cpp b/MantidQt/CustomInterfaces/src/Indirect/IndirectTransmission.cpp
index 3b6e74e659c9aa29a9074276801ab058578e317b..a064cdea29a61fd021402098f47e4807db974e58 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IndirectTransmission.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IndirectTransmission.cpp
@@ -1,4 +1,5 @@
 #include "MantidQtCustomInterfaces/Indirect/IndirectTransmission.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <QFileInfo>
 
diff --git a/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp
index 260515d88e4e4929a352e456f0fa5b49af55860c..c01713eb3c0e03c8bc48585fb879e7da77155425 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/IqtFit.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/FunctionDomain1D.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <math.h>
 #include <QFileInfo>
diff --git a/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp b/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
index 4b505613e3ce29bb8b3d2276b4a0d366173dccdb..b33ebef1f854d059f330be5ff9e6c008aa44b714 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
@@ -1,5 +1,5 @@
 #include "MantidAPI/AnalysisDataService.h"
-#include "MantidAPI/WorkspaceGroup_fwd.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidQtCustomInterfaces/Indirect/MSDFit.h"
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
 #include "MantidQtMantidWidgets/RangeSelector.h"
diff --git a/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp b/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
index e2f6f22fc6f280632235d48e2cf25a53893ca44e..a579f7dc2ac4abe95620d155bb06a69a1b38e152 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
@@ -2,6 +2,7 @@
 
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/ITableWorkspace.h"
 
 using namespace Mantid::API;
diff --git a/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp b/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
index 0d2e50dc7c537d30dc0a49439064db23cdef2799..7d4cbb4fd97df20b962327ec918b668e9017762f 100644
--- a/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
+++ b/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
@@ -2,6 +2,7 @@
 #include "MantidQtCustomInterfaces/UserInputValidator.h"
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 using namespace Mantid::API;
 
diff --git a/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp b/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp
index b87f18f79ac1dc3cda9dc124615aada5eec80a38..4e5a212ad6703d634d3112e7f87af5e420a8ca5a 100644
--- a/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp
+++ b/MantidQt/CustomInterfaces/src/MantidEVWorker.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/Workspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidAPI/IPeaksWorkspace.h"
@@ -56,9 +57,19 @@ std::string MantidEVWorker::workspaceType(const std::string &ws_name) {
   if (!ADS.doesExist(ws_name))
     return std::string("");
 
-  Workspace_const_sptr outWS = ADS.retrieveWS<Workspace>(ws_name);
+  WorkspaceGroup_const_sptr wsgroup = ADS.retrieveWS<WorkspaceGroup>(ws_name);
+  if (wsgroup) {
 
-  return outWS->id();
+    std::vector<std::string> group = wsgroup->getNames();
+    Workspace_const_sptr outWS = ADS.retrieveWS<Workspace>(group[0]);
+
+    return outWS->id();
+  } else {
+
+    Workspace_const_sptr outWS = ADS.retrieveWS<Workspace>(ws_name);
+
+    return outWS->id();
+  }
 }
 
 /**
diff --git a/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp b/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
index 0fa179229e8a56109bb5ef3c09df26257b2efba5..695909ab1cd3180f9286d46ef58c6ba5acd8c110 100644
--- a/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
+++ b/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
@@ -9,6 +9,7 @@
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 
 #include "MantidQtAPI/AlgorithmRunner.h"
diff --git a/MantidQt/CustomInterfaces/src/Muon/IO_MuonGrouping.cpp b/MantidQt/CustomInterfaces/src/Muon/IO_MuonGrouping.cpp
index ca42e651d15287e87aabb1be4f8fb3755a26a6b6..28775d2233072d7d80fe29ad87fb12a495b39878 100644
--- a/MantidQt/CustomInterfaces/src/Muon/IO_MuonGrouping.cpp
+++ b/MantidQt/CustomInterfaces/src/Muon/IO_MuonGrouping.cpp
@@ -27,6 +27,8 @@
 #pragma warning(disable : 4250)
 #include <Poco/XML/XMLWriter.h>
 #pragma warning(pop)
+#else
+#include <Poco/XML/XMLWriter.h>
 #endif
 
 //-----------------------------------------------------------------------------
diff --git a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
index 9d372e589fba433c0711cec5b9e281023ea53d53..9caa12314d5bce32a82557ab0ec6b944afc19878 100644
--- a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
+++ b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
@@ -1,6 +1,3 @@
-//----------------------
-// Includes
-//----------------------
 #include "MantidQtCustomInterfaces/Muon/MuonAnalysis.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
@@ -20,8 +17,8 @@
 #include "MantidKernel/Exception.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidKernel/Logger.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/cow_ptr.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/HelpWindow.h"
 #include "MantidQtAPI/ManageUserDirectories.h"
 #include "MantidQtCustomInterfaces/Muon/MuonAnalysisFitDataPresenter.h"
@@ -565,7 +562,7 @@ void MuonAnalysis::runSaveGroupButton() {
   QString filter;
   filter.append("Files (*.xml *.XML)");
   filter += ";;AllFiles (*)";
-  QString groupingFile = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString groupingFile = QFileDialog::getSaveFileName(
       this, "Save Grouping file as", prevPath, filter);
 
   // Add extension if the groupingFile specified doesn't have one. (Solving
@@ -2208,8 +2205,20 @@ void MuonAnalysis::setAppendingRun(int inc) {
 void MuonAnalysis::changeRun(int amountToChange) {
   QString filePath("");
   QString currentFile = m_uiForm.mwRunFiles->getFirstFilename();
-  if ((currentFile.isEmpty()))
-    currentFile = m_previousFilenames[0];
+  if ((currentFile.isEmpty())) {
+    if (m_previousFilenames.isEmpty()) {
+      // not a valid file, and no previous valid files
+      QMessageBox::warning(this, tr("Muon Analysis"),
+                           tr("Unable to open the file.\n"
+                              "and no previous valid files available."),
+                           QMessageBox::Ok, QMessageBox::Ok);
+      allowLoading(true);
+      return;
+    } else {
+      // blank box - use previous run
+      currentFile = m_previousFilenames[0];
+    }
+  }
 
   QString run("");
   int runSize(-1);
diff --git a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisDataLoader.cpp b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisDataLoader.cpp
index 9234edfd11fdad2ce83469d1f12a58ac544f0329..c8c5914ab134ad0a34c3b89abffe09c8af761cca 100644
--- a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisDataLoader.cpp
+++ b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisDataLoader.cpp
@@ -36,7 +36,9 @@ namespace CustomInterfaces {
 MuonAnalysisDataLoader::MuonAnalysisDataLoader(
     const DeadTimesType &deadTimesType, const QStringList &instruments,
     const std::string &deadTimesFile)
-    : m_instruments(instruments) {
+    : m_instruments(instruments),
+      m_cacheBlacklist("\\w*auto_\\w.tmp", Qt::CaseInsensitive,
+                       QRegExp::RegExp2) {
   this->setDeadTimesType(deadTimesType, deadTimesFile);
 }
 
@@ -80,10 +82,12 @@ LoadResult MuonAnalysisDataLoader::loadFiles(const QStringList &files) const {
     return oss.str();
   };
 
+  // Clean cache from stale files etc
+  updateCache();
   // Check cache to see if we've loaded this set of files before
   const std::string fileString = toString(files);
-  updateCache();
   if (m_loadedDataCache.find(fileString) != m_loadedDataCache.end()) {
+    g_log.information("Using cached workspace for file(s): " + fileString);
     return m_loadedDataCache[fileString];
   }
 
@@ -176,8 +180,11 @@ LoadResult MuonAnalysisDataLoader::loadFiles(const QStringList &files) const {
     result.label = MuonAnalysisHelper::getRunLabel(loadedWorkspaces);
   }
 
-  // Cache the result so we don't have to load it next time
-  m_loadedDataCache[fileString] = result;
+  // Cache the result if we should so we don't have to load it next time
+  if (shouldBeCached(files)) {
+    g_log.information("Caching loaded workspace for file(s): " + fileString);
+    m_loadedDataCache[fileString] = result;
+  }
   return result;
 }
 
@@ -200,6 +207,23 @@ std::string MuonAnalysisDataLoader::getInstrumentName(
   return "";
 }
 
+/**
+ * Checks against an internal regex for files that match. If any files match
+ * then none will be cached.
+ * @param filenames A list of file paths
+ * @return True if they should be cached on loading, false otherwise.
+ */
+bool MuonAnalysisDataLoader::shouldBeCached(
+    const QStringList &filenames) const {
+  for (const auto &filename : filenames) {
+    if (m_cacheBlacklist.indexIn(filename) >= 0) {
+      // match indicates not caching
+      return false;
+    }
+  }
+  return true;
+}
+
 /**
  * Correct loaded data for dead times (if present) and group
  * @param loadedData :: [input] Load result
@@ -443,6 +467,7 @@ void MuonAnalysisDataLoader::updateCache() const {
   }
   // Remove the invalid cache entries
   for (const auto &key : invalidKeys) {
+    g_log.information("Erasing invalid cached entry for file(s): " + key);
     m_loadedDataCache.erase(key);
   }
 }
diff --git a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisFitDataPresenter.cpp b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisFitDataPresenter.cpp
index 61645abc7ca230922c9defb60d3c51b34713aa0b..c70b373b061110988492a3f632e75c69f0589e6c 100644
--- a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisFitDataPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisFitDataPresenter.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/Workspace_fwd.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidQtCustomInterfaces/Muon/MuonAnalysisFitDataPresenter.h"
 #include "MantidQtCustomInterfaces/Muon/MuonAnalysisHelper.h"
 #include "MantidQtCustomInterfaces/Muon/MuonSequentialFitDialog.h"
diff --git a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisResultTableTab.cpp b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisResultTableTab.cpp
index 5241077e855d9f3bae90946db5cad7a3efc7b616..c7fce7342bb754e574be5efc424fe05f57e5bbf6 100644
--- a/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisResultTableTab.cpp
+++ b/MantidQt/CustomInterfaces/src/Muon/MuonAnalysisResultTableTab.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/TimeSeriesProperty.h"
@@ -18,8 +19,8 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/algorithm/string/predicate.hpp>
 
+#include <QFileInfo>
 #include <QLineEdit>
-#include <QFileDialog>
 #include <QHash>
 #include <QMessageBox>
 
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/MeasurementItem.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/MeasurementItem.cpp
index b777af5555cadd7a019cf5523a4840df07fc9f80..a9b14fa49e0727a1ce34549ae628c6cc59864a2e 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/MeasurementItem.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/MeasurementItem.cpp
@@ -13,13 +13,15 @@ namespace CustomInterfaces {
  * @param type
  * @param angle
  * @param run
+ * @param title
  */
 MeasurementItem::MeasurementItem(
     const MeasurementItem::IDType &measurementItemId,
     const MeasurementItem::IDType &subId, const std::string &label,
-    const std::string &type, const double angle, const std::string &run)
+    const std::string &type, const double angle, const std::string &run,
+    const std::string &title)
     : m_measurementItemId(measurementItemId), m_subId(subId), m_label(label),
-      m_type(type), m_angle(angle), m_run(run) {
+      m_type(type), m_angle(angle), m_run(run), m_title(title) {
 
   std::string accumulatedProblems;
   if (m_measurementItemId.empty()) {
@@ -45,7 +47,8 @@ MeasurementItem::MeasurementItem(const std::string &why)
 MeasurementItem::MeasurementItem(const MeasurementItem &other)
     : m_measurementItemId(other.m_measurementItemId), m_subId(other.m_subId),
       m_label(other.m_label), m_type(other.m_type), m_angle(other.m_angle),
-      m_run(other.m_run), m_whyUnuseable(other.m_whyUnuseable) {}
+      m_run(other.m_run), m_title(other.m_title),
+      m_whyUnuseable(other.m_whyUnuseable) {}
 
 /// Destructor
 MeasurementItem::~MeasurementItem() {}
@@ -75,6 +78,8 @@ double MeasurementItem::angle() const { return m_angle; }
 
 std::string MeasurementItem::run() const { return m_run; }
 
+std::string MeasurementItem::title() const { return m_title; }
+
 std::string MeasurementItem::angleStr() const {
   std::stringstream buffer;
   buffer << angle();
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/QtReflRunsTabView.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflRunsTabView.cpp
index a6601af6f8fcb7eca3065af343a641af04abda14..587aa09904076699e41d41f298d7c0fc63a58457 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/QtReflRunsTabView.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflRunsTabView.cpp
@@ -50,32 +50,54 @@ void QtReflRunsTabView::initLayout() {
   // Create the DataProcessor presenter
   ReflGenericDataProcessorPresenterFactory presenterFactory;
 
-  QDataProcessorWidget *qDataProcessorWidget = new QDataProcessorWidget(
+  QDataProcessorWidget *qDataProcessorWidget_1 = new QDataProcessorWidget(
       std::unique_ptr<DataProcessorPresenter>(presenterFactory.create()), this);
-  ui.layoutProcessPane->addWidget(qDataProcessorWidget);
+  ui.toolbox->addItem(qDataProcessorWidget_1, "Group 1");
+
+  QDataProcessorWidget *qDataProcessorWidget_2 = new QDataProcessorWidget(
+      std::unique_ptr<DataProcessorPresenter>(presenterFactory.create()), this);
+  ui.toolbox->addItem(qDataProcessorWidget_2, "Group 2");
+
+  std::vector<DataProcessorPresenter *> processingWidgets;
+  processingWidgets.push_back(qDataProcessorWidget_1->getPresenter());
+  processingWidgets.push_back(qDataProcessorWidget_2->getPresenter());
 
   // Create the presenter
   m_presenter = std::make_shared<ReflRunsTabPresenter>(
       this /* main view */,
       this /* Currently this concrete view is also responsible for prog reporting */,
-      qDataProcessorWidget->getPresenter() /* The data processor presenter */);
+      processingWidgets /* The data processor presenters */);
   m_algoRunner = boost::make_shared<MantidQt::API::AlgorithmRunner>(this);
 
   // Custom context menu for table
   connect(ui.tableSearchResults,
           SIGNAL(customContextMenuRequested(const QPoint &)), this,
           SLOT(showSearchContextMenu(const QPoint &)));
-  // Synchronize the two instrument selection widgets
+  // Synchronize the slit calculator
+  connect(ui.comboSearchInstrument, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(instrumentChanged(int)));
+  // Selected group changed
+  connect(ui.toolbox, SIGNAL(currentChanged(int)), this, SLOT(groupChanged()));
+
+  // Synchronize the instrument selection widgets
+  // Processing table in group 1
   connect(ui.comboSearchInstrument, SIGNAL(currentIndexChanged(int)),
-          qDataProcessorWidget,
+          qDataProcessorWidget_1,
           SLOT(on_comboProcessInstrument_currentIndexChanged(int)));
-  connect(qDataProcessorWidget,
+  connect(qDataProcessorWidget_1,
           SIGNAL(comboProcessInstrument_currentIndexChanged(int)),
           ui.comboSearchInstrument, SLOT(setCurrentIndex(int)));
-  // Synchronize the slit calculator
-  connect(ui.comboSearchInstrument, SIGNAL(currentIndexChanged(int)), this,
+  connect(qDataProcessorWidget_1,
+          SIGNAL(comboProcessInstrument_currentIndexChanged(int)), this,
           SLOT(instrumentChanged(int)));
-  connect(qDataProcessorWidget,
+  // Processing table in group 2
+  connect(ui.comboSearchInstrument, SIGNAL(currentIndexChanged(int)),
+          qDataProcessorWidget_2,
+          SLOT(on_comboProcessInstrument_currentIndexChanged(int)));
+  connect(qDataProcessorWidget_2,
+          SIGNAL(comboProcessInstrument_currentIndexChanged(int)),
+          ui.comboSearchInstrument, SLOT(setCurrentIndex(int)));
+  connect(qDataProcessorWidget_2,
           SIGNAL(comboProcessInstrument_currentIndexChanged(int)), this,
           SLOT(instrumentChanged(int)));
 }
@@ -302,5 +324,19 @@ std::string QtReflRunsTabView::getTransferMethod() const {
   return ui.comboTransferMethod->currentText().toStdString();
 }
 
+/**
+* @return the selected group
+*/
+int QtReflRunsTabView::getSelectedGroup() const {
+  return ui.toolbox->currentIndex();
+}
+
+/** This is slot is triggered when the selected group changes.
+*
+*/
+void QtReflRunsTabView::groupChanged() {
+  m_presenter->notify(IReflRunsTabPresenter::GroupChangedFlag);
+}
+
 } // namespace CustomInterfaces
 } // namespace Mantid
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsTabView.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsTabView.cpp
index feb486bedeb29716e07f5e77be1a32b6758ad0f2..0dd9bf213f455ba0dfc0b4c508003888f531a37d 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsTabView.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsTabView.cpp
@@ -1,12 +1,10 @@
 #include "MantidQtCustomInterfaces/Reflectometry/QtReflSettingsTabView.h"
+#include "MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h"
 #include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h"
-#include "MantidQtMantidWidgets/HintingLineEdit.h"
 
 namespace MantidQt {
 namespace CustomInterfaces {
 
-using namespace MantidQt::MantidWidgets;
-
 //----------------------------------------------------------------------------------------------
 /** Constructor
 * @param parent :: [input] The parent of this widget
@@ -15,8 +13,6 @@ QtReflSettingsTabView::QtReflSettingsTabView(QWidget *parent) {
 
   UNUSED_ARG(parent);
   initLayout();
-
-  m_presenter.reset(new ReflSettingsTabPresenter(this));
 }
 
 //----------------------------------------------------------------------------------------------
@@ -25,15 +21,22 @@ QtReflSettingsTabView::QtReflSettingsTabView(QWidget *parent) {
 QtReflSettingsTabView::~QtReflSettingsTabView() {}
 
 /**
-Initialise the Interface
+Initialise the interface
 */
 void QtReflSettingsTabView::initLayout() {
   m_ui.setupUi(this);
 
-  connect(m_ui.getExpDefaultsButton, SIGNAL(clicked()), this,
-          SLOT(requestExpDefaults()));
-  connect(m_ui.getInstDefaultsButton, SIGNAL(clicked()), this,
-          SLOT(requestInstDefaults()));
+  QtReflSettingsView *settings_1 = new QtReflSettingsView(this);
+  m_ui.toolbox->addItem(settings_1, "Group 1");
+
+  QtReflSettingsView *settings_2 = new QtReflSettingsView(this);
+  m_ui.toolbox->addItem(settings_2, "Group 2");
+
+  std::vector<IReflSettingsPresenter *> presenters;
+  presenters.push_back(settings_1->getPresenter());
+  presenters.push_back(settings_2->getPresenter());
+
+  m_presenter.reset(new ReflSettingsTabPresenter(presenters));
 }
 
 /** Returns the presenter managing this view
@@ -44,254 +47,5 @@ IReflSettingsTabPresenter *QtReflSettingsTabView::getPresenter() const {
   return m_presenter.get();
 }
 
-/** This slot notifies the presenter to fill experiment settings with default
-* values.
-*/
-void QtReflSettingsTabView::requestExpDefaults() const {
-  m_presenter->notify(IReflSettingsTabPresenter::ExpDefaultsFlag);
-}
-
-/** This slot notifies the presenter to fill instrument settings with default
-* values.
-*/
-void QtReflSettingsTabView::requestInstDefaults() const {
-  m_presenter->notify(IReflSettingsTabPresenter::InstDefaultsFlag);
-}
-
-/* Sets default values for all experiment settings given a list of default
-* values.
-*/
-void QtReflSettingsTabView::setExpDefaults(
-    const std::vector<std::string> &defaults) const {
-
-  int amIndex =
-      m_ui.analysisModeComboBox->findText(QString::fromStdString(defaults[0]));
-  if (amIndex != -1)
-    m_ui.analysisModeComboBox->setCurrentIndex(amIndex);
-
-  int pcIndex =
-      m_ui.polCorrComboBox->findText(QString::fromStdString(defaults[1]));
-  if (pcIndex != -1)
-    m_ui.polCorrComboBox->setCurrentIndex(pcIndex);
-
-  m_ui.CRhoEdit->setText(QString::fromStdString(defaults[2]));
-  m_ui.CAlphaEdit->setText(QString::fromStdString(defaults[3]));
-  m_ui.CApEdit->setText(QString::fromStdString(defaults[4]));
-  m_ui.CPpEdit->setText(QString::fromStdString(defaults[5]));
-  m_ui.scaleFactorEdit->setText(QString::fromStdString(defaults[6]));
-}
-
-/* Sets default values for all instrument settings given a list of default
-* values.
-*/
-void QtReflSettingsTabView::setInstDefaults(
-    const std::vector<double> &defaults) const {
-
-  auto intMonCheckState = (defaults[0] != 0) ? Qt::Checked : Qt::Unchecked;
-  m_ui.intMonCheckBox->setCheckState(intMonCheckState);
-
-  m_ui.monIntMinEdit->setText(QString::number(defaults[1]));
-  m_ui.monIntMaxEdit->setText(QString::number(defaults[2]));
-  m_ui.monBgMinEdit->setText(QString::number(defaults[3]));
-  m_ui.monBgMaxEdit->setText(QString::number(defaults[4]));
-  m_ui.lamMinEdit->setText(QString::number(defaults[5]));
-  m_ui.lamMaxEdit->setText(QString::number(defaults[6]));
-  m_ui.I0MonIndexEdit->setText(QString::number(defaults[7]));
-}
-
-/* Sets the enabled status of polarisation corrections and parameters
-* @param enable :: [input] bool to enable options or not
-*/
-void QtReflSettingsTabView::setPolarisationOptionsEnabled(bool enable) const {
-  m_ui.polCorrComboBox->setEnabled(enable);
-  m_ui.CRhoEdit->setEnabled(enable);
-  m_ui.CAlphaEdit->setEnabled(enable);
-  m_ui.CApEdit->setEnabled(enable);
-  m_ui.CPpEdit->setEnabled(enable);
-
-  if (!enable) {
-    // Set polarisation corrections text to 'None' when disabled
-    int noneIndex = m_ui.polCorrComboBox->findText("None");
-    if (noneIndex != -1)
-      m_ui.polCorrComboBox->setCurrentIndex(noneIndex);
-    // Clear all parameters as well
-    m_ui.CRhoEdit->clear();
-    m_ui.CAlphaEdit->clear();
-    m_ui.CApEdit->clear();
-    m_ui.CPpEdit->clear();
-  }
-}
-
-/** Returns global options for 'Stitch1DMany'
-* @return :: Global options for 'Stitch1DMany'
-*/
-std::string QtReflSettingsTabView::getStitchOptions() const {
-
-  auto widget = m_ui.expSettingsLayout0->itemAtPosition(7, 1)->widget();
-  return static_cast<HintingLineEdit *>(widget)->text().toStdString();
-}
-
-/** Creates hints for 'Stitch1DMany'
-* @param hints :: Hints as a map
-*/
-void QtReflSettingsTabView::createStitchHints(
-    const std::map<std::string, std::string> &hints) {
-
-  m_ui.expSettingsLayout0->addWidget(new HintingLineEdit(this, hints), 7, 1, 1,
-                                     3);
-}
-
-/** Return selected analysis mode
-* @return :: selected analysis mode
-*/
-std::string QtReflSettingsTabView::getAnalysisMode() const {
-
-  return m_ui.analysisModeComboBox->currentText().toStdString();
-}
-
-/** Return direct beam
-* @return :: direct beam range
-*/
-std::string QtReflSettingsTabView::getDirectBeam() const {
-
-  return m_ui.directBeamEdit->text().toStdString();
-}
-
-/** Return selected transmission run(s)
-* @return :: selected transmission run(s)
-*/
-std::string QtReflSettingsTabView::getTransmissionRuns() const {
-
-  return m_ui.transmissionRunsEdit->text().toStdString();
-}
-
-/** Return selected polarisation corrections
-* @return :: selected polarisation corrections
-*/
-std::string QtReflSettingsTabView::getPolarisationCorrections() const {
-
-  return m_ui.polCorrComboBox->currentText().toStdString();
-}
-
-/** Return CRho
-* @return :: polarization correction CRho
-*/
-std::string QtReflSettingsTabView::getCRho() const {
-
-  return m_ui.CRhoEdit->text().toStdString();
-}
-
-/** Return CAlpha
-* @return :: polarization correction CAlpha
-*/
-std::string QtReflSettingsTabView::getCAlpha() const {
-
-  return m_ui.CAlphaEdit->text().toStdString();
-}
-
-/** Return CAp
-* @return :: polarization correction CAp
-*/
-std::string QtReflSettingsTabView::getCAp() const {
-
-  return m_ui.CApEdit->text().toStdString();
-}
-
-/** Return CPp
-* @return :: polarization correction CPp
-*/
-std::string QtReflSettingsTabView::getCPp() const {
-
-  return m_ui.CPpEdit->text().toStdString();
-}
-
-/** Return momentum transfer limits
-* @return :: momentum transfer limits
-*/
-std::string QtReflSettingsTabView::getMomentumTransferStep() const {
-
-  return m_ui.momentumTransferStepEdit->text().toStdString();
-}
-
-/** Return scale factor
-* @return :: scale factor
-*/
-std::string QtReflSettingsTabView::getScaleFactor() const {
-
-  return m_ui.scaleFactorEdit->text().toStdString();
-}
-
-/** Return integrated monitors option
-* @return :: integrated monitors check
-*/
-std::string QtReflSettingsTabView::getIntMonCheck() const {
-
-  return m_ui.intMonCheckBox->isChecked() ? "1" : "0";
-}
-
-/** Return monitor integral wavelength min
-* @return :: monitor integral min
-*/
-std::string QtReflSettingsTabView::getMonitorIntegralMin() const {
-
-  return m_ui.monIntMinEdit->text().toStdString();
-}
-
-/** Return monitor integral wavelength max
-* @return :: monitor integral max
-*/
-std::string QtReflSettingsTabView::getMonitorIntegralMax() const {
-
-  return m_ui.monIntMaxEdit->text().toStdString();
-}
-
-/** Return monitor background wavelength min
-* @return :: monitor background min
-*/
-std::string QtReflSettingsTabView::getMonitorBackgroundMin() const {
-
-  return m_ui.monBgMinEdit->text().toStdString();
-}
-
-/** Return monitor background wavelength max
-* @return :: monitor background max
-*/
-std::string QtReflSettingsTabView::getMonitorBackgroundMax() const {
-
-  return m_ui.monBgMaxEdit->text().toStdString();
-}
-
-/** Return wavelength min
-* @return :: lambda min
-*/
-std::string QtReflSettingsTabView::getLambdaMin() const {
-
-  return m_ui.lamMinEdit->text().toStdString();
-}
-
-/** Return wavelength max
-* @return :: lambda max
-*/
-std::string QtReflSettingsTabView::getLambdaMax() const {
-
-  return m_ui.lamMaxEdit->text().toStdString();
-}
-
-/** Return I0MonitorIndex
-* @return :: I0MonitorIndex
-*/
-std::string QtReflSettingsTabView::getI0MonitorIndex() const {
-
-  return m_ui.I0MonIndexEdit->text().toStdString();
-}
-
-/** Return processing instructions
-* @return :: processing instructions
-*/
-std::string QtReflSettingsTabView::getProcessingInstructions() const {
-
-  return m_ui.procInstEdit->text().toStdString();
-}
-
 } // namespace CustomInterfaces
 } // namespace Mantid
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsView.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsView.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f6511d4e0660ae7f4c336e66477c31f8a63ab6e5
--- /dev/null
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/QtReflSettingsView.cpp
@@ -0,0 +1,297 @@
+#include "MantidQtCustomInterfaces/Reflectometry/QtReflSettingsView.h"
+#include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h"
+#include "MantidQtMantidWidgets/HintingLineEdit.h"
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+using namespace MantidQt::MantidWidgets;
+
+//----------------------------------------------------------------------------------------------
+/** Constructor
+* @param parent :: [input] The parent of this widget
+*/
+QtReflSettingsView::QtReflSettingsView(QWidget *parent) {
+
+  UNUSED_ARG(parent);
+  initLayout();
+
+  m_presenter.reset(new ReflSettingsPresenter(this));
+}
+
+//----------------------------------------------------------------------------------------------
+/** Destructor
+*/
+QtReflSettingsView::~QtReflSettingsView() {}
+
+/**
+Initialise the Interface
+*/
+void QtReflSettingsView::initLayout() {
+  m_ui.setupUi(this);
+
+  connect(m_ui.getExpDefaultsButton, SIGNAL(clicked()), this,
+          SLOT(requestExpDefaults()));
+  connect(m_ui.getInstDefaultsButton, SIGNAL(clicked()), this,
+          SLOT(requestInstDefaults()));
+}
+
+/** Returns the presenter managing this view
+* @return :: A pointer to the presenter
+*/
+IReflSettingsPresenter *QtReflSettingsView::getPresenter() const {
+
+  return m_presenter.get();
+}
+
+/** This slot notifies the presenter to fill experiment settings with default
+* values.
+*/
+void QtReflSettingsView::requestExpDefaults() const {
+  m_presenter->notify(IReflSettingsPresenter::ExpDefaultsFlag);
+}
+
+/** This slot notifies the presenter to fill instrument settings with default
+* values.
+*/
+void QtReflSettingsView::requestInstDefaults() const {
+  m_presenter->notify(IReflSettingsPresenter::InstDefaultsFlag);
+}
+
+/* Sets default values for all experiment settings given a list of default
+* values.
+*/
+void QtReflSettingsView::setExpDefaults(
+    const std::vector<std::string> &defaults) const {
+
+  int amIndex =
+      m_ui.analysisModeComboBox->findText(QString::fromStdString(defaults[0]));
+  if (amIndex != -1)
+    m_ui.analysisModeComboBox->setCurrentIndex(amIndex);
+
+  int pcIndex =
+      m_ui.polCorrComboBox->findText(QString::fromStdString(defaults[1]));
+  if (pcIndex != -1)
+    m_ui.polCorrComboBox->setCurrentIndex(pcIndex);
+
+  m_ui.CRhoEdit->setText(QString::fromStdString(defaults[2]));
+  m_ui.CAlphaEdit->setText(QString::fromStdString(defaults[3]));
+  m_ui.CApEdit->setText(QString::fromStdString(defaults[4]));
+  m_ui.CPpEdit->setText(QString::fromStdString(defaults[5]));
+  m_ui.scaleFactorEdit->setText(QString::fromStdString(defaults[6]));
+}
+
+/* Sets default values for all instrument settings given a list of default
+* values.
+*/
+void QtReflSettingsView::setInstDefaults(
+    const std::vector<double> &defaults) const {
+
+  auto intMonCheckState = (defaults[0] != 0) ? Qt::Checked : Qt::Unchecked;
+  m_ui.intMonCheckBox->setCheckState(intMonCheckState);
+
+  m_ui.monIntMinEdit->setText(QString::number(defaults[1]));
+  m_ui.monIntMaxEdit->setText(QString::number(defaults[2]));
+  m_ui.monBgMinEdit->setText(QString::number(defaults[3]));
+  m_ui.monBgMaxEdit->setText(QString::number(defaults[4]));
+  m_ui.lamMinEdit->setText(QString::number(defaults[5]));
+  m_ui.lamMaxEdit->setText(QString::number(defaults[6]));
+  m_ui.I0MonIndexEdit->setText(QString::number(defaults[7]));
+}
+
+/* Sets the enabled status of polarisation corrections and parameters
+* @param enable :: [input] bool to enable options or not
+*/
+void QtReflSettingsView::setPolarisationOptionsEnabled(bool enable) const {
+  m_ui.polCorrComboBox->setEnabled(enable);
+  m_ui.CRhoEdit->setEnabled(enable);
+  m_ui.CAlphaEdit->setEnabled(enable);
+  m_ui.CApEdit->setEnabled(enable);
+  m_ui.CPpEdit->setEnabled(enable);
+
+  if (!enable) {
+    // Set polarisation corrections text to 'None' when disabled
+    int noneIndex = m_ui.polCorrComboBox->findText("None");
+    if (noneIndex != -1)
+      m_ui.polCorrComboBox->setCurrentIndex(noneIndex);
+    // Clear all parameters as well
+    m_ui.CRhoEdit->clear();
+    m_ui.CAlphaEdit->clear();
+    m_ui.CApEdit->clear();
+    m_ui.CPpEdit->clear();
+  }
+}
+
+/** Returns global options for 'Stitch1DMany'
+* @return :: Global options for 'Stitch1DMany'
+*/
+std::string QtReflSettingsView::getStitchOptions() const {
+
+  auto widget = m_ui.expSettingsLayout0->itemAtPosition(7, 1)->widget();
+  return static_cast<HintingLineEdit *>(widget)->text().toStdString();
+}
+
+/** Creates hints for 'Stitch1DMany'
+* @param hints :: Hints as a map
+*/
+void QtReflSettingsView::createStitchHints(
+    const std::map<std::string, std::string> &hints) {
+
+  m_ui.expSettingsLayout0->addWidget(new HintingLineEdit(this, hints), 7, 1, 1,
+                                     3);
+}
+
+/** Return selected analysis mode
+* @return :: selected analysis mode
+*/
+std::string QtReflSettingsView::getAnalysisMode() const {
+
+  return m_ui.analysisModeComboBox->currentText().toStdString();
+}
+
+/** Return direct beam
+* @return :: direct beam range
+*/
+std::string QtReflSettingsView::getDirectBeam() const {
+
+  return m_ui.directBeamEdit->text().toStdString();
+}
+
+/** Return selected transmission run(s)
+* @return :: selected transmission run(s)
+*/
+std::string QtReflSettingsView::getTransmissionRuns() const {
+
+  return m_ui.transmissionRunsEdit->text().toStdString();
+}
+
+/** Return selected polarisation corrections
+* @return :: selected polarisation corrections
+*/
+std::string QtReflSettingsView::getPolarisationCorrections() const {
+
+  return m_ui.polCorrComboBox->currentText().toStdString();
+}
+
+/** Return CRho
+* @return :: polarization correction CRho
+*/
+std::string QtReflSettingsView::getCRho() const {
+
+  return m_ui.CRhoEdit->text().toStdString();
+}
+
+/** Return CAlpha
+* @return :: polarization correction CAlpha
+*/
+std::string QtReflSettingsView::getCAlpha() const {
+
+  return m_ui.CAlphaEdit->text().toStdString();
+}
+
+/** Return CAp
+* @return :: polarization correction CAp
+*/
+std::string QtReflSettingsView::getCAp() const {
+
+  return m_ui.CApEdit->text().toStdString();
+}
+
+/** Return CPp
+* @return :: polarization correction CPp
+*/
+std::string QtReflSettingsView::getCPp() const {
+
+  return m_ui.CPpEdit->text().toStdString();
+}
+
+/** Return momentum transfer limits
+* @return :: momentum transfer limits
+*/
+std::string QtReflSettingsView::getMomentumTransferStep() const {
+
+  return m_ui.momentumTransferStepEdit->text().toStdString();
+}
+
+/** Return scale factor
+* @return :: scale factor
+*/
+std::string QtReflSettingsView::getScaleFactor() const {
+
+  return m_ui.scaleFactorEdit->text().toStdString();
+}
+
+/** Return integrated monitors option
+* @return :: integrated monitors check
+*/
+std::string QtReflSettingsView::getIntMonCheck() const {
+
+  return m_ui.intMonCheckBox->isChecked() ? "1" : "0";
+}
+
+/** Return monitor integral wavelength min
+* @return :: monitor integral min
+*/
+std::string QtReflSettingsView::getMonitorIntegralMin() const {
+
+  return m_ui.monIntMinEdit->text().toStdString();
+}
+
+/** Return monitor integral wavelength max
+* @return :: monitor integral max
+*/
+std::string QtReflSettingsView::getMonitorIntegralMax() const {
+
+  return m_ui.monIntMaxEdit->text().toStdString();
+}
+
+/** Return monitor background wavelength min
+* @return :: monitor background min
+*/
+std::string QtReflSettingsView::getMonitorBackgroundMin() const {
+
+  return m_ui.monBgMinEdit->text().toStdString();
+}
+
+/** Return monitor background wavelength max
+* @return :: monitor background max
+*/
+std::string QtReflSettingsView::getMonitorBackgroundMax() const {
+
+  return m_ui.monBgMaxEdit->text().toStdString();
+}
+
+/** Return wavelength min
+* @return :: lambda min
+*/
+std::string QtReflSettingsView::getLambdaMin() const {
+
+  return m_ui.lamMinEdit->text().toStdString();
+}
+
+/** Return wavelength max
+* @return :: lambda max
+*/
+std::string QtReflSettingsView::getLambdaMax() const {
+
+  return m_ui.lamMaxEdit->text().toStdString();
+}
+
+/** Return I0MonitorIndex
+* @return :: I0MonitorIndex
+*/
+std::string QtReflSettingsView::getI0MonitorIndex() const {
+
+  return m_ui.I0MonIndexEdit->text().toStdString();
+}
+
+/** Return processing instructions
+* @return :: processing instructions
+*/
+std::string QtReflSettingsView::getProcessingInstructions() const {
+
+  return m_ui.procInstEdit->text().toStdString();
+}
+
+} // namespace CustomInterfaces
+} // namespace Mantid
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflLegacyTransferStrategy.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflLegacyTransferStrategy.cpp
index 015ff49e579f544f9ee1cf900f9ea6e9a195eb60..e6f10cce1e332e3a79735c7857cb1754c5dd68e5 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflLegacyTransferStrategy.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflLegacyTransferStrategy.cpp
@@ -20,8 +20,6 @@ TransferResults ReflLegacyTransferStrategy::transferRuns(
 
   // maps descriptions to runs. Multiple runs are joined with '+'
   std::map<std::string, std::string> runsByDesc;
-  // Counter used to feed fresh group ids
-  int nextGroupId = 0;
   // maps a description to a group. If descriptions only differ by theta,
   // they'll share a group
   std::map<std::string, std::string> groupsByDesc;
@@ -61,7 +59,7 @@ TransferResults ReflLegacyTransferStrategy::transferRuns(
     // If there isn't a group for this description (ignoring differences in
     // theta) yet, make one
     if (groupsByDesc[cleanDesc].empty())
-      groupsByDesc[cleanDesc] = boost::lexical_cast<std::string>(nextGroupId++);
+      groupsByDesc[cleanDesc] = desc.substr(0, desc.find("th") - 1);
 
     // Assign this description to the group it belongs to
     groupsByDesc[desc] = groupsByDesc[cleanDesc];
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflMainWindowPresenter.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflMainWindowPresenter.cpp
index 89f4a97d3e8fcd8970ac5c51ce42ac65d0b8b036..b7568006bfce6a287534efd7b216205eaf365b09 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflMainWindowPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflMainWindowPresenter.cpp
@@ -22,8 +22,8 @@ ReflMainWindowPresenter::ReflMainWindowPresenter(
 
   // Tell the tab presenters that this is going to be the main presenter
   m_runsPresenter->acceptMainPresenter(this);
-  m_settingsPresenter->acceptMainPresenter(this);
   m_savePresenter->acceptMainPresenter(this);
+  // Settings tab does not need a main presenter
 
   // Trigger the setting of the current instrument name in settings tab
   m_runsPresenter->notify(IReflRunsTabPresenter::InstrumentChangedFlag);
@@ -34,35 +34,44 @@ ReflMainWindowPresenter::ReflMainWindowPresenter(
 ReflMainWindowPresenter::~ReflMainWindowPresenter() {}
 
 /** Returns global options for 'CreateTransmissionWorkspaceAuto'
+*
+* @param group :: Index of the group in 'Settings' tab from which to get the
+*options
 * @return :: Global options for 'CreateTransmissionWorkspaceAuto'
 */
-std::string ReflMainWindowPresenter::getTransmissionOptions() const {
+std::string ReflMainWindowPresenter::getTransmissionOptions(int group) const {
 
   checkPtrValid(m_settingsPresenter);
 
-  return m_settingsPresenter->getTransmissionOptions();
+  return m_settingsPresenter->getTransmissionOptions(group);
 }
 
 /** Returns global processing options
+*
+* @param group :: Index of the group in 'Settings' tab from which to get the
+*options
 * @return :: Global processing options
 */
-std::string ReflMainWindowPresenter::getReductionOptions() const {
+std::string ReflMainWindowPresenter::getReductionOptions(int group) const {
 
   checkPtrValid(m_settingsPresenter);
 
   // Request global processing options to 'Settings' presenter
-  return m_settingsPresenter->getReductionOptions();
+  return m_settingsPresenter->getReductionOptions(group);
 }
 
 /** Returns global post-processing options
+*
+* @param group :: Index of the group in 'Settings' tab from which to get the
+*options
 * @return :: Global post-processing options
 */
-std::string ReflMainWindowPresenter::getStitchOptions() const {
+std::string ReflMainWindowPresenter::getStitchOptions(int group) const {
 
   checkPtrValid(m_settingsPresenter);
 
   // Request global post-processing options to 'Settings' presenter
-  return m_settingsPresenter->getStitchOptions();
+  return m_settingsPresenter->getStitchOptions(group);
 }
 
 /**
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflMeasureTransferStrategy.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflMeasureTransferStrategy.cpp
index 4d6966ccbc6db49aa89e5caea3a1fe7477ca92cd..c0eea69281402814de1aa7d57a570d33b97b327e 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflMeasureTransferStrategy.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflMeasureTransferStrategy.cpp
@@ -95,10 +95,19 @@ MantidQt::CustomInterfaces::ReflMeasureTransferStrategy::transferRuns(
   for (auto group = mapOfMeasurements.begin(); group != mapOfMeasurements.end();
        ++group) {
 
+    std::string groupName;
+
     // Map keyed by subId to index of exisiting subid written.
     std::map<std::string, size_t> subIdMap;
     for (size_t i = 0; i < group->second.size(); ++i) {
       const MeasurementItem &measurementItem = group->second[i];
+
+      if (i == 0) {
+        std::string title = measurementItem.title();
+        groupName = std::to_string(nextGroupId) + " - " +
+                    title.substr(0, title.find(":th"));
+      }
+
       if (subIdMap.find(measurementItem.subId()) != subIdMap.end()) {
         // We already have that subid.
         const size_t rowIndex = subIdMap[measurementItem.subId()];
@@ -112,9 +121,7 @@ MantidQt::CustomInterfaces::ReflMeasureTransferStrategy::transferRuns(
         std::map<std::string, std::string> row;
         row[ReflTableSchema::RUNS] = measurementItem.run();
         row[ReflTableSchema::ANGLE] = measurementItem.angleStr();
-        std::stringstream buffer;
-        buffer << nextGroupId;
-        row[ReflTableSchema::GROUP] = buffer.str();
+        row[ReflTableSchema::GROUP] = groupName;
         // run was successful so add it to 'runs'
         results.addTransferRow(row);
         // get successful transfers to get size for subIdMap
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflNexusMeasurementItemSource.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflNexusMeasurementItemSource.cpp
index 25787d49a8eccdd780ef7c2924dcc1a94d282010..e185395fa11461b875e2f4cf88999a3e9c869ce7 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflNexusMeasurementItemSource.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflNexusMeasurementItemSource.cpp
@@ -77,6 +77,12 @@ ReflNexusMeasurementItemSource::obtain(const std::string &definedPath,
         runNumber = match[0];
       }
     }
+    std::string runTitle;
+    try {
+      runTitle = run.getPropertyValueAsType<std::string>("run_title");
+    } catch (Exception::NotFoundError &) {
+      // OK, runTitle will be empty
+    }
 
     double theta = -1.0;
     try {
@@ -90,7 +96,7 @@ ReflNexusMeasurementItemSource::obtain(const std::string &definedPath,
 
     return MeasurementItem(measurementItemId, measurementItemSubId,
                            measurementItemLabel, measurementItemType, theta,
-                           runNumber);
+                           runNumber, runTitle);
 
   } catch (std::invalid_argument &ex) {
     std::stringstream buffer;
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflRunsTabPresenter.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflRunsTabPresenter.cpp
index 1c0addb7f876cff44388053c50847e192a662fd8..9a2b9136106c95d3dc19b7050b8cac1df5adf2b5 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflRunsTabPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflRunsTabPresenter.cpp
@@ -34,21 +34,22 @@ namespace CustomInterfaces {
 /** Constructor
 * @param mainView :: [input] The view we're managing
 * @param progressableView :: [input] The view reporting progress
-* @param tablePresenter :: [input] The data processor presenter
+* @param tablePresenters :: [input] The data processor presenters
 * @param searcher :: [input] The search implementation
 */
 ReflRunsTabPresenter::ReflRunsTabPresenter(
     IReflRunsTabView *mainView, ProgressableView *progressableView,
-    DataProcessorPresenter *tablePresenter,
+    std::vector<DataProcessorPresenter *> tablePresenters,
     boost::shared_ptr<IReflSearcher> searcher)
     : m_view(mainView), m_progressView(progressableView),
-      m_tablePresenter(tablePresenter), m_mainPresenter(),
+      m_tablePresenters(tablePresenters), m_mainPresenter(),
       m_searcher(searcher) {
 
   // Register this presenter as the workspace receiver
-  // When doing so, the inner presenter will notify this
+  // When doing so, the inner presenters will notify this
   // presenter with the list of commands
-  m_tablePresenter->accept(this);
+  for (const auto &presenter : m_tablePresenters)
+    presenter->accept(this);
 
   // If we don't have a searcher yet, use ReflCatalogSearcher
   if (!m_searcher)
@@ -60,6 +61,9 @@ ReflRunsTabPresenter::ReflRunsTabPresenter(
   methods.insert(MeasureTransferMethod);
   m_view->setTransferMethods(methods);
 
+  // Set current transfer method
+  m_currentTransferMethod = m_view->getTransferMethod();
+
   // Set up the instrument selectors
   std::vector<std::string> instruments;
   instruments.emplace_back("INTER");
@@ -75,10 +79,12 @@ ReflRunsTabPresenter::ReflRunsTabPresenter(
   if (std::find(instruments.begin(), instruments.end(), defaultInst) !=
       instruments.end()) {
     m_view->setInstrumentList(instruments, defaultInst);
-    m_tablePresenter->setInstrumentList(instruments, defaultInst);
+    for (const auto &presenter : m_tablePresenters)
+      presenter->setInstrumentList(instruments, defaultInst);
   } else {
     m_view->setInstrumentList(instruments, "INTER");
-    m_tablePresenter->setInstrumentList(instruments, "INTER");
+    for (const auto &presenter : m_tablePresenters)
+      presenter->setInstrumentList(instruments, "INTER");
   }
 }
 
@@ -113,6 +119,9 @@ void ReflRunsTabPresenter::notify(IReflRunsTabPresenter::Flag flag) {
   case IReflRunsTabPresenter::InstrumentChangedFlag:
     m_mainPresenter->setInstrumentName(m_view->getSearchInstrument());
     break;
+  case IReflRunsTabPresenter::GroupChangedFlag:
+    pushCommands();
+    break;
   }
   // Not having a 'default' case is deliberate. gcc issues a warning if there's
   // a flag we aren't handling.
@@ -125,7 +134,8 @@ void ReflRunsTabPresenter::pushCommands() {
 
   // The expected number of commands
   const size_t nCommands = 27;
-  auto commands = m_tablePresenter->publishCommands();
+  auto commands =
+      m_tablePresenters.at(m_view->getSelectedGroup())->publishCommands();
   if (commands.size() != nCommands) {
     throw std::runtime_error("Invalid list of commands");
   }
@@ -197,6 +207,7 @@ void ReflRunsTabPresenter::search() {
 void ReflRunsTabPresenter::populateSearch(IAlgorithm_sptr searchAlg) {
   if (searchAlg->isExecuted()) {
     ITableWorkspace_sptr results = searchAlg->getProperty("OutputWorkspace");
+    m_currentTransferMethod = m_view->getTransferMethod();
     m_searchModel = ReflSearchModel_sptr(new ReflSearchModel(
         *getTransferStrategy(), results, m_view->getSearchInstrument()));
     m_view->showSearch(m_searchModel);
@@ -211,8 +222,20 @@ void ReflRunsTabPresenter::transfer() {
   SearchResultMap runs;
   auto selectedRows = m_view->getSelectedSearchRows();
 
-  // Do not begin transfer if nothing is selected
+  // Do not begin transfer if nothing is selected or if the transfer method does
+  // not match the one used for populating search
   if (selectedRows.size() == 0) {
+    m_mainPresenter->giveUserCritical(
+        "Error: Please select at least one run to transfer.",
+        "No runs selected");
+    return;
+  } else if (m_currentTransferMethod != m_view->getTransferMethod()) {
+    m_mainPresenter->giveUserCritical(
+        "Error: Method selected for transferring runs (" +
+            m_view->getTransferMethod() +
+            ") must match the method used for searching runs (" +
+            m_currentTransferMethod + ").",
+        "Transfer method mismatch");
     return;
   }
 
@@ -274,7 +297,8 @@ void ReflRunsTabPresenter::transfer() {
     }
   }
 
-  m_tablePresenter->transfer(results.getTransferRuns());
+  m_tablePresenters.at(m_view->getSelectedGroup())
+      ->transfer(results.getTransferRuns());
 }
 
 /**
@@ -284,9 +308,8 @@ void ReflRunsTabPresenter::transfer() {
 */
 std::unique_ptr<ReflTransferStrategy>
 ReflRunsTabPresenter::getTransferStrategy() {
-  const std::string currentMethod = m_view->getTransferMethod();
   std::unique_ptr<ReflTransferStrategy> rtnStrategy;
-  if (currentMethod == MeasureTransferMethod) {
+  if (m_currentTransferMethod == MeasureTransferMethod) {
 
     // We need catalog info overrides from the user-based config service
     std::unique_ptr<CatalogConfigService> catConfigService(
@@ -306,12 +329,12 @@ ReflRunsTabPresenter::getTransferStrategy() {
     rtnStrategy = Mantid::Kernel::make_unique<ReflMeasureTransferStrategy>(
         std::move(catInfo), std::move(source));
     return rtnStrategy;
-  } else if (currentMethod == LegacyTransferMethod) {
+  } else if (m_currentTransferMethod == LegacyTransferMethod) {
     rtnStrategy = make_unique<ReflLegacyTransferStrategy>();
     return rtnStrategy;
   } else {
     throw std::runtime_error("Unknown tranfer method selected: " +
-                             currentMethod);
+                             m_currentTransferMethod);
   }
 }
 
@@ -337,7 +360,8 @@ std::map<std::string, std::string>
 ReflRunsTabPresenter::getPreprocessingOptions() const {
 
   std::map<std::string, std::string> options;
-  options["Transmission Run(s)"] = m_mainPresenter->getTransmissionOptions();
+  options["Transmission Run(s)"] =
+      m_mainPresenter->getTransmissionOptions(m_view->getSelectedGroup());
 
   return options;
 }
@@ -347,7 +371,7 @@ ReflRunsTabPresenter::getPreprocessingOptions() const {
 * @return :: Global pre-processing options
 */
 std::string ReflRunsTabPresenter::getProcessingOptions() const {
-  return m_mainPresenter->getReductionOptions();
+  return m_mainPresenter->getReductionOptions(m_view->getSelectedGroup());
 }
 
 /** Requests global pre-processing options. Options are supplied by the main
@@ -355,7 +379,7 @@ std::string ReflRunsTabPresenter::getProcessingOptions() const {
 * @return :: Global pre-processing options
 */
 std::string ReflRunsTabPresenter::getPostprocessingOptions() const {
-  return m_mainPresenter->getStitchOptions();
+  return m_mainPresenter->getStitchOptions(m_view->getSelectedGroup());
 }
 
 /**
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsPresenter.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsPresenter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..01c23e7274d6af6f9512037e3fa7d169de0bed41
--- /dev/null
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsPresenter.cpp
@@ -0,0 +1,356 @@
+#include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h"
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h"
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h"
+#include "MantidQtMantidWidgets/AlgorithmHintStrategy.h"
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/IAlgorithm.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidGeometry/Instrument.h"
+#include <boost/algorithm/string.hpp>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+
+using namespace Mantid::API;
+using namespace MantidQt::MantidWidgets;
+using namespace Mantid::Geometry;
+
+/** Constructor
+* @param view :: The view we are handling
+*/
+ReflSettingsPresenter::ReflSettingsPresenter(IReflSettingsView *view)
+    : m_view(view) {
+
+  // Create the 'HintingLineEdits'
+  createStitchHints();
+}
+
+/** Destructor
+*/
+ReflSettingsPresenter::~ReflSettingsPresenter() {}
+
+/** Used by the view to tell the presenter something has changed
+*
+* @param flag :: A flag used by the view to tell the presenter what happened
+*/
+void ReflSettingsPresenter::notify(IReflSettingsPresenter::Flag flag) {
+  switch (flag) {
+  case IReflSettingsPresenter::ExpDefaultsFlag:
+    getExpDefaults();
+    break;
+  case IReflSettingsPresenter::InstDefaultsFlag:
+    getInstDefaults();
+    break;
+  }
+  // Not having a 'default' case is deliberate. gcc issues a warning if there's
+  // a flag we aren't handling.
+}
+
+/** Sets the current instrument name and changes accessibility status of
+* the polarisation corrections option in the view accordingly
+* @param instName :: [input] The name of the instrument to set to
+*/
+void ReflSettingsPresenter::setInstrumentName(const std::string &instName) {
+  m_currentInstrumentName = instName;
+  m_view->setPolarisationOptionsEnabled(instName != "INTER" &&
+                                        instName != "SURF");
+}
+
+/** Returns global options for 'CreateTransmissionWorkspaceAuto'
+* @return :: Global options for 'CreateTransmissionWorkspaceAuto'
+*/
+std::string ReflSettingsPresenter::getTransmissionOptions() const {
+
+  std::vector<std::string> options;
+
+  // Add analysis mode
+  auto analysisMode = m_view->getAnalysisMode();
+  if (!analysisMode.empty())
+    options.push_back("AnalysisMode=" + analysisMode);
+
+  // Add monitor integral min
+  auto monIntMin = m_view->getMonitorIntegralMin();
+  if (!monIntMin.empty())
+    options.push_back("MonitorIntegrationWavelengthMin=" + monIntMin);
+
+  // Add monitor integral max
+  auto monIntMax = m_view->getMonitorIntegralMax();
+  if (!monIntMax.empty())
+    options.push_back("MonitorIntegrationWavelengthMax=" + monIntMax);
+
+  // Add monitor background min
+  auto monBgMin = m_view->getMonitorBackgroundMin();
+  if (!monBgMin.empty())
+    options.push_back("MonitorBackgroundWavelengthMin=" + monBgMin);
+
+  // Add monitor background max
+  auto monBgMax = m_view->getMonitorBackgroundMax();
+  if (!monBgMax.empty())
+    options.push_back("MonitorBackgroundWavelengthMax=" + monBgMax);
+
+  // Add lambda min
+  auto lamMin = m_view->getLambdaMin();
+  if (!lamMin.empty())
+    options.push_back("WavelengthMin=" + lamMin);
+
+  // Add lambda max
+  auto lamMax = m_view->getLambdaMax();
+  if (!lamMax.empty())
+    options.push_back("WavelengthMax=" + lamMax);
+
+  // Add I0MonitorIndex
+  auto I0MonitorIndex = m_view->getI0MonitorIndex();
+  if (!I0MonitorIndex.empty())
+    options.push_back("I0MonitorIndex=" + I0MonitorIndex);
+
+  // Add detector limits
+  auto procInst = m_view->getProcessingInstructions();
+  if (!procInst.empty())
+    options.push_back("ProcessingInstructions=" + procInst);
+
+  return boost::algorithm::join(options, ",");
+}
+
+/** Returns global options for 'ReflectometryReductionOneAuto'
+* @return :: Global options for 'ReflectometryReductionOneAuto'
+*/
+std::string ReflSettingsPresenter::getReductionOptions() const {
+
+  std::vector<std::string> options;
+
+  // Add analysis mode
+  auto analysisMode = m_view->getAnalysisMode();
+  if (!analysisMode.empty())
+    options.push_back("AnalysisMode=" + analysisMode);
+
+  // Add CRho
+  auto crho = m_view->getCRho();
+  if (!crho.empty())
+    options.push_back("CRho=" + crho);
+
+  // Add CAlpha
+  auto calpha = m_view->getCAlpha();
+  if (!calpha.empty())
+    options.push_back("CAlpha=" + calpha);
+
+  // Add CAp
+  auto cap = m_view->getCAp();
+  if (!cap.empty())
+    options.push_back("CAp=" + cap);
+
+  // Add CPp
+  auto cpp = m_view->getCPp();
+  if (!cpp.empty())
+    options.push_back("CPp=" + cpp);
+
+  // Add direct beam
+  auto dbnr = m_view->getDirectBeam();
+  if (!dbnr.empty())
+    options.push_back("RegionOfDirectBeam=" + dbnr);
+
+  // Add polarisation corrections
+  auto polCorr = m_view->getPolarisationCorrections();
+  if (!polCorr.empty())
+    options.push_back("PolarizationAnalysis=" + polCorr);
+
+  // Add integrated monitors option
+  auto intMonCheck = m_view->getIntMonCheck();
+  if (!intMonCheck.empty())
+    options.push_back("NormalizeByIntegratedMonitors=" + intMonCheck);
+
+  // Add monitor integral min
+  auto monIntMin = m_view->getMonitorIntegralMin();
+  if (!monIntMin.empty())
+    options.push_back("MonitorIntegrationWavelengthMin=" + monIntMin);
+
+  // Add monitor integral max
+  auto monIntMax = m_view->getMonitorIntegralMax();
+  if (!monIntMax.empty())
+    options.push_back("MonitorIntegrationWavelengthMax=" + monIntMax);
+
+  // Add monitor background min
+  auto monBgMin = m_view->getMonitorBackgroundMin();
+  if (!monBgMin.empty())
+    options.push_back("MonitorBackgroundWavelengthMin=" + monBgMin);
+
+  // Add monitor background max
+  auto monBgMax = m_view->getMonitorBackgroundMax();
+  if (!monBgMax.empty())
+    options.push_back("MonitorBackgroundWavelengthMax=" + monBgMax);
+
+  // Add lambda min
+  auto lamMin = m_view->getLambdaMin();
+  if (!lamMin.empty())
+    options.push_back("WavelengthMin=" + lamMin);
+
+  // Add lambda max
+  auto lamMax = m_view->getLambdaMax();
+  if (!lamMax.empty())
+    options.push_back("WavelengthMax=" + lamMax);
+
+  // Add I0MonitorIndex
+  auto I0MonitorIndex = m_view->getI0MonitorIndex();
+  if (!I0MonitorIndex.empty())
+    options.push_back("I0MonitorIndex=" + I0MonitorIndex);
+
+  // Add scale factor
+  auto scaleFactor = m_view->getScaleFactor();
+  if (!scaleFactor.empty())
+    options.push_back("ScaleFactor=" + scaleFactor);
+
+  // Add momentum transfer limits
+  auto qTransStep = m_view->getMomentumTransferStep();
+  if (!qTransStep.empty()) {
+    options.push_back("MomentumTransferStep=" + qTransStep);
+  }
+
+  // Add detector limits
+  auto procInst = m_view->getProcessingInstructions();
+  if (!procInst.empty())
+    options.push_back("ProcessingInstructions=" + procInst);
+
+  // Add transmission runs
+  auto transRuns = this->getTransmissionRuns();
+  if (!transRuns.empty())
+    options.push_back(transRuns);
+
+  return boost::algorithm::join(options, ",");
+}
+
+/** Receives specified transmission runs from the view and loads them into the
+*ADS. Returns a string with transmission runs so that they are considered in the
+*reduction
+*
+* @return :: transmission run(s) as a string that will be used for the reduction
+*/
+std::string ReflSettingsPresenter::getTransmissionRuns() const {
+
+  auto runs = m_view->getTransmissionRuns();
+  if (runs.empty())
+    return "";
+
+  std::vector<std::string> transRuns;
+  boost::split(transRuns, runs, boost::is_any_of(","));
+
+  if (transRuns.size() > 2)
+    throw std::invalid_argument("Only one transmission run or two "
+                                "transmission runs separated by ',' "
+                                "are allowed.");
+
+  for (const auto &run : transRuns) {
+    if (AnalysisDataService::Instance().doesExist("TRANS_" + run))
+      continue;
+    // Load transmission runs and put them in the ADS
+    IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadISISNexus");
+    alg->setProperty("Filename", run);
+    alg->setPropertyValue("OutputWorkspace", "TRANS_" + run);
+    alg->execute();
+  }
+
+  // Return them as options for reduction
+  std::string options = "FirstTransmissionRun=TRANS_" + transRuns[0];
+  if (transRuns.size() > 1)
+    options += ",SecondTransmissionRun=TRANS_" + transRuns[1];
+
+  return options;
+}
+
+/** Returns global options for 'Stitch1DMany'
+* @return :: Global options for 'Stitch1DMany'
+*/
+std::string ReflSettingsPresenter::getStitchOptions() const {
+
+  return m_view->getStitchOptions();
+}
+
+/** Creates hints for 'Stitch1DMany'
+*/
+void ReflSettingsPresenter::createStitchHints() {
+
+  // The algorithm
+  IAlgorithm_sptr alg = AlgorithmManager::Instance().create("Stitch1DMany");
+  // The blacklist
+  std::set<std::string> blacklist = {"InputWorkspaces", "OutputWorkspace",
+                                     "OutputWorkspace"};
+  AlgorithmHintStrategy strategy(alg, blacklist);
+
+  m_view->createStitchHints(strategy.createHints());
+}
+
+/** Fills experiment settings with default values
+*/
+void ReflSettingsPresenter::getExpDefaults() {
+  // Algorithm and instrument
+  auto alg = createReductionAlg();
+  auto inst = createEmptyInstrument(m_currentInstrumentName);
+
+  // Collect all default values and set them in view
+  std::vector<std::string> defaults(7);
+  defaults[0] = alg->getPropertyValue("AnalysisMode");
+  defaults[1] = alg->getPropertyValue("PolarizationAnalysis");
+
+  auto cRho = inst->getStringParameter("crho");
+  if (!cRho.empty())
+    defaults[2] = cRho[0];
+
+  auto cAlpha = inst->getStringParameter("calpha");
+  if (!cAlpha.empty())
+    defaults[3] = cAlpha[0];
+
+  auto cAp = inst->getStringParameter("cAp");
+  if (!cAp.empty())
+    defaults[4] = cAp[0];
+
+  auto cPp = inst->getStringParameter("cPp");
+  if (!cPp.empty())
+    defaults[5] = cPp[0];
+
+  defaults[6] = alg->getPropertyValue("ScaleFactor");
+
+  m_view->setExpDefaults(defaults);
+}
+
+/** Fills instrument settings with default values
+*/
+void ReflSettingsPresenter::getInstDefaults() {
+  // Algorithm and instrument
+  auto alg = createReductionAlg();
+  auto inst = createEmptyInstrument(m_currentInstrumentName);
+
+  // Collect all default values
+  std::vector<double> defaults(8);
+  defaults[0] = boost::lexical_cast<double>(
+      alg->getPropertyValue("NormalizeByIntegratedMonitors"));
+  defaults[1] = inst->getNumberParameter("MonitorIntegralMin")[0];
+  defaults[2] = inst->getNumberParameter("MonitorIntegralMax")[0];
+  defaults[3] = inst->getNumberParameter("MonitorBackgroundMin")[0];
+  defaults[4] = inst->getNumberParameter("MonitorBackgroundMax")[0];
+  defaults[5] = inst->getNumberParameter("LambdaMin")[0];
+  defaults[6] = inst->getNumberParameter("LambdaMax")[0];
+  defaults[7] = inst->getNumberParameter("I0MonitorIndex")[0];
+
+  m_view->setInstDefaults(defaults);
+}
+
+/** Generates and returns an instance of the ReflectometryReductionOne algorithm
+*/
+IAlgorithm_sptr ReflSettingsPresenter::createReductionAlg() {
+  return AlgorithmManager::Instance().create("ReflectometryReductionOneAuto");
+}
+
+/** Creates and returns an example empty instrument given an instrument name
+*/
+Instrument_const_sptr
+ReflSettingsPresenter::createEmptyInstrument(const std::string &instName) {
+  IAlgorithm_sptr loadInst =
+      AlgorithmManager::Instance().create("LoadEmptyInstrument");
+  loadInst->setChild(true);
+  loadInst->setProperty("OutputWorkspace", "outWs");
+  loadInst->setProperty("InstrumentName", instName);
+  loadInst->execute();
+  MatrixWorkspace_const_sptr ws = loadInst->getProperty("OutputWorkspace");
+  return ws->getInstrument();
+}
+}
+}
\ No newline at end of file
diff --git a/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsTabPresenter.cpp b/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsTabPresenter.cpp
index 03ef0f433f58882597e3eedb7b8278419d4c464a..6e082f7d0d26a2e6ea2adcc0da2f15b2124a3cd1 100644
--- a/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsTabPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Reflectometry/ReflSettingsTabPresenter.cpp
@@ -1,358 +1,67 @@
 #include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflMainWindowPresenter.h"
-#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h"
+#include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h"
 #include "MantidQtMantidWidgets/AlgorithmHintStrategy.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
+#include <boost/algorithm/string.hpp>
+
 namespace MantidQt {
 namespace CustomInterfaces {
 
-using namespace Mantid::API;
-using namespace MantidQt::MantidWidgets;
-using namespace Mantid::Geometry;
-
 /** Constructor
-* @param view :: The view we are handling
+*
+* @param presenters :: The presenters of each group as a vector
 */
-ReflSettingsTabPresenter::ReflSettingsTabPresenter(IReflSettingsTabView *view)
-    : m_view(view), m_mainPresenter() {
-
-  // Create the 'HintingLineEdits'
-  createStitchHints();
-}
+ReflSettingsTabPresenter::ReflSettingsTabPresenter(
+    std::vector<IReflSettingsPresenter *> presenters)
+    : m_settingsPresenters(presenters) {}
 
 /** Destructor
+*
 */
 ReflSettingsTabPresenter::~ReflSettingsTabPresenter() {}
 
-/** Accept a main presenter
-* @param mainPresenter :: [input] The main presenter
-*/
-void ReflSettingsTabPresenter::acceptMainPresenter(
-    IReflMainWindowPresenter *mainPresenter) {
-  m_mainPresenter = mainPresenter;
-}
-
-/** Used by the view to tell the presenter something has changed
-*/
-void ReflSettingsTabPresenter::notify(IReflSettingsTabPresenter::Flag flag) {
-  switch (flag) {
-  case IReflSettingsTabPresenter::ExpDefaultsFlag:
-    getExpDefaults();
-    break;
-  case IReflSettingsTabPresenter::InstDefaultsFlag:
-    getInstDefaults();
-    break;
-  }
-  // Not having a 'default' case is deliberate. gcc issues a warning if there's
-  // a flag we aren't handling.
-}
-
 /** Sets the current instrument name and changes accessibility status of
 * the polarisation corrections option in the view accordingly
+*
 * @param instName :: [input] The name of the instrument to set to
 */
-void ReflSettingsTabPresenter::setInstrumentName(const std::string instName) {
-  m_currentInstrumentName = instName;
-  m_view->setPolarisationOptionsEnabled(instName != "INTER" &&
-                                        instName != "SURF");
+void ReflSettingsTabPresenter::setInstrumentName(const std::string &instName) {
+  for (auto presenter : m_settingsPresenters)
+    presenter->setInstrumentName(instName);
 }
 
 /** Returns global options for 'CreateTransmissionWorkspaceAuto'
+*
+* @param group :: The group from which to get the options
 * @return :: Global options for 'CreateTransmissionWorkspaceAuto'
 */
-std::string ReflSettingsTabPresenter::getTransmissionOptions() const {
-
-  std::vector<std::string> options;
-
-  // Add analysis mode
-  auto analysisMode = m_view->getAnalysisMode();
-  if (!analysisMode.empty())
-    options.push_back("AnalysisMode=" + analysisMode);
-
-  // Add monitor integral min
-  auto monIntMin = m_view->getMonitorIntegralMin();
-  if (!monIntMin.empty())
-    options.push_back("MonitorIntegrationWavelengthMin=" + monIntMin);
-
-  // Add monitor integral max
-  auto monIntMax = m_view->getMonitorIntegralMax();
-  if (!monIntMax.empty())
-    options.push_back("MonitorIntegrationWavelengthMax=" + monIntMax);
-
-  // Add monitor background min
-  auto monBgMin = m_view->getMonitorBackgroundMin();
-  if (!monBgMin.empty())
-    options.push_back("MonitorBackgroundWavelengthMin=" + monBgMin);
-
-  // Add monitor background max
-  auto monBgMax = m_view->getMonitorBackgroundMax();
-  if (!monBgMax.empty())
-    options.push_back("MonitorBackgroundWavelengthMax=" + monBgMax);
-
-  // Add lambda min
-  auto lamMin = m_view->getLambdaMin();
-  if (!lamMin.empty())
-    options.push_back("WavelengthMin=" + lamMin);
+std::string ReflSettingsTabPresenter::getTransmissionOptions(int group) const {
 
-  // Add lambda max
-  auto lamMax = m_view->getLambdaMax();
-  if (!lamMax.empty())
-    options.push_back("WavelengthMax=" + lamMax);
-
-  // Add I0MonitorIndex
-  auto I0MonitorIndex = m_view->getI0MonitorIndex();
-  if (!I0MonitorIndex.empty())
-    options.push_back("I0MonitorIndex=" + I0MonitorIndex);
-
-  // Add detector limits
-  auto procInst = m_view->getProcessingInstructions();
-  if (!procInst.empty())
-    options.push_back("ProcessingInstructions=" + procInst);
-
-  return boost::algorithm::join(options, ",");
+  return m_settingsPresenters.at(group)->getTransmissionOptions();
 }
 
 /** Returns global options for 'ReflectometryReductionOneAuto'
-* @return :: Global options for 'ReflectometryReductionOneAuto'
-*/
-std::string ReflSettingsTabPresenter::getReductionOptions() const {
-
-  std::vector<std::string> options;
-
-  // Add analysis mode
-  auto analysisMode = m_view->getAnalysisMode();
-  if (!analysisMode.empty())
-    options.push_back("AnalysisMode=" + analysisMode);
-
-  // Add CRho
-  auto crho = m_view->getCRho();
-  if (!crho.empty())
-    options.push_back("CRho=" + crho);
-
-  // Add CAlpha
-  auto calpha = m_view->getCAlpha();
-  if (!calpha.empty())
-    options.push_back("CAlpha=" + calpha);
-
-  // Add CAp
-  auto cap = m_view->getCAp();
-  if (!cap.empty())
-    options.push_back("CAp=" + cap);
-
-  // Add CPp
-  auto cpp = m_view->getCPp();
-  if (!cpp.empty())
-    options.push_back("CPp=" + cpp);
-
-  // Add direct beam
-  auto dbnr = m_view->getDirectBeam();
-  if (!dbnr.empty())
-    options.push_back("RegionOfDirectBeam=" + dbnr);
-
-  // Add polarisation corrections
-  auto polCorr = m_view->getPolarisationCorrections();
-  if (!polCorr.empty())
-    options.push_back("PolarizationAnalysis=" + polCorr);
-
-  // Add integrated monitors option
-  auto intMonCheck = m_view->getIntMonCheck();
-  if (!intMonCheck.empty())
-    options.push_back("NormalizeByIntegratedMonitors=" + intMonCheck);
-
-  // Add monitor integral min
-  auto monIntMin = m_view->getMonitorIntegralMin();
-  if (!monIntMin.empty())
-    options.push_back("MonitorIntegrationWavelengthMin=" + monIntMin);
-
-  // Add monitor integral max
-  auto monIntMax = m_view->getMonitorIntegralMax();
-  if (!monIntMax.empty())
-    options.push_back("MonitorIntegrationWavelengthMax=" + monIntMax);
-
-  // Add monitor background min
-  auto monBgMin = m_view->getMonitorBackgroundMin();
-  if (!monBgMin.empty())
-    options.push_back("MonitorBackgroundWavelengthMin=" + monBgMin);
-
-  // Add monitor background max
-  auto monBgMax = m_view->getMonitorBackgroundMax();
-  if (!monBgMax.empty())
-    options.push_back("MonitorBackgroundWavelengthMax=" + monBgMax);
-
-  // Add lambda min
-  auto lamMin = m_view->getLambdaMin();
-  if (!lamMin.empty())
-    options.push_back("WavelengthMin=" + lamMin);
-
-  // Add lambda max
-  auto lamMax = m_view->getLambdaMax();
-  if (!lamMax.empty())
-    options.push_back("WavelengthMax=" + lamMax);
-
-  // Add I0MonitorIndex
-  auto I0MonitorIndex = m_view->getI0MonitorIndex();
-  if (!I0MonitorIndex.empty())
-    options.push_back("I0MonitorIndex=" + I0MonitorIndex);
-
-  // Add scale factor
-  auto scaleFactor = m_view->getScaleFactor();
-  if (!scaleFactor.empty())
-    options.push_back("ScaleFactor=" + scaleFactor);
-
-  // Add momentum transfer limits
-  auto qTransStep = m_view->getMomentumTransferStep();
-  if (!qTransStep.empty()) {
-    options.push_back("MomentumTransferStep=" + qTransStep);
-  }
-
-  // Add detector limits
-  auto procInst = m_view->getProcessingInstructions();
-  if (!procInst.empty())
-    options.push_back("ProcessingInstructions=" + procInst);
-
-  // Add transmission runs
-  auto transRuns = this->getTransmissionRuns();
-  if (!transRuns.empty())
-    options.push_back(transRuns);
-
-  return boost::algorithm::join(options, ",");
-}
-
-/** Receives specified transmission runs from the view and loads them into the
-*ADS. Returns a string with transmission runs so that they are considered in the
-*reduction
 *
-* @return :: transmission run(s) as a string that will be used for the reduction
+* @param group :: The group from which to get the options
+* @return :: Global options for 'ReflectometryReductionOneAuto'
 */
-std::string ReflSettingsTabPresenter::getTransmissionRuns() const {
-
-  auto runs = m_view->getTransmissionRuns();
-  if (runs.empty())
-    return "";
+std::string ReflSettingsTabPresenter::getReductionOptions(int group) const {
 
-  std::vector<std::string> transRuns;
-  boost::split(transRuns, runs, boost::is_any_of(","));
-
-  if (transRuns.size() > 2)
-    throw std::invalid_argument("Only one transmission run or two "
-                                "transmission runs separated by ',' "
-                                "are allowed.");
-
-  for (const auto &run : transRuns) {
-    if (AnalysisDataService::Instance().doesExist("TRANS_" + run))
-      continue;
-    // Load transmission runs and put them in the ADS
-    IAlgorithm_sptr alg = AlgorithmManager::Instance().create("LoadISISNexus");
-    alg->setProperty("Filename", run);
-    alg->setPropertyValue("OutputWorkspace", "TRANS_" + run);
-    alg->execute();
-  }
-
-  // Return them as options for reduction
-  std::string options = "FirstTransmissionRun=TRANS_" + transRuns[0];
-  if (transRuns.size() > 1)
-    options += ",SecondTransmissionRun=TRANS_" + transRuns[1];
-
-  return options;
+  return m_settingsPresenters.at(group)->getReductionOptions();
 }
 
 /** Returns global options for 'Stitch1DMany'
+*
+* @param group :: The group from which to get the options
 * @return :: Global options for 'Stitch1DMany'
 */
-std::string ReflSettingsTabPresenter::getStitchOptions() const {
-
-  return m_view->getStitchOptions();
-}
-
-/** Creates hints for 'Stitch1DMany'
-*/
-void ReflSettingsTabPresenter::createStitchHints() {
-
-  // The algorithm
-  IAlgorithm_sptr alg = AlgorithmManager::Instance().create("Stitch1DMany");
-  // The blacklist
-  std::set<std::string> blacklist = {"InputWorkspaces", "OutputWorkspace",
-                                     "OutputWorkspace"};
-  AlgorithmHintStrategy strategy(alg, blacklist);
-
-  m_view->createStitchHints(strategy.createHints());
-}
-
-/** Fills experiment settings with default values
-*/
-void ReflSettingsTabPresenter::getExpDefaults() {
-  // Algorithm and instrument
-  auto alg = createReductionAlg();
-  auto inst = createEmptyInstrument(m_currentInstrumentName);
-
-  // Collect all default values and set them in view
-  std::vector<std::string> defaults(7);
-  defaults[0] = alg->getPropertyValue("AnalysisMode");
-  defaults[1] = alg->getPropertyValue("PolarizationAnalysis");
-
-  auto cRho = inst->getStringParameter("crho");
-  if (!cRho.empty())
-    defaults[2] = cRho[0];
-
-  auto cAlpha = inst->getStringParameter("calpha");
-  if (!cAlpha.empty())
-    defaults[3] = cAlpha[0];
-
-  auto cAp = inst->getStringParameter("cAp");
-  if (!cAp.empty())
-    defaults[4] = cAp[0];
-
-  auto cPp = inst->getStringParameter("cPp");
-  if (!cPp.empty())
-    defaults[5] = cPp[0];
-
-  defaults[6] = alg->getPropertyValue("ScaleFactor");
-
-  m_view->setExpDefaults(defaults);
-}
-
-/** Fills instrument settings with default values
-*/
-void ReflSettingsTabPresenter::getInstDefaults() {
-  // Algorithm and instrument
-  auto alg = createReductionAlg();
-  auto inst = createEmptyInstrument(m_currentInstrumentName);
-
-  // Collect all default values
-  std::vector<double> defaults(8);
-  defaults[0] = boost::lexical_cast<double>(
-      alg->getPropertyValue("NormalizeByIntegratedMonitors"));
-  defaults[1] = inst->getNumberParameter("MonitorIntegralMin")[0];
-  defaults[2] = inst->getNumberParameter("MonitorIntegralMax")[0];
-  defaults[3] = inst->getNumberParameter("MonitorBackgroundMin")[0];
-  defaults[4] = inst->getNumberParameter("MonitorBackgroundMax")[0];
-  defaults[5] = inst->getNumberParameter("LambdaMin")[0];
-  defaults[6] = inst->getNumberParameter("LambdaMax")[0];
-  defaults[7] = inst->getNumberParameter("I0MonitorIndex")[0];
+std::string ReflSettingsTabPresenter::getStitchOptions(int group) const {
 
-  m_view->setInstDefaults(defaults);
+  return m_settingsPresenters.at(group)->getStitchOptions();
 }
-
-/** Generates and returns an instance of the ReflectometryReductionOne algorithm
-*/
-IAlgorithm_sptr ReflSettingsTabPresenter::createReductionAlg() {
-  return AlgorithmManager::Instance().create("ReflectometryReductionOneAuto");
-}
-
-/** Creates and returns an example empty instrument given an instrument name
-*/
-Instrument_const_sptr
-ReflSettingsTabPresenter::createEmptyInstrument(std::string instName) {
-  IAlgorithm_sptr loadInst =
-      AlgorithmManager::Instance().create("LoadEmptyInstrument");
-  loadInst->setChild(true);
-  loadInst->setProperty("OutputWorkspace", "outWs");
-  loadInst->setProperty("InstrumentName", instName);
-  loadInst->execute();
-  MatrixWorkspace_const_sptr ws = loadInst->getProperty("OutputWorkspace");
-  return ws->getInstrument();
 }
 }
-}
\ No newline at end of file
diff --git a/MantidQt/CustomInterfaces/src/SANSAddFiles.cpp b/MantidQt/CustomInterfaces/src/SANSAddFiles.cpp
index 23598d28162ee1e4bde5742e5a39990afa75e452..d8c0a534b33ce2a535446daa12dc9bdb2d7f9aff 100644
--- a/MantidQt/CustomInterfaces/src/SANSAddFiles.cpp
+++ b/MantidQt/CustomInterfaces/src/SANSAddFiles.cpp
@@ -4,6 +4,7 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidAPI/FileProperty.h"
 #include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/PropertyHelper.h"
 #include "MantidAPI/AlgorithmManager.h"
 
 #include <QStringList>
diff --git a/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp b/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp
index b9a5d746b3d1b694e7769c496fa580e50e3b1091..5018d487eb361c564d296bd90ade9cabe373f6dc 100644
--- a/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp
+++ b/MantidQt/CustomInterfaces/src/SANSRunWindow.cpp
@@ -17,7 +17,6 @@
 #include "MantidAPI/Run.h"
 #include "MantidAPI/WorkspaceGroup.h"
 
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/MantidDesktopServices.h"
 #include "MantidQtAPI/ManageUserDirectories.h"
 #include "MantidQtCustomInterfaces/SANSAddFiles.h"
@@ -25,6 +24,7 @@
 #include "MantidQtCustomInterfaces/SANSEventSlicing.h"
 
 #include <QClipboard>
+#include <QFileDialog>
 #include <QTemporaryFile>
 #include <QTextStream>
 #include <QUrl>
@@ -1981,7 +1981,7 @@ void SANSRunWindow::saveFileBrowse() {
 
   const QString filter = ";;AllFiles (*)";
 
-  QString oFile = FileDialogHandler::getSaveFileName(
+  QString oFile = QFileDialog::getSaveFileName(
       this, title, prevPath + "/" + m_uiForm.outfile_edit->text());
 
   if (!oFile.isEmpty()) {
@@ -2515,8 +2515,8 @@ void SANSRunWindow::handleReduceButtonClick(const QString &typeStr) {
 
     QString csv_file(m_uiForm.csv_filename->text());
     if (m_dirty_batch_grid) {
-      QString selected_file = MantidQt::API::FileDialogHandler::getSaveFileName(
-          this, "Save as CSV", m_last_dir);
+      QString selected_file =
+          QFileDialog::getSaveFileName(this, "Save as CSV", m_last_dir);
       csv_file = saveBatchGrid(selected_file);
     }
     py_code.prepend("import SANSBatchMode as batch\n");
diff --git a/MantidQt/CustomInterfaces/src/StepScan.cpp b/MantidQt/CustomInterfaces/src/StepScan.cpp
index 0aafa658bc16f2589d0d53a564f685602205d5c7..fda17e6c5e3dacf5b56f2a3647c6459f2b4ff174 100644
--- a/MantidQt/CustomInterfaces/src/StepScan.cpp
+++ b/MantidQt/CustomInterfaces/src/StepScan.cpp
@@ -5,7 +5,9 @@
 #include "MantidAPI/InstrumentDataService.h"
 #include "MantidAPI/LiveListenerFactory.h"
 #include "MantidAPI/Run.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/InstrumentInfo.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include <QFileInfo>
 #include <QUrl>
@@ -124,7 +126,6 @@ void StepScan::startLiveListener() {
         "This interface requires event data.\nThe live data for " +
             QString::fromStdString(m_instrument) + " is in histogram form");
     m_uiForm.mWRunFiles->liveButtonSetChecked(false);
-    m_uiForm.mWRunFiles->liveButtonSetEnabled(false);
     return;
   }
 
diff --git a/MantidQt/CustomInterfaces/src/Tomography/EnergyBandsViewQtGUI.cpp b/MantidQt/CustomInterfaces/src/Tomography/EnergyBandsViewQtGUI.cpp
index 516633b5157f81df6afbee5c12695d37cb810c83..80a2a43378668f2843cb3acce51e5d8e21b7266f 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/EnergyBandsViewQtGUI.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/EnergyBandsViewQtGUI.cpp
@@ -132,6 +132,8 @@ void TomographyIfaceViewQtGUI::browseAggScriptClicked() {
 void TomographyIfaceViewQtGUI::runAggregateBands(
     Mantid::API::IAlgorithm_sptr alg) {
 
+  // reset any previous connections
+  m_aggAlgRunner.get()->disconnect();
   connect(m_aggAlgRunner.get(), SIGNAL(batchComplete(bool)), this,
           SLOT(finishedAggBands(bool)), Qt::QueuedConnection);
 
diff --git a/MantidQt/CustomInterfaces/src/Tomography/ImageROIPresenter.cpp b/MantidQt/CustomInterfaces/src/Tomography/ImageROIPresenter.cpp
index a739bdaf9691a550c6cf32d8ca2ece4f38bc7226..313daa2b592b86284466320169ec65c9cc927f1e 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/ImageROIPresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/ImageROIPresenter.cpp
@@ -135,7 +135,7 @@ void ImageROIPresenter::processBrowseImage() {
     return;
 
   m_stackPath = path;
-  processNewStack(true);
+  processLoadSingleImage();
 }
 
 void ImageROIPresenter::processBrowseStack() {
@@ -145,7 +145,7 @@ void ImageROIPresenter::processBrowseStack() {
     return;
 
   m_stackPath = path;
-  processNewStack(false);
+  processLoadStackOfImages();
 }
 
 /**
@@ -177,62 +177,64 @@ StackOfImagesDirs ImageROIPresenter::checkInputStack(const std::string &path) {
   return soid;
 }
 
-void ImageROIPresenter::processNewStack(bool singleImg) {
-  if (!singleImg) {
-
-    StackOfImagesDirs soid("");
-    try {
-      soid = checkInputStack(m_stackPath);
-    } catch (std::exception &e) {
-      // Poco::FileNotFoundException: this should never happen, unless
-      // the open dir dialog misbehaves unexpectedly, or in tests
-      m_view->userWarning(
-          "Error trying to open directories/files",
-          "The path selected via the dialog cannot be openend or "
-          "there was a problem while trying to access it. This "
-          "is an unexpected inconsistency. Error details: " +
-              std::string(e.what()));
+void ImageROIPresenter::processLoadSingleImage() {
+  try {
+    auto &ads = Mantid::API::AnalysisDataService::Instance();
+    if (ads.doesExist(g_wsgName)) {
+      ads.remove(g_wsgName);
     }
-
-    if (!soid.isValid())
-      return;
-
-    std::vector<std::string> imgs = soid.sampleFiles();
-    if (0 >= imgs.size()) {
-      m_view->userWarning(
-          "Error while trying to find image/projection files in the stack "
-          "directories",
-          "Could not find any (image) file in the samples subdirectory: " +
-              soid.sampleImagesDir());
-      return;
+    if (ads.doesExist(g_wsgFlatsName)) {
+      ads.remove(g_wsgFlatsName);
+    }
+    if (ads.doesExist(g_wsgDarksName)) {
+      ads.remove(g_wsgDarksName);
     }
+  } catch (std::runtime_error &rexc) {
+    g_log.warning("There was a problem while trying to remove apparently "
+                  "existing workspaces. Error details: " +
+                  std::string(rexc.what()));
+  }
 
-    loadFITSStack(soid, g_wsgName, g_wsgFlatsName, g_wsgDarksName);
-    m_stackFlats = nullptr;
-    m_stackDarks = nullptr;
+  loadFITSImage(m_stackPath, g_wsgName);
+  setupAlgorithmRunnerAfterLoad();
+}
 
-  } else {
-    // TODO: find a better place for this
-    try {
-      auto &ads = Mantid::API::AnalysisDataService::Instance();
-      if (ads.doesExist(g_wsgName)) {
-        ads.remove(g_wsgName);
-      }
-      if (ads.doesExist(g_wsgFlatsName)) {
-        ads.remove(g_wsgFlatsName);
-      }
-      if (ads.doesExist(g_wsgDarksName)) {
-        ads.remove(g_wsgDarksName);
-      }
-    } catch (std::runtime_error &rexc) {
-      g_log.warning("There was a problem while trying to remove apparently "
-                    "existing workspaces. Error details: " +
-                    std::string(rexc.what()));
-    }
+void ImageROIPresenter::processLoadStackOfImages() {
+  StackOfImagesDirs soid("");
+  try {
+    soid = checkInputStack(m_stackPath);
+  } catch (std::exception &e) {
+    // Poco::FileNotFoundException: this should never happen, unless
+    // the open dir dialog misbehaves unexpectedly, or in tests
+    m_view->userWarning("Error trying to open directories/files",
+                        "The path selected via the dialog cannot be openend or "
+                        "there was a problem while trying to access it. This "
+                        "is an unexpected inconsistency. Error details: " +
+                            std::string(e.what()));
+  }
+
+  if (!soid.isValid())
+    return;
 
-    loadFITSImage(m_stackPath, g_wsgName);
+  std::vector<std::string> imgs = soid.sampleFiles();
+  if (0 >= imgs.size()) {
+    m_view->userWarning(
+        "Error while trying to find image/projection files in the stack "
+        "directories",
+        "Could not find any (image) file in the samples subdirectory: " +
+            soid.sampleImagesDir());
+    return;
   }
 
+  loadFITSStack(soid, g_wsgName, g_wsgFlatsName, g_wsgDarksName);
+  m_stackFlats = nullptr;
+  m_stackDarks = nullptr;
+  setupAlgorithmRunnerAfterLoad();
+}
+
+void ImageROIPresenter::setupAlgorithmRunnerAfterLoad() {
+  // reset any previous connections
+  m_algRunner.get()->disconnect();
   connect(m_algRunner.get(), SIGNAL(batchComplete(bool)), this,
           SLOT(finishedLoadStack(bool)), Qt::QueuedConnection);
 
diff --git a/MantidQt/CustomInterfaces/src/Tomography/ImageROIViewQtWidget.cpp b/MantidQt/CustomInterfaces/src/Tomography/ImageROIViewQtWidget.cpp
index 56e0b1ea8d526fb6703d6f404090f6c4d6f8c2c1..bc9839db3884a9c21bc54946ed02375e1b0c6538 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/ImageROIViewQtWidget.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/ImageROIViewQtWidget.cpp
@@ -481,6 +481,9 @@ void ImageROIViewQtWidget::refreshROIetAl() {
   if (!pp)
     return;
 
+  m_ui.label_img->setMaximumWidth(static_cast<int>(m_imgWidth));
+  m_ui.label_img->setMaximumHeight(static_cast<int>(m_imgHeight));
+
   QPixmap toDisplay(*m_basePixmap.get());
   QPainter painter(&toDisplay);
 
diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp
index 31497f41dd006f5d391f4918118058d8367d5e20..7bc14215c90e98a4c0c9a41afcf09dae2ea5954e 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/TomoToolConfigDialogSavu.cpp
@@ -1,3 +1,8 @@
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceViewQtGUI.h"
+
+#include <boost/lexical_cast.hpp>
 #include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogSavu.h"
 #include "MantidQtCustomInterfaces/Tomography/TomoReconToolsUserSettings.h"
 
diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp
index e9e6b2a00e5ec9c33623f1b3d49c4cf96ba56464..51cdc53e074010637e9b577a3ff24ab609a41fff 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceModel.cpp
@@ -1,16 +1,15 @@
-#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidQtAPI/AlgorithmRunner.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
 
-#include <Poco/Path.h>
-#include <Poco/Pipe.h>
-#include <Poco/PipeStream.h>
-#include <Poco/Process.h>
-#include <Poco/StreamCopier.h>
+#include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyProcess.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyThread.h"
 
-#include <QMutex>
+#include <Poco/Path.h>
 
 #ifndef _WIN32
 // This is exclusively for kill/waitpid (interim solution, see below)
@@ -336,50 +335,53 @@ void TomographyIfaceModel::doQueryJobStatus(const std::string &compRes,
  * --params..
  * - remote only has the script path: /scriptPathOnRemote/ --params..
  *
- * @param comp Compute resource for which the command line is being prepared
+ * @param local Is the resource local or remote
  * @param runnable Path to a runnable application (script, python module, etc.)
- * @param opt Command line options to the application
+ * @param args A vector that contains all the arguments
+ * @param allOpts The concatenated arguments in a single string
  */
-void TomographyIfaceModel::makeRunnableWithOptions(
-    const std::string &comp, std::string &runnable,
-    std::vector<std::string> &opt) const {
-
+void TomographyIfaceModel::prepareSubmissionArguments(
+    const bool local, std::string &runnable, std::vector<std::string> &args,
+    std::string &allOpts) {
   if (!m_currentToolSettings) {
     throw std::invalid_argument("Settings for tool not set up");
   }
-
   const std::string tool = usingTool();
-
   const std::string cmd = m_currentToolSettings->toCommand();
 
-  const bool local = (g_LocalResourceName == comp) ? true : false;
-
   std::string longOpt;
   // this gets the runnable from the whole string
   splitCmdLine(cmd, runnable, longOpt);
-  // Special case. Just pass on user inputs.
-  // this stops from appending all the filters and other options
+
+  // this is discarded for all tools but the custom command
+  std::string trailingCommands;
+  if (local) {
+    std::string execScriptPath;
+    splitCmdLine(longOpt, execScriptPath, trailingCommands);
+    args.emplace_back(execScriptPath);
+  }
+
   if (tool == g_customCmdTool) {
-    opt.resize(1);
-    // this will pass on all the arguments as a single member
-    opt[0] = longOpt;
+    // if it's local we need to append the trailingCommands, as the
+    // external interpreter and script path are already appended, the script
+    // path has to be in a separate argument member otherwise running the
+    // external interpreter fails if remote we just want to append all of the
+    // options, the script path is already appended
+    args.emplace_back(local ? trailingCommands : longOpt);
+    allOpts = constructSingleStringFromVector(args);
     return;
   }
 
-  if (local) {
-    std::string execScriptPath;
+  // appends the additional options tool name, algorithm name, filters, etc
+  makeTomoRecScriptOptions(local, args);
 
-    // this variable holds the input paths, but is discarded for now
-    // until the command line building overhaul
-    std::string discardedInputPaths;
-    // this gets the path to the python script tomo_reconstruct.py
-    splitCmdLine(longOpt, execScriptPath, discardedInputPaths);
+  checkIfToolIsSetupProperly(tool, cmd, args);
 
-    checkIfToolIsSetupProperly(tool, cmd);
-    opt.emplace_back(execScriptPath);
-  }
+  // used for remote submission
+  allOpts = constructSingleStringFromVector(args);
 
-  makeTomoRecScriptOptions(local, opt);
+  logMsg("Running " + usingTool() + ", with binary: " + runnable +
+         ", with parameters: " + allOpts);
 }
 
 /**
@@ -436,42 +438,8 @@ std::string TomographyIfaceModel::constructSingleStringFromVector(
   return allOpts;
 }
 
-/** Handling the job submission request relies on a submit algorithm.
- * @param compRes The resource to which the request will be made
- */
-void TomographyIfaceModel::doSubmitReconstructionJob(
-    const std::string &compRes) {
-  std::string run;
-  std::vector<std::string> args;
-  try {
-    makeRunnableWithOptions(compRes, run, args);
-  } catch (std::exception &e) {
-    g_log.error() << "Could not prepare the requested reconstruction job "
-                     "submission. There was an error: " +
-                         std::string(e.what());
-    throw;
-  }
-
-  if (run.empty()) {
-    throw std::runtime_error(
-        "The script or executable to run is not defined "
-        "(empty string). You need to setup the reconstruction tool.");
-  }
-
-  std::string allOpts = constructSingleStringFromVector(args);
-
-  logMsg("Running " + usingTool() + ", with binary: " + run +
-         ", with parameters: " + allOpts);
-
-  if (g_LocalResourceName == compRes) {
-    doRunReconstructionJobLocal(run, allOpts, args);
-  } else {
-    doRunReconstructionJobRemote(compRes, run, allOpts);
-  }
-}
-
-void TomographyIfaceModel::doRunReconstructionJobRemote(
-    const std::string &compRes, const std::string &run,
+void TomographyIfaceModel::doRemoteRunReconstructionJob(
+    const std::string &compRes, const std::string &runnable,
     const std::string &allOpts) {
   // with SCARF we use one (pseudo)-transaction for every submission
   auto transAlg = Mantid::API::AlgorithmManager::Instance().createUnmanaged(
@@ -494,7 +462,7 @@ void TomographyIfaceModel::doRunReconstructionJobRemote(
   submitAlg->setProperty("ComputeResource", compRes);
   submitAlg->setProperty("TaskName", "Mantid tomographic reconstruction job");
   submitAlg->setProperty("TransactionID", tid);
-  submitAlg->setProperty("ScriptName", run);
+  submitAlg->setProperty("ScriptName", runnable);
   submitAlg->setProperty("ScriptParams", allOpts);
   try {
     submitAlg->execute();
@@ -505,57 +473,37 @@ void TomographyIfaceModel::doRunReconstructionJobRemote(
   }
 }
 
-void TomographyIfaceModel::doRunReconstructionJobLocal(
-    const std::string &run, const std::string &allOpts,
-    const std::vector<std::string> &args) {
-
-  // initialise to 0, if the launch fails then the id will not be changed
-  Poco::Process::PID pid = 0;
-  // Poco::Pipe outPipe;
-  // Poco::Pipe errPipe;
-  try {
-    Poco::ProcessHandle handle = Poco::Process::launch(run, args);
-    pid = handle.id();
-  } catch (Poco::SystemException &sexc) {
-    g_log.error() << "Execution failed. Could not run the tool. Error details: "
-                  << std::string(sexc.what());
-  }
+/** Starts the local thread with the external reconstruction process
+ * @param runnable Path to a runnable application (script, python module, etc.)
+ * @param args A vector that contains all the arguments
+ * @param allOpts The concatenated arguments in a single string
+ * @param thread This thread will be started after the worker is set up with the
+ *    runnable and the arguments
+ * @param worker The worker will only be set up with the runnable and arguments
+ */
+void TomographyIfaceModel::doLocalRunReconstructionJob(
+    const std::string &runnable, const std::vector<std::string> &args,
+    const std::string &allOpts, TomographyThread &thread,
+    TomographyProcess &worker) {
+
+  // Can only run one reconstruction at a time
+  // Qt doesn't use exceptions so we can't make sure it ran here
+  worker.setup(runnable, args, allOpts);
+  thread.start();
+}
 
+void TomographyIfaceModel::addJobToStatus(const qint64 pid,
+                                          const std::string &runnable,
+                                          const std::string &allOpts) {
   Mantid::API::IRemoteJobManager::RemoteJobInfo info;
   info.id = boost::lexical_cast<std::string>(pid);
   info.name = pid > 0 ? "Mantid_Local" : "none";
   info.status = pid > 0 ? "Starting" : "Exit";
-  info.cmdLine = run + " " + allOpts;
+  info.cmdLine = runnable + " " + allOpts;
   m_jobsStatusLocal.emplace_back(info);
-
   doRefreshJobsInfo(g_LocalResourceName);
 }
 
-/** Converts the pipes to strings and prints them into the mantid logger stream
-*
-* @param outPipe Poco::Pipe that holds the output stream of the process
-* @param errPipe Poco::Pipe that holds the error stream of the process
-*/
-void TomographyIfaceModel::printProcessStreamsToMantidLog(
-    const Poco::Pipe &outPipe, const Poco::Pipe &errPipe) {
-  // if the launch is successful then print output streams
-  // into the g_log so the user can see the information/error
-  Poco::PipeInputStream outstr(outPipe);
-  Poco::PipeInputStream errstr(errPipe);
-  std::string outString;
-  std::string errString;
-  Poco::StreamCopier::copyToString(outstr, outString);
-  Poco::StreamCopier::copyToString(errstr, errString);
-
-  // print normal output stream if not empty
-  if (!outString.empty())
-    g_log.information(outString);
-
-  // print error output stream if not empty
-  if (!errString.empty())
-    g_log.error(errString);
-}
-
 void TomographyIfaceModel::doCancelJobs(const std::string &compRes,
                                         const std::vector<std::string> &ids) {
   for (size_t i = 0; i < ids.size(); i++) {
@@ -613,6 +561,17 @@ void TomographyIfaceModel::refreshLocalJobsInfo() {
   }
 }
 
+void TomographyIfaceModel::updateProcessInJobList(const qint64 pid,
+                                                  const int exitCode) {
+  // cast to string from qint64 so we can compare
+  const std::string processPID = std::to_string(pid);
+  for (auto &job : m_jobsStatusLocal) {
+    if (job.id == processPID && exitCode == 1) {
+      job.status = "Exit";
+    }
+  }
+}
+
 void TomographyIfaceModel::getJobStatusInfo(const std::string &compRes) {
   if (m_loggedInUser.empty())
     return;
@@ -687,9 +646,9 @@ void TomographyIfaceModel::checkDataPathsSet() const {
  *
  * @return running status
  */
-bool TomographyIfaceModel::processIsRunning(int pid) {
+bool TomographyIfaceModel::processIsRunning(qint64 pid) const {
 #ifdef _WIN32
-  HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
+  HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, static_cast<int>(pid));
   DWORD code;
   BOOL rc = GetExitCodeProcess(handle, &code);
   CloseHandle(handle);
@@ -698,8 +657,9 @@ bool TomographyIfaceModel::processIsRunning(int pid) {
   // zombie/defunct processes
   while (waitpid(-1, 0, WNOHANG) > 0) {
   }
-  return (0 == kill(pid, 0));
+  return (0 == kill(static_cast<int>(pid), 0));
 #endif
+  // return Poco::Process::isRunning(pid);
 }
 
 /**
@@ -709,10 +669,12 @@ bool TomographyIfaceModel::processIsRunning(int pid) {
  *
  * @param tool Name of the tool this warning applies to
  * @param cmd command/script/executable derived from the settings
+ * @param args All the arguments for the run
  */
 bool TomographyIfaceModel::checkIfToolIsSetupProperly(
-    const std::string &tool, const std::string &cmd) const {
-  if (tool.empty() || cmd.empty()) {
+    const std::string &tool, const std::string &cmd,
+    const std::vector<std::string> &args) const {
+  if (tool.empty() || cmd.empty() || args.empty()) {
     const std::string detail =
         "Please define the settings of this tool. "
         "You have not defined any settings for this tool: " +
@@ -731,7 +693,7 @@ bool TomographyIfaceModel::checkIfToolIsSetupProperly(
  * when the code is reorganized to use the tool settings objects better.
  */
 void TomographyIfaceModel::splitCmdLine(const std::string &cmd,
-                                        std::string &run,
+                                        std::string &runnable,
                                         std::string &opts) const {
   if (cmd.empty())
     return;
@@ -740,7 +702,7 @@ void TomographyIfaceModel::splitCmdLine(const std::string &cmd,
   if (std::string::npos == pos)
     return;
 
-  run = cmd.substr(0, pos);
+  runnable = cmd.substr(0, pos);
   opts = cmd.substr(pos + 1);
 }
 
@@ -805,8 +767,10 @@ TomographyIfaceModel::loadFITSImage(const std::string &path) {
   }
 }
 
-void TomographyIfaceModel::logMsg(const std::string &msg) {
-  g_log.notice() << msg << '\n';
+void TomographyIfaceModel::logMsg(const std::string &msg) { g_log.notice(msg); }
+
+void TomographyIfaceModel::logErrMsg(const std::string &msg) {
+  g_log.error(msg);
 }
 
 /**
diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp
index 3952b276cc2f7b9d45ec427618826f34558e1e3b..4b02439d07c5d8734a372ced25054256f1fb8408 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfacePresenter.cpp
@@ -1,4 +1,3 @@
-#include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/TableRow.h"
@@ -6,7 +5,11 @@
 #include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 #include "MantidQtCustomInterfaces/Tomography/ITomographyIfaceView.h"
+#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h"
 #include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyIfacePresenter.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyProcess.h"
+#include "MantidQtCustomInterfaces/Tomography/TomographyThread.h"
 
 #include <boost/lexical_cast.hpp>
 
@@ -19,8 +22,6 @@
 #include <QThread>
 #include <QTimer>
 
-#include "MantidQtCustomInterfaces/Tomography/TomoToolConfigDialogBase.h"
-
 using namespace Mantid::API;
 using namespace MantidQt::CustomInterfaces;
 
@@ -42,22 +43,18 @@ const std::string TomographyIfacePresenter::g_defOutPathRemote =
 #endif
 
 TomographyIfacePresenter::TomographyIfacePresenter(ITomographyIfaceView *view)
-    : m_view(view), m_model(new TomographyIfaceModel()), m_statusMutex(NULL),
-      m_keepAliveTimer(NULL), m_keepAliveThread(NULL) {
+    : m_view(view), m_model(new TomographyIfaceModel()),
+      m_statusMutex(new QMutex()), m_keepAliveTimer(nullptr) {
   if (!m_view) {
     throw std::runtime_error("Severe inconsistency found. Presenter created "
                              "with an empty/null view (tomography interface). "
                              "Cannot continue.");
   }
-  m_statusMutex = new QMutex();
 }
 
 TomographyIfacePresenter::~TomographyIfacePresenter() {
   cleanup();
 
-  if (m_keepAliveThread)
-    delete m_keepAliveThread;
-
   if (m_keepAliveTimer)
     delete m_keepAliveTimer;
 
@@ -554,38 +551,126 @@ void TomographyIfacePresenter::processRunRecon() {
   // center of rotation and regions
   m_model->setImageStackPreParams(m_view->currentROIEtcParams());
 
+  // we have to branch out to handle local and remote somewhere
   try {
-    m_model->doSubmitReconstructionJob(m_view->currentComputeResource());
+    const bool local = isLocalResourceSelected();
+
+    std::string runnable;
+    std::vector<std::string> args;
+    std::string allOpts;
+
+    m_model->prepareSubmissionArguments(local, runnable, args, allOpts);
+    if (local) {
+      setupAndRunLocalReconstruction(runnable, args, allOpts);
+
+      // start the refresh jobs timer if not running
+      startKeepAliveMechanism(m_view->keepAlivePeriod());
+    } else {
+      // get the actual compute resource name
+      const std::string computingResouce = m_view->currentComputeResource();
+      m_model->doRemoteRunReconstructionJob(computingResouce, runnable,
+                                            allOpts);
+    }
   } catch (std::exception &e) {
     m_view->userWarning("Issue when trying to start a job", e.what());
   }
+
   processRefreshJobs();
 }
 
-bool TomographyIfacePresenter::isLocalResourceSelected() const {
-  return m_model->localComputeResource() == m_view->currentComputeResource();
+bool TomographyIfacePresenter::userConfirmationToCancelRecon() {
+  if (m_reconRunning) {
+    const bool result = m_view->userConfirmation(
+        "Reconstruction is RUNNING",
+        "Are you sure you want to<br>cancel the running reconstruction?");
+
+    if (!result) {
+      // user clicked NO, so we don't terminate the running reconstruction and
+      // simply return
+      return false;
+    }
+    m_reconRunning = false;
+  }
+  return true;
 }
 
-void TomographyIfacePresenter::processRefreshJobs() {
-  // No need to be logged in, there can be local processes
-  if (m_model->loggedIn().empty()) {
-    m_model->doRefreshJobsInfo("Local");
-    m_view->updateJobsInfoDisplay(m_model->jobsStatus(),
-                                  m_model->jobsStatusLocal());
+void TomographyIfacePresenter::setupAndRunLocalReconstruction(
+    const std::string &runnable, const std::vector<std::string> &args,
+    const std::string &allOpts) {
+
+  if (!userConfirmationToCancelRecon()) {
+    // user didnt confirm
     return;
   }
 
-  // TODOPRES is this necessary? if we're logged in, we will never refresh the
-  // jobs for 'Local', also will need to be removed if more remote resources are
-  // added
-  std::string comp = m_view->currentComputeResource();
-  if (isLocalResourceSelected()) {
-    comp = "SCARF@STFC";
-  }
-  m_model->doRefreshJobsInfo(comp);
+  // this kills the previous thread forcefully
+  m_workerThread.reset();
+  auto *worker = new MantidQt::CustomInterfaces::TomographyProcess();
+  m_workerThread = Mantid::Kernel::make_unique<TomographyThread>(this, worker);
+
+  // we do this so the thread can independently read the process' output and
+  // only signal the presenter after it's done reading and has something to
+  // share so it doesn't block the presenter
+  connect(m_workerThread.get(), SIGNAL(stdOutReady(QString)), this,
+          SLOT(readWorkerStdOut(QString)));
+  connect(m_workerThread.get(), SIGNAL(stdErrReady(QString)), this,
+          SLOT(readWorkerStdErr(QString)));
+
+  // remove the user confirmation for running recon, if the recon has finished
+  connect(m_workerThread.get(), SIGNAL(workerFinished(qint64, int)), this,
+          SLOT(workerFinished(qint64, int)));
+
+  connect(worker, SIGNAL(started()), this, SLOT(addProcessToJobList()));
+
+  m_model->doLocalRunReconstructionJob(runnable, args, allOpts, *m_workerThread,
+                                       *worker);
+  m_reconRunning = true;
+}
+
+/** Simply reset the switch that tracks if a recon is running and
+ * update the process job in the reconstruction list
+ */
+void TomographyIfacePresenter::workerFinished(const qint64 pid,
+                                              const int exitCode) {
+  m_reconRunning = false;
+  m_model->updateProcessInJobList(pid, exitCode);
+  processRefreshJobs();
+}
+
+void TomographyIfacePresenter::reconProcessFailedToStart() {
+  m_view->userError("Reconstruction failed to start",
+                    "The reconstruction process has encountered an error and "
+                    "has failed to start.");
+}
+
+void TomographyIfacePresenter::addProcessToJobList() {
+  auto *worker = qobject_cast<TomographyProcess *>(sender());
+  const qint64 pid = worker->getPID();
+  const auto runnable = worker->getRunnable();
+  const auto args = worker->getArgs();
+
+  m_workerThread->setProcessPID(pid);
+
+  m_model->addJobToStatus(pid, runnable, args);
+  processRefreshJobs();
+}
+
+void TomographyIfacePresenter::readWorkerStdOut(const QString &s) {
+  m_model->logMsg(s.toStdString());
+}
+
+void TomographyIfacePresenter::readWorkerStdErr(const QString &s) {
+  m_model->logErrMsg(s.toStdString());
+}
+
+bool TomographyIfacePresenter::isLocalResourceSelected() const {
+  return m_model->localComputeResource() == m_view->currentComputeResource();
+}
+
+void TomographyIfacePresenter::processRefreshJobs() {
+  m_model->doRefreshJobsInfo(m_view->currentComputeResource());
 
   {
-    // update widgets from that info
     QMutexLocker lockit(m_statusMutex);
 
     m_view->updateJobsInfoDisplay(m_model->jobsStatus(),
@@ -594,11 +679,11 @@ void TomographyIfacePresenter::processRefreshJobs() {
 }
 
 void TomographyIfacePresenter::processCancelJobs() {
-  if (m_model->loggedIn().empty())
-    return;
-
   const std::string &resource = m_view->currentComputeResource();
-  if (!isLocalResourceSelected()) {
+  if (isLocalResourceSelected() && userConfirmationToCancelRecon()) {
+    // if local and user confirmed
+    m_workerThread.reset();
+  } else {
     m_model->doCancelJobs(resource, m_view->processingJobsIDs());
   }
 }
@@ -755,6 +840,11 @@ void TomographyIfacePresenter::startKeepAliveMechanism(int period) {
     return;
   }
 
+  // timer is already running, so return
+  if (m_keepAliveTimer) {
+    return;
+  }
+
   m_model->logMsg(
       "Tomography GUI: starting mechanism to periodically query the "
       "status of jobs. This will update the status of running jobs every " +
@@ -764,22 +854,19 @@ void TomographyIfacePresenter::startKeepAliveMechanism(int period) {
       "also expected to keep sessions on remote compute resources "
       "alive after logging in.");
 
-  if (m_keepAliveThread)
-    delete m_keepAliveThread;
-  QThread *m_keepAliveThread = new QThread();
-
   if (m_keepAliveTimer)
     delete m_keepAliveTimer;
-  m_keepAliveTimer = new QTimer(NULL); // no-parent so it can be moveToThread
+  m_keepAliveTimer = new QTimer(this); // no-parent so it can be moveToThread
 
   m_keepAliveTimer->setInterval(1000 * period); // interval in ms
-  m_keepAliveTimer->moveToThread(m_keepAliveThread);
-  // direct connection from the thread
-  connect(m_keepAliveTimer, SIGNAL(timeout()), SLOT(processRefreshJobs()),
-          Qt::DirectConnection);
-  QObject::connect(m_keepAliveThread, SIGNAL(started()), m_keepAliveTimer,
-                   SLOT(start()));
-  m_keepAliveThread->start();
+
+  // remove previous connections
+  m_keepAliveTimer->disconnect();
+
+  connect(m_keepAliveTimer, SIGNAL(timeout()), this,
+          SLOT(processRefreshJobs()));
+
+  m_keepAliveTimer->start();
 }
 
 void TomographyIfacePresenter::killKeepAliveMechanism() {
diff --git a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp
index 282736e9ab3d5c2766951136425302c5d2a8cc37..c445f51bc07df570c97ea90098d667e995af90bf 100644
--- a/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp
+++ b/MantidQt/CustomInterfaces/src/Tomography/TomographyIfaceViewQtGUI.cpp
@@ -1,4 +1,6 @@
+#include "MantidKernel/ConfigService.h"
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Run.h"
@@ -1355,11 +1357,13 @@ void TomographyIfaceViewQtGUI::browseLocalReconScriptsDirClicked() {
                      "Select location of scripts (scripts subdirectory/folder "
                      "in the Mantid installation",
                      false);
+  systemSettingsEdited();
 }
 
 void TomographyIfaceViewQtGUI::browseLocalExternalInterpreterClicked() {
   checkUserBrowseFile(m_uiTabSystemSettings.lineEdit_local_external_interpreter,
                       "Select interpreter executable", false);
+  systemSettingsEdited();
 }
 
 /**
@@ -1657,8 +1661,13 @@ TomographyIfaceViewQtGUI::grabSystemSettingsFromUser() const {
   setts.m_local.m_reconScriptsPath =
       m_uiTabSystemSettings.lineEdit_local_recon_scripts->text().toStdString();
 
+  setts.m_local.m_externalInterpreterPath =
+      m_uiTabSystemSettings.lineEdit_local_external_interpreter->text()
+          .toStdString();
+
   setts.m_experimentReference =
       m_uiTabRun.lineEdit_experiment_reference->text().toStdString();
+
   return setts;
 }
 
@@ -1910,19 +1919,33 @@ void TomographyIfaceViewQtGUI::systemSettingsNumericEdited() {
 }
 
 void TomographyIfaceViewQtGUI::resetSystemSettings() {
-  auto reply = QMessageBox::question(
-      this, "Reset Confirmation", "Are you sure you want to <br><strong>RESET "
-                                  "ALL</strong> System settings?<br>This "
-                                  "action cannot be undone!",
-      QMessageBox::Yes | QMessageBox::No);
+  const auto title = "Reset Confirmation";
+  const auto body = "Are you sure you want to <br><strong>RESET "
+                    "ALL</strong> System settings?<br>This "
+                    "action cannot be undone!";
   // default constructors with factory defaults
-  if (reply == QMessageBox::Yes) {
+  if (userConfirmation(title, body)) {
     // From factory defaults
     TomoSystemSettings defaults;
     updateSystemSettingsTabFields(defaults);
   }
 }
 
+/**
+ * Prompts the user for confirmation with a yes/no dialogue.
+ * The body can use HTML formatting.
+ *
+ * @param title The title that the message has
+ * @param body The body that the message has. This CAN use HTML formatting
+ */
+bool TomographyIfaceViewQtGUI::userConfirmation(const std::string &title,
+                                                const std::string &body) {
+  auto reply = QMessageBox::question(this, QString::fromStdString(title),
+                                     QString::fromStdString(body),
+                                     QMessageBox::Yes | QMessageBox::No);
+  return reply == QMessageBox::Yes;
+}
+
 /**
 * Show a warning message to the user (pop up)
 *
diff --git a/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h b/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h
index 1efbd884c1dfbaf628f6699e7fccfc771749095e..8a48efdc0d1f463602cd282be2a09f65a5bccad7 100644
--- a/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ALCPeakFittingPresenterTest.h
@@ -139,7 +139,7 @@ public:
   }
 
   void test_fitEmptyFunction() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
     ON_CALL(*m_view, function(QString("")))
         .WillByDefault(Return(IFunction_const_sptr()));
@@ -151,7 +151,7 @@ public:
   }
 
   void test_fit() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
 
     IFunction_sptr peaks = createGaussian(1, 2, 3);
@@ -166,7 +166,7 @@ public:
   }
 
   void test_onDataChanged() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
 
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
 
@@ -186,7 +186,7 @@ public:
     ON_CALL(*m_model, fittedPeaks())
         .WillByDefault(Return(createGaussian(1, 2, 3)));
 
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
 
     // TODO: check better
@@ -200,7 +200,7 @@ public:
     ON_CALL(*m_model, fittedPeaks())
         .WillByDefault(Return(IFunction_const_sptr()));
 
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
 
     EXPECT_CALL(*m_view, setFittedCurve(Property(&QwtData::size, 0)));
@@ -310,7 +310,7 @@ public:
    * Test that clicking "Plot guess" with no function set plots nothing
    */
   void test_plotGuess_noFunction() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
     ON_CALL(*m_view, function(QString("")))
         .WillByDefault(Return(IFunction_const_sptr()));
@@ -334,7 +334,7 @@ public:
    * Test that "Plot guess" with a function set plots a function
    */
   void test_plotGuess() {
-    auto ws = WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+    auto ws = WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     ON_CALL(*m_model, data()).WillByDefault(Return(ws));
     IFunction_sptr peaks = createGaussian(1, 2, 3);
     ON_CALL(*m_view, function(QString(""))).WillByDefault(Return(peaks));
diff --git a/MantidQt/CustomInterfaces/test/ImageROIPresenterTest.h b/MantidQt/CustomInterfaces/test/ImageROIPresenterTest.h
index e7a4db3c56b8abb409ac0067d878f343fbd5a727..852450bf411f86aef92c2a73eb93f7796aa9f4de 100644
--- a/MantidQt/CustomInterfaces/test/ImageROIPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ImageROIPresenterTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidQtCustomInterfaces/Tomography/ImageROIPresenter.h"
 #include "MantidTestHelpers/FakeObjects.h"
 
diff --git a/MantidQt/CustomInterfaces/test/MeasurementItemTest.h b/MantidQt/CustomInterfaces/test/MeasurementItemTest.h
index efd737ba924095c7387d9f3f3efb3f25822e278e..01527a6bc0344d5763166132d5d4ab0ca8279a6b 100644
--- a/MantidQt/CustomInterfaces/test/MeasurementItemTest.h
+++ b/MantidQt/CustomInterfaces/test/MeasurementItemTest.h
@@ -30,9 +30,11 @@ public:
     const std::string measurementType = "t";
     const double angle = 0.1;
     const std::string run = "123";
+    const std::string title = "title";
 
     MeasurementItem measurement(measurementId, measurementSubId,
-                                measurementLabel, measurementType, angle, run);
+                                measurementLabel, measurementType, angle, run,
+                                title);
 
     TS_ASSERT(measurement.isUseable());
     TS_ASSERT_EQUALS(measurementId, measurement.id());
@@ -46,7 +48,7 @@ public:
   void test_invalid_construction_when_measurementId_empty() {
 
     MeasurementItem measurement("", "measurementSubId", "measurementLabel",
-                                "measurementType", 0.1, "111");
+                                "measurementType", 0.1, "111", "title");
 
     TS_ASSERT(!measurement.isUseable());
   }
@@ -54,7 +56,7 @@ public:
   void test_invalid_construction_when_measurementSubId_empty() {
 
     MeasurementItem measurement("measurementId", "", "measurementLabel",
-                                "measurementType", 0.1, "111");
+                                "measurementType", 0.1, "111", "title");
 
     TS_ASSERT(!measurement.isUseable());
   }
@@ -62,17 +64,25 @@ public:
   void test_valid_construction_when_label_empty() {
 
     MeasurementItem measurement("measurementId", "measurementSubId", "",
-                                "measurementType", 0.1, "111");
+                                "measurementType", 0.1, "111", "title");
 
     TSM_ASSERT("Empty labels are not terminal", measurement.isUseable());
   }
 
   void test_valid_construction_when_type_empty() {
     MeasurementItem measurement("measurementId", "measurementSubId",
-                                "measurementLabel", "", 0.1, "111");
+                                "measurementLabel", "", 0.1, "111", "title");
 
     TSM_ASSERT("Empty type info is not terminal", measurement.isUseable());
   }
+
+  void test_valid_construction_when_title_empty() {
+    MeasurementItem measurement("measurementId", "measurementSubId",
+                                "measurementLabel", "measurementType", 0.1,
+                                "111", "");
+
+    TSM_ASSERT("Empty run title is not terminal", measurement.isUseable());
+  }
 };
 
 #endif /* MANTIDQT_CUSTOMINTERFACES_MEASUREMENTITEMTEST_H_ */
diff --git a/MantidQt/CustomInterfaces/test/MuonAnalysisHelperTest.h b/MantidQt/CustomInterfaces/test/MuonAnalysisHelperTest.h
index 6c7ac68b3a68eadb4221909f0b65c6b2eec3b32a..a99610cb87796108b85b2b51a6f64cb2fafd6195 100644
--- a/MantidQt/CustomInterfaces/test/MuonAnalysisHelperTest.h
+++ b/MantidQt/CustomInterfaces/test/MuonAnalysisHelperTest.h
@@ -11,6 +11,7 @@
 #include "MantidAPI/ScopedWorkspace.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/WorkspaceFactory.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidTestHelpers/WorkspaceCreationHelper.h"
@@ -124,11 +125,11 @@ public:
 
   void test_sumWorkspaces() {
     MatrixWorkspace_sptr ws1 =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     MatrixWorkspace_sptr ws2 =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     MatrixWorkspace_sptr ws3 =
-        WorkspaceCreationHelper::Create2DWorkspace123(1, 3);
+        WorkspaceCreationHelper::create2DWorkspace123(1, 3);
     DateAndTime start{"2015-12-23T15:32:40Z"};
     DateAndTime end{"2015-12-24T09:00:00Z"};
     addLog(ws1, "run_start", start.toSimpleString());
diff --git a/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h b/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h
index e01c9dd9ff2674bf21a08f4f211e446c12ed45e0..b24b560717714e2438467ebba8dbac31ef56fd16 100644
--- a/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflLegacyTransferStrategyTest.h
@@ -38,19 +38,21 @@ public:
 
     expectedRow[ReflTableSchema::RUNS] = "1234";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "0";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on gold";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1235";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "1";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on silver";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1236";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "2";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on bronze";
     expected.push_back(expectedRow);
 
+    std::sort(expected.begin(), expected.end());
+
     ReflLegacyTransferStrategy strategy;
 
     MockProgressBase progress;
@@ -74,19 +76,21 @@ public:
 
     expectedRow[ReflTableSchema::RUNS] = "1233";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "0";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on platinum";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1234+1235";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "1";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on gold";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1236";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "2";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on silver";
     expected.push_back(expectedRow);
 
+    std::sort(expected.begin(), expected.end());
+
     ReflLegacyTransferStrategy strategy;
 
     MockProgressBase progress;
@@ -112,22 +116,22 @@ public:
 
     expectedRow[ReflTableSchema::RUNS] = "1234";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "0";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on gold";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1235";
     expectedRow[ReflTableSchema::ANGLE] = "3.14";
-    expectedRow[ReflTableSchema::GROUP] = "1";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on silver in 3.14";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1236";
     expectedRow[ReflTableSchema::ANGLE] = "2.17";
-    expectedRow[ReflTableSchema::GROUP] = "2";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on bronze";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1237";
     expectedRow[ReflTableSchema::ANGLE] = "1.23";
-    expectedRow[ReflTableSchema::GROUP] = "3";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on platinum";
     expected.push_back(expectedRow);
 
     std::sort(expected.begin(), expected.end());
@@ -161,37 +165,37 @@ public:
 
     expectedRow[ReflTableSchema::RUNS] = "1230";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "0";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on gold";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1231+1232";
     expectedRow[ReflTableSchema::ANGLE] = "3.14";
-    expectedRow[ReflTableSchema::GROUP] = "1";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on silver in 3.14";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1233";
     expectedRow[ReflTableSchema::ANGLE] = "2.17";
-    expectedRow[ReflTableSchema::GROUP] = "1";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on silver in 3.14";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1234";
     expectedRow[ReflTableSchema::ANGLE] = "2.17";
-    expectedRow[ReflTableSchema::GROUP] = "2";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on bronze";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1235";
     expectedRow[ReflTableSchema::ANGLE] = "1.23";
-    expectedRow[ReflTableSchema::GROUP] = "2";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on bronze";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1236";
     expectedRow[ReflTableSchema::ANGLE] = "1.23";
-    expectedRow[ReflTableSchema::GROUP] = "3";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on platinum";
     expected.push_back(expectedRow);
 
     expectedRow[ReflTableSchema::RUNS] = "1237";
     expectedRow[ReflTableSchema::ANGLE] = "";
-    expectedRow[ReflTableSchema::GROUP] = "4";
+    expectedRow[ReflTableSchema::GROUP] = "fictitious run on fool's gold";
     expected.push_back(expectedRow);
 
     std::sort(expected.begin(), expected.end());
diff --git a/MantidQt/CustomInterfaces/test/ReflMainWindowPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflMainWindowPresenterTest.h
index 5bf6b733d278a65f8d4c7043b89e34c6dfba6438..2db4b1e775569aeb85d268f4532ccd67ce89669e 100644
--- a/MantidQt/CustomInterfaces/test/ReflMainWindowPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflMainWindowPresenterTest.h
@@ -36,9 +36,14 @@ public:
                                       &mockSettingsPresenter,
                                       &mockSaveTabPresenter);
 
-    EXPECT_CALL(mockSettingsPresenter, getTransmissionOptions())
+    EXPECT_CALL(mockSettingsPresenter, getTransmissionOptions(0))
         .Times(Exactly(1));
-    presenter.getTransmissionOptions();
+    presenter.getTransmissionOptions(0);
+
+    EXPECT_CALL(mockSettingsPresenter, getTransmissionOptions(1))
+        .Times(Exactly(1));
+    presenter.getTransmissionOptions(1);
+
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockSettingsPresenter));
   }
 
@@ -51,8 +56,14 @@ public:
                                       &mockSettingsPresenter,
                                       &mockSaveTabPresenter);
 
-    EXPECT_CALL(mockSettingsPresenter, getReductionOptions()).Times(Exactly(1));
-    presenter.getReductionOptions();
+    EXPECT_CALL(mockSettingsPresenter, getReductionOptions(0))
+        .Times(Exactly(1));
+    presenter.getReductionOptions(0);
+
+    EXPECT_CALL(mockSettingsPresenter, getReductionOptions(1))
+        .Times(Exactly(1));
+    presenter.getReductionOptions(1);
+
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockSettingsPresenter));
   }
 
@@ -65,8 +76,12 @@ public:
                                       &mockSettingsPresenter,
                                       &mockSaveTabPresenter);
 
-    EXPECT_CALL(mockSettingsPresenter, getStitchOptions()).Times(Exactly(1));
-    presenter.getStitchOptions();
+    EXPECT_CALL(mockSettingsPresenter, getStitchOptions(0)).Times(Exactly(1));
+    presenter.getStitchOptions(0);
+
+    EXPECT_CALL(mockSettingsPresenter, getStitchOptions(1)).Times(Exactly(1));
+    presenter.getStitchOptions(1);
+
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockSettingsPresenter));
   }
 
diff --git a/MantidQt/CustomInterfaces/test/ReflMeasureTransferStrategyTest.h b/MantidQt/CustomInterfaces/test/ReflMeasureTransferStrategyTest.h
index 85dc94244468eb72443e6b39f362ddae678dc2a5..54bcfb4b75b244d6fa158547a24dc9ccb0f84583 100644
--- a/MantidQt/CustomInterfaces/test/ReflMeasureTransferStrategyTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflMeasureTransferStrategyTest.h
@@ -52,7 +52,7 @@ public:
     EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
         .Times(Exactly(static_cast<int>(data.size())))
         .WillRepeatedly(
-            Return(MeasurementItem("a", "s_a", "l", "t", 0, "111")));
+            Return(MeasurementItem("a", "s_a", "l", "t", 0, "111", "title")));
 
     auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
     auto mockCatInfo_ptr = mockCatInfo.get();
@@ -95,9 +95,12 @@ public:
     // id
     EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
         .Times(Exactly(static_cast<int>(data.size())))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.1, "111")))
-        .WillOnce(Return(MeasurementItem("m1", "s2", "l1", "t1", 0.2, "122")))
-        .WillOnce(Return(MeasurementItem("m2", "s2", "l1", "t1", 0.2, "123")));
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.1, "111", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s2", "l1", "t1", 0.2, "122", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m2", "s2", "l1", "t1", 0.2, "123", "title")));
 
     auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
     auto mockCatInfo_ptr = mockCatInfo.get();
@@ -132,10 +135,14 @@ public:
     TSM_ASSERT_EQUALS("Group should be the same for first two rows",
                       successfulRuns[0][ReflTableSchema::GROUP],
                       successfulRuns[1][ReflTableSchema::GROUP]);
+    TSM_ASSERT_EQUALS("Group should be '0 - title' for first two rows",
+                      successfulRuns[0][ReflTableSchema::GROUP], "0 - title");
 
     TSM_ASSERT_DIFFERS("Group should be different for last rows",
                        successfulRuns[0][ReflTableSchema::GROUP],
                        successfulRuns[2][ReflTableSchema::GROUP]);
+    TSM_ASSERT_EQUALS("Group should be '1 - title' for third row",
+                      successfulRuns[2][ReflTableSchema::GROUP], "1 - title");
 
     TS_ASSERT(Mock::VerifyAndClear(mockCatInfo_ptr));
     TS_ASSERT(Mock::VerifyAndClear(mockMeasurementItemSource_ptr));
@@ -158,9 +165,12 @@ public:
     // We have 2 with valid measurement ids and 1 with no measurement id
     EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
         .Times(Exactly(static_cast<int>(data.size())))
-        .WillOnce(Return(MeasurementItem("", "s1", "l1", "t1", 0.1, "111")))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.2, "122")))
-        .WillOnce(Return(MeasurementItem("m1", "s2", "l1", "t1", 0.2, "123")));
+        .WillOnce(
+             Return(MeasurementItem("", "s1", "l1", "t1", 0.1, "111", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.2, "122", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s2", "l1", "t1", 0.2, "123", "title")));
 
     auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
     auto mockCatInfo_ptr = mockCatInfo.get();
@@ -219,9 +229,12 @@ public:
     // All 3 have same measurment id, but we also have 2 with same sub id.
     EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
         .Times(Exactly(static_cast<int>(data.size())))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.1, "111")))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.2, "122")))
-        .WillOnce(Return(MeasurementItem("m1", "s2", "l1", "t1", 0.2, "123")));
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.1, "111", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.2, "122", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s2", "l1", "t1", 0.2, "123", "title")));
 
     auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
     auto mockCatInfo_ptr = mockCatInfo.get();
@@ -257,6 +270,8 @@ public:
       TSM_ASSERT_EQUALS("All should have the same group",
                         successfulRuns[0][ReflTableSchema::GROUP],
                         successfulRuns[i][ReflTableSchema::GROUP]);
+      TSM_ASSERT_EQUALS("Group should be '0 - title'",
+                        successfulRuns[i][ReflTableSchema::GROUP], "0 - title");
     }
 
     TS_ASSERT(Mock::VerifyAndClear(mockCatInfo_ptr));
@@ -283,11 +298,14 @@ public:
     // All 3 have same measurment id, but we also have 2 with same sub id.
     EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
         .Times(Exactly(static_cast<int>(data.size())))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.1, "14913")))
-        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.1, "14914")))
-        .WillOnce(Return(MeasurementItem("m2", "s1", "l1", "t1", 0.2, "14915")))
-        .WillOnce(
-            Return(MeasurementItem("m2", "s1", "l1", "t1", 0.2, "14916")));
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.1, "14913", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m1", "s1", "l1", "t1", 0.1, "14914", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m2", "s1", "l1", "t1", 0.2, "14915", "title")))
+        .WillOnce(Return(
+            MeasurementItem("m2", "s1", "l1", "t1", 0.2, "14916", "title")));
 
     auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
     auto mockCatInfo_ptr = mockCatInfo.get();
@@ -319,6 +337,67 @@ public:
                       "14913+14914", successfulRuns[0][ReflTableSchema::RUNS]);
     TSM_ASSERT_EQUALS("Runs should be summed. Sub ids are the same.",
                       "14915+14916", successfulRuns[1][ReflTableSchema::RUNS]);
+    TSM_ASSERT_EQUALS("Group should be '0 - title'",
+                      successfulRuns[0][ReflTableSchema::GROUP], "0 - title");
+    TSM_ASSERT_EQUALS("Group should be '1 - title'",
+                      successfulRuns[1][ReflTableSchema::GROUP], "1 - title");
+
+    TS_ASSERT(Mock::VerifyAndClear(mockCatInfo_ptr));
+    TS_ASSERT(Mock::VerifyAndClear(mockMeasurementItemSource_ptr));
+  }
+
+  void test_same_id_but_different_title() {
+
+    SearchResultMap data;
+    data.insert(
+        std::make_pair<std::string, SearchResult>("14913", SearchResult()));
+    data.insert(
+        std::make_pair<std::string, SearchResult>("14914", SearchResult()));
+
+    auto mockMeasurementItemSource =
+        Mantid::Kernel::make_unique<MockReflMeasurementItemSource>();
+    auto mockMeasurementItemSource_ptr = mockMeasurementItemSource.get();
+
+    // Same measurment id but different title
+    EXPECT_CALL(*mockMeasurementItemSource, obtain(_, _))
+        .Times(Exactly(static_cast<int>(data.size())))
+        .WillOnce(Return(MeasurementItem("m1", "s1", "l1", "t1", 0.1, "14913",
+                                         "Sample 1 H=0.10")))
+        .WillOnce(Return(MeasurementItem("m1", "s2", "l1", "t1", 0.1, "14914",
+                                         "Sample 1 H=0.09")));
+
+    auto mockCatInfo = Mantid::Kernel::make_unique<MockICatalogInfo>();
+    auto mockCatInfo_ptr = mockCatInfo.get();
+    // We expect that every location will be translated/transformed to make it
+    // os specific
+    EXPECT_CALL(*mockCatInfo, transformArchivePath(_))
+        .Times(Exactly(static_cast<int>(data.size())))
+        .WillRepeatedly(Return(std::string()));
+
+    MockProgressBase progress;
+    // Expect a progress update
+    EXPECT_CALL(progress, doReport(_))
+        .Times(Exactly(static_cast<int>(data.size())));
+
+    // Make the transfer stragegy
+    ReflMeasureTransferStrategy strategy(std::move(mockCatInfo),
+                                         std::move(mockMeasurementItemSource));
+
+    // Do the transfer
+    auto transferResult = strategy.transferRuns(data, progress);
+    auto successfulRuns = transferResult.getTransferRuns();
+
+    // Check the transfer entries
+    TSM_ASSERT_EQUALS("Should have two rows", 2, successfulRuns.size());
+    TSM_ASSERT_DIFFERS("Runs should be the different for both columns",
+                       successfulRuns[0][ReflTableSchema::RUNS],
+                       successfulRuns[1][ReflTableSchema::RUNS]);
+    TSM_ASSERT_EQUALS("Group should be '0 - Sample 1 H=0.10'",
+                      successfulRuns[0][ReflTableSchema::GROUP],
+                      "0 - Sample 1 H=0.10");
+    TSM_ASSERT_EQUALS("Group should be '0 - Sample 1 H=0.10'",
+                      successfulRuns[1][ReflTableSchema::GROUP],
+                      "0 - Sample 1 H=0.10");
 
     TS_ASSERT(Mock::VerifyAndClear(mockCatInfo_ptr));
     TS_ASSERT(Mock::VerifyAndClear(mockMeasurementItemSource_ptr));
diff --git a/MantidQt/CustomInterfaces/test/ReflMockObjects.h b/MantidQt/CustomInterfaces/test/ReflMockObjects.h
index 0473e7b5614fd100f4d3b25299f21bb4edbb7f99..54c76710396d004e918e1cf6c12ba732a33c04b6 100644
--- a/MantidQt/CustomInterfaces/test/ReflMockObjects.h
+++ b/MantidQt/CustomInterfaces/test/ReflMockObjects.h
@@ -8,8 +8,9 @@
 #include "MantidQtCustomInterfaces/Reflectometry/IReflMainWindowView.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflRunsTabPresenter.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflRunsTabView.h"
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsPresenter.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabPresenter.h"
-#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsTabView.h"
+#include "MantidQtCustomInterfaces/Reflectometry/IReflSettingsView.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflSaveTabView.h"
 #include "MantidQtCustomInterfaces/Reflectometry/IReflSaveTabPresenter.h"
 #include "MantidQtCustomInterfaces/Reflectometry/ReflSearchModel.h"
@@ -51,6 +52,7 @@ public:
   MOCK_CONST_METHOD0(getTransferMethod, std::string());
   MOCK_CONST_METHOD0(getAlgorithmRunner,
                      boost::shared_ptr<MantidQt::API::AlgorithmRunner>());
+  MOCK_CONST_METHOD0(getSelectedGroup, int());
   MOCK_METHOD1(setTransferMethods, void(const std::set<std::string> &));
   MOCK_METHOD0(setTableCommandsProxy, void());
   MOCK_METHOD0(setRowCommandsProxy, void());
@@ -60,10 +62,10 @@ public:
 
   // Calls we don't care about
   void showSearch(ReflSearchModel_sptr) override{};
-  IReflRunsTabPresenter *getPresenter() const override { return nullptr; }
+  IReflRunsTabPresenter *getPresenter() const override { return nullptr; };
 };
 
-class MockSettingsTabView : public IReflSettingsTabView {
+class MockSettingsView : public IReflSettingsView {
 public:
   // Global options
   MOCK_CONST_METHOD0(getTransmissionOptions, std::string());
@@ -96,7 +98,7 @@ public:
   createStitchHints(const std::map<std::string, std::string> &hints) override {
     UNUSED_ARG(hints);
   };
-  IReflSettingsTabPresenter *getPresenter() const override { return nullptr; }
+  IReflSettingsPresenter *getPresenter() const override { return nullptr; }
 };
 
 class MockSaveTabView : public IReflSaveTabView {
@@ -147,21 +149,24 @@ public:
   ~MockRunsTabPresenter() override{};
 };
 
-class MockSettingsTabPresenter : public IReflSettingsTabPresenter {
+class MockSettingsPresenter : public IReflSettingsPresenter {
 public:
   MOCK_CONST_METHOD0(getTransmissionOptions, std::string());
   MOCK_CONST_METHOD0(getReductionOptions, std::string());
   MOCK_CONST_METHOD0(getStitchOptions, std::string());
-  // Other calls we don't care about
-  void acceptMainPresenter(IReflMainWindowPresenter *presenter) override {
-    UNUSED_ARG(presenter);
-  };
-  void notify(IReflSettingsTabPresenter::Flag flag) override {
-    UNUSED_ARG(flag);
-  };
-  void setInstrumentName(const std::string instName) override {
+  MOCK_METHOD1(setInstrumentName, void(const std::string &));
+  void notify(IReflSettingsPresenter::Flag flag) override { UNUSED_ARG(flag); }
+  ~MockSettingsPresenter() override{};
+};
+
+class MockSettingsTabPresenter : public IReflSettingsTabPresenter {
+public:
+  MOCK_CONST_METHOD1(getTransmissionOptions, std::string(int));
+  MOCK_CONST_METHOD1(getReductionOptions, std::string(int));
+  MOCK_CONST_METHOD1(getStitchOptions, std::string(int));
+  void setInstrumentName(const std::string &instName) override {
     UNUSED_ARG(instName);
-  }
+  };
   ~MockSettingsTabPresenter() override{};
 };
 
@@ -176,9 +181,9 @@ public:
 
 class MockMainWindowPresenter : public IReflMainWindowPresenter {
 public:
-  MOCK_CONST_METHOD0(getTransmissionOptions, std::string());
-  MOCK_CONST_METHOD0(getReductionOptions, std::string());
-  MOCK_CONST_METHOD0(getStitchOptions, std::string());
+  MOCK_CONST_METHOD1(getTransmissionOptions, std::string(int));
+  MOCK_CONST_METHOD1(getReductionOptions, std::string(int));
+  MOCK_CONST_METHOD1(getStitchOptions, std::string(int));
   MOCK_CONST_METHOD0(getInstrumentName, std::string());
   MOCK_METHOD3(askUserString,
                std::string(const std::string &, const std::string &,
diff --git a/MantidQt/CustomInterfaces/test/ReflRunsTabPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflRunsTabPresenterTest.h
index f42429c643fba381bfd9788a03c95b336b757cf5..b462c0d0237733ea26d3af46a493e6e38e7d180a 100644
--- a/MantidQt/CustomInterfaces/test/ReflRunsTabPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflRunsTabPresenterTest.h
@@ -32,11 +32,9 @@ public:
   void test_constructor_sets_possible_transfer_methods() {
     NiceMock<MockRunsTabView> mockRunsTabView;
     MockProgressableView mockProgress;
-    MockDataProcessorPresenter mockTablePresenter;
-
-    // Expect that the table presenter accepts this presenter as a workspace
-    // receiver
-    EXPECT_CALL(mockTablePresenter, accept(_)).Times(Exactly(1));
+    NiceMock<MockDataProcessorPresenter> mockTablePresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
 
     // Expect that the transfer methods get initialized on the view
     EXPECT_CALL(mockRunsTabView, setTransferMethods(_)).Times(Exactly(1));
@@ -45,20 +43,50 @@ public:
 
     // Constructor
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
 
     // Verify expectations
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockRunsTabView));
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter));
   }
 
-  void test_presenter_sets_commands_when_notified() {
+  void test_table_presenters_accept_this_presenter() {
+    NiceMock<MockRunsTabView> mockRunsTabView;
+    MockProgressableView mockProgress;
+    MockDataProcessorPresenter mockTablePresenter_1;
+    MockDataProcessorPresenter mockTablePresenter_2;
+    MockDataProcessorPresenter mockTablePresenter_3;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter_1);
+    tablePresenterVec.push_back(&mockTablePresenter_2);
+    tablePresenterVec.push_back(&mockTablePresenter_3);
+
+    // Expect that the table presenters accept this presenter as a workspace
+    // receiver
+    EXPECT_CALL(mockTablePresenter_1, accept(_)).Times(Exactly(1));
+    EXPECT_CALL(mockTablePresenter_2, accept(_)).Times(Exactly(1));
+    EXPECT_CALL(mockTablePresenter_3, accept(_)).Times(Exactly(1));
+
+    // Constructor
+    ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
+                                   tablePresenterVec);
+
+    // Verify expectations
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockRunsTabView));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_2));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_3));
+  }
+
+  void test_presenter_sets_commands_when_ADS_changed() {
     NiceMock<MockRunsTabView> mockRunsTabView;
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
 
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
 
     // Expect that the view clears the list of commands
     EXPECT_CALL(mockRunsTabView, clearCommands()).Times(Exactly(1));
@@ -78,8 +106,11 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
+
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
     EXPECT_CALL(mockMainPresenter,
@@ -94,8 +125,10 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
     EXPECT_CALL(mockMainPresenter, askUserYesNo("Prompt", "Title")).Times(1);
@@ -109,8 +142,10 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
     EXPECT_CALL(mockMainPresenter, giveUserWarning("Prompt", "Warning Message"))
@@ -125,8 +160,10 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
     EXPECT_CALL(mockMainPresenter,
@@ -141,8 +178,10 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
     EXPECT_CALL(mockMainPresenter, runPythonAlgorithm("Python code to run"))
@@ -157,14 +196,21 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
-    EXPECT_CALL(mockMainPresenter, getTransmissionOptions()).Times(1);
+    int group = 199;
+    EXPECT_CALL(mockRunsTabView, getSelectedGroup())
+        .Times(Exactly(1))
+        .WillOnce(Return(group));
+    EXPECT_CALL(mockMainPresenter, getTransmissionOptions(group)).Times(1);
     presenter.getPreprocessingOptions();
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockMainPresenter));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockRunsTabView));
   }
 
   void test_processingOptions() {
@@ -172,14 +218,21 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
-    EXPECT_CALL(mockMainPresenter, getReductionOptions()).Times(1);
+    int group = 199;
+    EXPECT_CALL(mockRunsTabView, getSelectedGroup())
+        .Times(Exactly(1))
+        .WillOnce(Return(group));
+    EXPECT_CALL(mockMainPresenter, getReductionOptions(group)).Times(1);
     presenter.getProcessingOptions();
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockMainPresenter));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockRunsTabView));
   }
 
   void test_postprocessingOptions() {
@@ -187,14 +240,52 @@ public:
     MockProgressableView mockProgress;
     NiceMock<MockDataProcessorPresenter> mockTablePresenter;
     MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter);
     ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
-                                   &mockTablePresenter);
+                                   tablePresenterVec);
     presenter.acceptMainPresenter(&mockMainPresenter);
 
-    EXPECT_CALL(mockMainPresenter, getStitchOptions()).Times(1);
+    int group = 199;
+    EXPECT_CALL(mockRunsTabView, getSelectedGroup())
+        .Times(Exactly(1))
+        .WillOnce(Return(group));
+    EXPECT_CALL(mockMainPresenter, getStitchOptions(group)).Times(1);
     presenter.getPostprocessingOptions();
 
     TS_ASSERT(Mock::VerifyAndClearExpectations(&mockMainPresenter));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockRunsTabView));
+  }
+
+  void test_when_group_changes_commands_are_updated() {
+    NiceMock<MockRunsTabView> mockRunsTabView;
+    MockProgressableView mockProgress;
+    NiceMock<MockDataProcessorPresenter> mockTablePresenter_0;
+    NiceMock<MockDataProcessorPresenter> mockTablePresenter_1;
+    NiceMock<MockDataProcessorPresenter> mockTablePresenter_2;
+    MockMainWindowPresenter mockMainPresenter;
+    std::vector<DataProcessorPresenter *> tablePresenterVec;
+    tablePresenterVec.push_back(&mockTablePresenter_0);
+    tablePresenterVec.push_back(&mockTablePresenter_1);
+    tablePresenterVec.push_back(&mockTablePresenter_2);
+
+    ReflRunsTabPresenter presenter(&mockRunsTabView, &mockProgress,
+                                   tablePresenterVec);
+    presenter.acceptMainPresenter(&mockMainPresenter);
+
+    EXPECT_CALL(mockRunsTabView, getSelectedGroup())
+        .Times(Exactly(1))
+        .WillOnce(Return(1));
+    // Commands should be updated with presenter of selected group
+    EXPECT_CALL(mockTablePresenter_0, publishCommandsMocked()).Times(0);
+    EXPECT_CALL(mockTablePresenter_1, publishCommandsMocked()).Times(1);
+    EXPECT_CALL(mockTablePresenter_2, publishCommandsMocked()).Times(0);
+    presenter.notify(IReflRunsTabPresenter::GroupChangedFlag);
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockMainPresenter));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockTablePresenter_2));
   }
 };
 
diff --git a/MantidQt/CustomInterfaces/test/ReflSaveTabPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflSaveTabPresenterTest.h
index 631075acdf52fb078ea06554835904851e625082..b56f370f55f0286bc1f4f90d300f3b5de1b7db02 100644
--- a/MantidQt/CustomInterfaces/test/ReflSaveTabPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflSaveTabPresenterTest.h
@@ -209,7 +209,7 @@ public:
 
 private:
   void createWS(std::string name) {
-    Workspace2D_sptr ws = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    Workspace2D_sptr ws = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().addOrReplace(name, ws);
   }
 
diff --git a/MantidQt/CustomInterfaces/test/ReflSettingsPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflSettingsPresenterTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f2335622db0455a2fc6a0e5006a47ffb741645b
--- /dev/null
+++ b/MantidQt/CustomInterfaces/test/ReflSettingsPresenterTest.h
@@ -0,0 +1,245 @@
+#ifndef MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTERTEST_H
+#define MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTERTEST_H
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/FrameworkManager.h"
+#include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsPresenter.h"
+#include "ReflMockObjects.h"
+#include <boost/algorithm/string.hpp>
+
+using namespace MantidQt::CustomInterfaces;
+using namespace testing;
+
+namespace {
+class split_q {
+private:
+  mutable bool in_q;
+
+public:
+  split_q() : in_q(false) {}
+  bool operator()(char c) const {
+    if (c == '\"')
+      in_q = !in_q;
+    return !in_q && c == ',';
+  }
+};
+}
+
+//=====================================================================================
+// Functional tests
+//=====================================================================================
+class ReflSettingsPresenterTest : 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 ReflSettingsPresenterTest *createSuite() {
+    return new ReflSettingsPresenterTest();
+  }
+  static void destroySuite(ReflSettingsPresenterTest *suite) { delete suite; }
+
+  ReflSettingsPresenterTest() { FrameworkManager::Instance(); }
+
+  void testGetTransmissionOptions() {
+    MockSettingsView mockView;
+    ReflSettingsPresenter presenter(&mockView);
+
+    EXPECT_CALL(mockView, getAnalysisMode())
+        .Times(Exactly(1))
+        .WillOnce(Return("MultiDetectorAnalysis"));
+    EXPECT_CALL(mockView, getMonitorIntegralMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("4"));
+    EXPECT_CALL(mockView, getMonitorIntegralMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("10"));
+    EXPECT_CALL(mockView, getMonitorBackgroundMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("12"));
+    EXPECT_CALL(mockView, getMonitorBackgroundMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("17"));
+    EXPECT_CALL(mockView, getLambdaMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("1"));
+    EXPECT_CALL(mockView, getLambdaMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("15"));
+    EXPECT_CALL(mockView, getI0MonitorIndex())
+        .Times(Exactly(1))
+        .WillOnce(Return("2"));
+    EXPECT_CALL(mockView, getProcessingInstructions())
+        .Times(Exactly(1))
+        .WillOnce(Return("\"3,4\""));
+    auto options = presenter.getTransmissionOptions();
+
+    std::vector<std::string> optionsVec;
+    boost::split(optionsVec, options, split_q());
+    TS_ASSERT_EQUALS(optionsVec[0], "AnalysisMode=MultiDetectorAnalysis");
+    TS_ASSERT_EQUALS(optionsVec[1], "MonitorIntegrationWavelengthMin=4");
+    TS_ASSERT_EQUALS(optionsVec[2], "MonitorIntegrationWavelengthMax=10");
+    TS_ASSERT_EQUALS(optionsVec[3], "MonitorBackgroundWavelengthMin=12");
+    TS_ASSERT_EQUALS(optionsVec[4], "MonitorBackgroundWavelengthMax=17");
+    TS_ASSERT_EQUALS(optionsVec[5], "WavelengthMin=1");
+    TS_ASSERT_EQUALS(optionsVec[6], "WavelengthMax=15");
+    TS_ASSERT_EQUALS(optionsVec[7], "I0MonitorIndex=2");
+    TS_ASSERT_EQUALS(optionsVec[8], "ProcessingInstructions=\"3,4\"");
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  }
+
+  void testGetReductionOptions() {
+    MockSettingsView mockView;
+    ReflSettingsPresenter presenter(&mockView);
+
+    EXPECT_CALL(mockView, getAnalysisMode())
+        .Times(Exactly(1))
+        .WillOnce(Return("MultiDetectorAnalysis"));
+    EXPECT_CALL(mockView, getCRho()).Times(Exactly(1)).WillOnce(Return("2.5"));
+    EXPECT_CALL(mockView, getCAlpha())
+        .Times(Exactly(1))
+        .WillOnce(Return("0.6"));
+    EXPECT_CALL(mockView, getCAp()).Times(Exactly(1)).WillOnce(Return("100.0"));
+    EXPECT_CALL(mockView, getCPp()).Times(Exactly(1)).WillOnce(Return("0.54"));
+    EXPECT_CALL(mockView, getDirectBeam())
+        .Times(Exactly(1))
+        .WillOnce(Return("\"0,3\""));
+    EXPECT_CALL(mockView, getPolarisationCorrections())
+        .Times(Exactly(1))
+        .WillOnce(Return("PNR"));
+    EXPECT_CALL(mockView, getIntMonCheck())
+        .Times(Exactly(1))
+        .WillOnce(Return("True"));
+    EXPECT_CALL(mockView, getMonitorIntegralMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("4"));
+    EXPECT_CALL(mockView, getMonitorIntegralMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("10"));
+    EXPECT_CALL(mockView, getMonitorBackgroundMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("12"));
+    EXPECT_CALL(mockView, getMonitorBackgroundMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("17"));
+    EXPECT_CALL(mockView, getLambdaMin())
+        .Times(Exactly(1))
+        .WillOnce(Return("1"));
+    EXPECT_CALL(mockView, getLambdaMax())
+        .Times(Exactly(1))
+        .WillOnce(Return("15"));
+    EXPECT_CALL(mockView, getI0MonitorIndex())
+        .Times(Exactly(1))
+        .WillOnce(Return("2"));
+    EXPECT_CALL(mockView, getScaleFactor())
+        .Times(Exactly(1))
+        .WillOnce(Return("2"));
+    EXPECT_CALL(mockView, getMomentumTransferStep())
+        .Times(Exactly(1))
+        .WillOnce(Return("-0.02"));
+    EXPECT_CALL(mockView, getProcessingInstructions())
+        .Times(Exactly(1))
+        .WillOnce(Return("\"3,4\""));
+    EXPECT_CALL(mockView, getTransmissionRuns())
+        .Times(Exactly(1))
+        .WillOnce(Return("INTER00013463,INTER00013464"));
+    auto options = presenter.getReductionOptions();
+
+    std::vector<std::string> optionsVec;
+    boost::split(optionsVec, options, split_q());
+    TS_ASSERT_EQUALS(optionsVec[0], "AnalysisMode=MultiDetectorAnalysis");
+    TS_ASSERT_EQUALS(optionsVec[1], "CRho=2.5");
+    TS_ASSERT_EQUALS(optionsVec[2], "CAlpha=0.6");
+    TS_ASSERT_EQUALS(optionsVec[3], "CAp=100.0");
+    TS_ASSERT_EQUALS(optionsVec[4], "CPp=0.54");
+    TS_ASSERT_EQUALS(optionsVec[5], "RegionOfDirectBeam=\"0,3\"");
+    TS_ASSERT_EQUALS(optionsVec[6], "PolarizationAnalysis=PNR");
+    TS_ASSERT_EQUALS(optionsVec[7], "NormalizeByIntegratedMonitors=True");
+    TS_ASSERT_EQUALS(optionsVec[8], "MonitorIntegrationWavelengthMin=4");
+    TS_ASSERT_EQUALS(optionsVec[9], "MonitorIntegrationWavelengthMax=10");
+    TS_ASSERT_EQUALS(optionsVec[10], "MonitorBackgroundWavelengthMin=12");
+    TS_ASSERT_EQUALS(optionsVec[11], "MonitorBackgroundWavelengthMax=17");
+    TS_ASSERT_EQUALS(optionsVec[12], "WavelengthMin=1");
+    TS_ASSERT_EQUALS(optionsVec[13], "WavelengthMax=15");
+    TS_ASSERT_EQUALS(optionsVec[14], "I0MonitorIndex=2");
+    TS_ASSERT_EQUALS(optionsVec[15], "ScaleFactor=2");
+    TS_ASSERT_EQUALS(optionsVec[16], "MomentumTransferStep=-0.02");
+    TS_ASSERT_EQUALS(optionsVec[17], "ProcessingInstructions=\"3,4\"");
+    TS_ASSERT_EQUALS(optionsVec[18],
+                     "FirstTransmissionRun=TRANS_INTER00013463");
+    TS_ASSERT_EQUALS(optionsVec[19],
+                     "SecondTransmissionRun=TRANS_INTER00013464");
+
+    TS_ASSERT(AnalysisDataService::Instance().doesExist("TRANS_INTER00013463"));
+    TS_ASSERT(AnalysisDataService::Instance().doesExist("TRANS_INTER00013464"));
+    AnalysisDataService::Instance().clear();
+
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  }
+
+  void testStitchOptions() {
+    MockSettingsView mockView;
+    ReflSettingsPresenter presenter(&mockView);
+
+    EXPECT_CALL(mockView, getStitchOptions()).Times(Exactly(1));
+    presenter.getStitchOptions();
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  }
+
+  void testPolarisationOptionsEnabled() {
+    MockSettingsView mockView;
+    ReflSettingsPresenter presenter(&mockView);
+
+    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(false))
+        .Times(Exactly(1));
+    presenter.setInstrumentName("INTER");
+    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(true))
+        .Times(Exactly(1));
+    presenter.setInstrumentName("POLREF");
+  }
+
+  void testExperimentDefaults() {
+    MockSettingsView mockView;
+    ReflSettingsPresenter presenter(&mockView);
+    MockMainWindowPresenter mainPresenter;
+
+    // Set instrument to 'POLREF'
+    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(true))
+        .Times(Exactly(1));
+    presenter.setInstrumentName("POLREF");
+
+    std::vector<std::string> defaults = {
+        "PointDetectorAnalysis", "None",
+        "1.006831,-0.011467,0.002244,-0.000095",
+        "1.017526,-0.017183,0.003136,-0.000140",
+        "0.917940,0.038265,-0.006645,0.000282",
+        "0.972762,0.001828,-0.000261,0.0", "1"};
+
+    EXPECT_CALL(mockView, setExpDefaults(defaults)).Times(1);
+    presenter.notify(IReflSettingsPresenter::ExpDefaultsFlag);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  }
+
+  void testInstrumentDefaults() {
+    MockSettingsView mockView;
+    MockMainWindowPresenter mainPresenter;
+    ReflSettingsPresenter presenter(&mockView);
+
+    // Set instrument to 'INTER'
+    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(false))
+        .Times(Exactly(1));
+    presenter.setInstrumentName("INTER");
+
+    std::vector<double> defaults = {1., 4.0, 10., 15., 17., 1.0, 17., 2.0};
+
+    EXPECT_CALL(mockView, setInstDefaults(defaults)).Times(1);
+    presenter.notify(IReflSettingsPresenter::InstDefaultsFlag);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  }
+};
+
+#endif /* MANTID_CUSTOMINTERFACES_REFLSETTINGSPRESENTERTEST_H */
diff --git a/MantidQt/CustomInterfaces/test/ReflSettingsTabPresenterTest.h b/MantidQt/CustomInterfaces/test/ReflSettingsTabPresenterTest.h
index 992c5a7d530edac9c9ced79cf607c85d797fd9ca..8390fc7248d85a5e47a5caab038539f782ea8337 100644
--- a/MantidQt/CustomInterfaces/test/ReflSettingsTabPresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/ReflSettingsTabPresenterTest.h
@@ -4,7 +4,9 @@
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
+#include <boost/algorithm/string.hpp>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidQtCustomInterfaces/Reflectometry/ReflSettingsTabPresenter.h"
 #include "ReflMockObjects.h"
@@ -12,21 +14,6 @@
 using namespace MantidQt::CustomInterfaces;
 using namespace testing;
 
-namespace {
-class split_q {
-private:
-  mutable bool in_q;
-
-public:
-  split_q() : in_q(false) {}
-  bool operator()(char c) const {
-    if (c == '\"')
-      in_q = !in_q;
-    return !in_q && c == ',';
-  }
-};
-}
-
 //=====================================================================================
 // Functional tests
 //=====================================================================================
@@ -44,207 +31,131 @@ public:
 
   ReflSettingsTabPresenterTest() { FrameworkManager::Instance(); }
 
-  void testGetTransmissionOptions() {
-    MockSettingsTabView mockView;
-    ReflSettingsTabPresenter presenter(&mockView);
-
-    EXPECT_CALL(mockView, getAnalysisMode())
-        .Times(Exactly(1))
-        .WillOnce(Return("MultiDetectorAnalysis"));
-    EXPECT_CALL(mockView, getMonitorIntegralMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("4"));
-    EXPECT_CALL(mockView, getMonitorIntegralMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("10"));
-    EXPECT_CALL(mockView, getMonitorBackgroundMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("12"));
-    EXPECT_CALL(mockView, getMonitorBackgroundMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("17"));
-    EXPECT_CALL(mockView, getLambdaMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("1"));
-    EXPECT_CALL(mockView, getLambdaMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("15"));
-    EXPECT_CALL(mockView, getI0MonitorIndex())
-        .Times(Exactly(1))
-        .WillOnce(Return("2"));
-    EXPECT_CALL(mockView, getProcessingInstructions())
-        .Times(Exactly(1))
-        .WillOnce(Return("\"3,4\""));
-    auto options = presenter.getTransmissionOptions();
-
-    std::vector<std::string> optionsVec;
-    boost::split(optionsVec, options, split_q());
-    TS_ASSERT_EQUALS(optionsVec[0], "AnalysisMode=MultiDetectorAnalysis");
-    TS_ASSERT_EQUALS(optionsVec[1], "MonitorIntegrationWavelengthMin=4");
-    TS_ASSERT_EQUALS(optionsVec[2], "MonitorIntegrationWavelengthMax=10");
-    TS_ASSERT_EQUALS(optionsVec[3], "MonitorBackgroundWavelengthMin=12");
-    TS_ASSERT_EQUALS(optionsVec[4], "MonitorBackgroundWavelengthMax=17");
-    TS_ASSERT_EQUALS(optionsVec[5], "WavelengthMin=1");
-    TS_ASSERT_EQUALS(optionsVec[6], "WavelengthMax=15");
-    TS_ASSERT_EQUALS(optionsVec[7], "I0MonitorIndex=2");
-    TS_ASSERT_EQUALS(optionsVec[8], "ProcessingInstructions=\"3,4\"");
-
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
-  }
+  void test_instrument_name() {
+    MockSettingsPresenter presenter_1;
+    MockSettingsPresenter presenter_2;
+    std::vector<IReflSettingsPresenter *> settingsPresenters;
+    settingsPresenters.push_back(&presenter_1);
+    settingsPresenters.push_back(&presenter_2);
+    ReflSettingsTabPresenter presenter(settingsPresenters);
 
-  void testGetReductionOptions() {
-    MockSettingsTabView mockView;
-    ReflSettingsTabPresenter presenter(&mockView);
-
-    EXPECT_CALL(mockView, getAnalysisMode())
-        .Times(Exactly(1))
-        .WillOnce(Return("MultiDetectorAnalysis"));
-    EXPECT_CALL(mockView, getCRho()).Times(Exactly(1)).WillOnce(Return("2.5"));
-    EXPECT_CALL(mockView, getCAlpha())
-        .Times(Exactly(1))
-        .WillOnce(Return("0.6"));
-    EXPECT_CALL(mockView, getCAp()).Times(Exactly(1)).WillOnce(Return("100.0"));
-    EXPECT_CALL(mockView, getCPp()).Times(Exactly(1)).WillOnce(Return("0.54"));
-    EXPECT_CALL(mockView, getDirectBeam())
-        .Times(Exactly(1))
-        .WillOnce(Return("\"0,3\""));
-    EXPECT_CALL(mockView, getPolarisationCorrections())
-        .Times(Exactly(1))
-        .WillOnce(Return("PNR"));
-    EXPECT_CALL(mockView, getIntMonCheck())
-        .Times(Exactly(1))
-        .WillOnce(Return("True"));
-    EXPECT_CALL(mockView, getMonitorIntegralMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("4"));
-    EXPECT_CALL(mockView, getMonitorIntegralMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("10"));
-    EXPECT_CALL(mockView, getMonitorBackgroundMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("12"));
-    EXPECT_CALL(mockView, getMonitorBackgroundMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("17"));
-    EXPECT_CALL(mockView, getLambdaMin())
-        .Times(Exactly(1))
-        .WillOnce(Return("1"));
-    EXPECT_CALL(mockView, getLambdaMax())
-        .Times(Exactly(1))
-        .WillOnce(Return("15"));
-    EXPECT_CALL(mockView, getI0MonitorIndex())
-        .Times(Exactly(1))
-        .WillOnce(Return("2"));
-    EXPECT_CALL(mockView, getScaleFactor())
-        .Times(Exactly(1))
-        .WillOnce(Return("2"));
-    EXPECT_CALL(mockView, getMomentumTransferStep())
-        .Times(Exactly(1))
-        .WillOnce(Return("-0.02"));
-    EXPECT_CALL(mockView, getProcessingInstructions())
-        .Times(Exactly(1))
-        .WillOnce(Return("\"3,4\""));
-    EXPECT_CALL(mockView, getTransmissionRuns())
-        .Times(Exactly(1))
-        .WillOnce(Return("INTER00013463,INTER00013464"));
-    auto options = presenter.getReductionOptions();
-
-    std::vector<std::string> optionsVec;
-    boost::split(optionsVec, options, split_q());
-    TS_ASSERT_EQUALS(optionsVec[0], "AnalysisMode=MultiDetectorAnalysis");
-    TS_ASSERT_EQUALS(optionsVec[1], "CRho=2.5");
-    TS_ASSERT_EQUALS(optionsVec[2], "CAlpha=0.6");
-    TS_ASSERT_EQUALS(optionsVec[3], "CAp=100.0");
-    TS_ASSERT_EQUALS(optionsVec[4], "CPp=0.54");
-    TS_ASSERT_EQUALS(optionsVec[5], "RegionOfDirectBeam=\"0,3\"");
-    TS_ASSERT_EQUALS(optionsVec[6], "PolarizationAnalysis=PNR");
-    TS_ASSERT_EQUALS(optionsVec[7], "NormalizeByIntegratedMonitors=True");
-    TS_ASSERT_EQUALS(optionsVec[8], "MonitorIntegrationWavelengthMin=4");
-    TS_ASSERT_EQUALS(optionsVec[9], "MonitorIntegrationWavelengthMax=10");
-    TS_ASSERT_EQUALS(optionsVec[10], "MonitorBackgroundWavelengthMin=12");
-    TS_ASSERT_EQUALS(optionsVec[11], "MonitorBackgroundWavelengthMax=17");
-    TS_ASSERT_EQUALS(optionsVec[12], "WavelengthMin=1");
-    TS_ASSERT_EQUALS(optionsVec[13], "WavelengthMax=15");
-    TS_ASSERT_EQUALS(optionsVec[14], "I0MonitorIndex=2");
-    TS_ASSERT_EQUALS(optionsVec[15], "ScaleFactor=2");
-    TS_ASSERT_EQUALS(optionsVec[16], "MomentumTransferStep=-0.02");
-    TS_ASSERT_EQUALS(optionsVec[17], "ProcessingInstructions=\"3,4\"");
-    TS_ASSERT_EQUALS(optionsVec[18],
-                     "FirstTransmissionRun=TRANS_INTER00013463");
-    TS_ASSERT_EQUALS(optionsVec[19],
-                     "SecondTransmissionRun=TRANS_INTER00013464");
-
-    TS_ASSERT(AnalysisDataService::Instance().doesExist("TRANS_INTER00013463"));
-    TS_ASSERT(AnalysisDataService::Instance().doesExist("TRANS_INTER00013464"));
-    AnalysisDataService::Instance().clear();
-
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
-  }
+    EXPECT_CALL(presenter_1, setInstrumentName("INSTRUMENT_NAME")).Times(1);
+    EXPECT_CALL(presenter_2, setInstrumentName("INSTRUMENT_NAME")).Times(1);
+    presenter.setInstrumentName("INSTRUMENT_NAME");
 
-  void testStitchOptions() {
-    MockSettingsTabView mockView;
-    ReflSettingsTabPresenter presenter(&mockView);
-
-    EXPECT_CALL(mockView, getStitchOptions()).Times(Exactly(1));
-    presenter.getStitchOptions();
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
   }
 
-  void testPolarisationOptionsEnabled() {
-    MockSettingsTabView mockView;
-    ReflSettingsTabPresenter presenter(&mockView);
-
-    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(false))
-        .Times(Exactly(1));
-    presenter.setInstrumentName("INTER");
-    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(true))
-        .Times(Exactly(1));
-    presenter.setInstrumentName("POLREF");
+  void test_transmission_options() {
+    MockSettingsPresenter presenter_0;
+    MockSettingsPresenter presenter_1;
+    MockSettingsPresenter presenter_2;
+
+    std::vector<IReflSettingsPresenter *> settingsPresenters;
+    settingsPresenters.push_back(&presenter_0);
+    settingsPresenters.push_back(&presenter_1);
+    settingsPresenters.push_back(&presenter_2);
+
+    ReflSettingsTabPresenter presenter(settingsPresenters);
+
+    EXPECT_CALL(presenter_0, getTransmissionOptions()).Times(1);
+    EXPECT_CALL(presenter_1, getTransmissionOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getTransmissionOptions()).Times(0);
+    presenter.getTransmissionOptions(0);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getTransmissionOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getTransmissionOptions()).Times(1);
+    EXPECT_CALL(presenter_2, getTransmissionOptions()).Times(0);
+    presenter.getTransmissionOptions(1);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getTransmissionOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getTransmissionOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getTransmissionOptions()).Times(1);
+    presenter.getTransmissionOptions(2);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
   }
 
-  void testExperimentDefaults() {
-    MockSettingsTabView mockView;
-    ReflSettingsTabPresenter presenter(&mockView);
-    MockMainWindowPresenter mainPresenter;
-
-    // This presenter accepts the main presenter
-    presenter.acceptMainPresenter(&mainPresenter);
-
-    // Set instrument to 'POLREF'
-    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(true))
-        .Times(Exactly(1));
-    presenter.setInstrumentName("POLREF");
-
-    std::vector<std::string> defaults = {
-        "PointDetectorAnalysis", "None",
-        "1.006831,-0.011467,0.002244,-0.000095",
-        "1.017526,-0.017183,0.003136,-0.000140",
-        "0.917940,0.038265,-0.006645,0.000282",
-        "0.972762,0.001828,-0.000261,0.0", "1"};
-
-    EXPECT_CALL(mockView, setExpDefaults(defaults)).Times(1);
-    presenter.notify(IReflSettingsTabPresenter::ExpDefaultsFlag);
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  void test_reduction_options() {
+    MockSettingsPresenter presenter_0;
+    MockSettingsPresenter presenter_1;
+    MockSettingsPresenter presenter_2;
+
+    std::vector<IReflSettingsPresenter *> settingsPresenters;
+    settingsPresenters.push_back(&presenter_0);
+    settingsPresenters.push_back(&presenter_1);
+    settingsPresenters.push_back(&presenter_2);
+
+    ReflSettingsTabPresenter presenter(settingsPresenters);
+
+    EXPECT_CALL(presenter_0, getReductionOptions()).Times(1);
+    EXPECT_CALL(presenter_1, getReductionOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getReductionOptions()).Times(0);
+    presenter.getReductionOptions(0);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getReductionOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getReductionOptions()).Times(1);
+    EXPECT_CALL(presenter_2, getReductionOptions()).Times(0);
+    presenter.getReductionOptions(1);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getReductionOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getReductionOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getReductionOptions()).Times(1);
+    presenter.getReductionOptions(2);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
   }
 
-  void testInstrumentDefaults() {
-    MockSettingsTabView mockView;
-    MockMainWindowPresenter mainPresenter;
-    ReflSettingsTabPresenter presenter(&mockView);
-
-    // This presenter accepts the main presenter
-    presenter.acceptMainPresenter(&mainPresenter);
-
-    // Set instrument to 'INTER'
-    EXPECT_CALL(mockView, setPolarisationOptionsEnabled(false))
-        .Times(Exactly(1));
-    presenter.setInstrumentName("INTER");
-
-    std::vector<double> defaults = {1., 4.0, 10., 15., 17., 1.0, 17., 2.0};
-
-    EXPECT_CALL(mockView, setInstDefaults(defaults)).Times(1);
-    presenter.notify(IReflSettingsTabPresenter::InstDefaultsFlag);
-    TS_ASSERT(Mock::VerifyAndClearExpectations(&mockView));
+  void test_stitch_options() {
+    MockSettingsPresenter presenter_0;
+    MockSettingsPresenter presenter_1;
+    MockSettingsPresenter presenter_2;
+
+    std::vector<IReflSettingsPresenter *> settingsPresenters;
+    settingsPresenters.push_back(&presenter_0);
+    settingsPresenters.push_back(&presenter_1);
+    settingsPresenters.push_back(&presenter_2);
+
+    ReflSettingsTabPresenter presenter(settingsPresenters);
+
+    EXPECT_CALL(presenter_0, getStitchOptions()).Times(1);
+    EXPECT_CALL(presenter_1, getStitchOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getStitchOptions()).Times(0);
+    presenter.getStitchOptions(0);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getStitchOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getStitchOptions()).Times(1);
+    EXPECT_CALL(presenter_2, getStitchOptions()).Times(0);
+    presenter.getStitchOptions(1);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
+
+    EXPECT_CALL(presenter_0, getStitchOptions()).Times(0);
+    EXPECT_CALL(presenter_1, getStitchOptions()).Times(0);
+    EXPECT_CALL(presenter_2, getStitchOptions()).Times(1);
+    presenter.getStitchOptions(2);
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_0));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_1));
+    TS_ASSERT(Mock::VerifyAndClearExpectations(&presenter_2));
   }
 };
 
diff --git a/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h b/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h
index fcd419ae25dbce1df39991eff4b0bc9239b16d30..8abf9d97d9546073cef297ab918e06e752bd7ee1 100644
--- a/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h
+++ b/MantidQt/CustomInterfaces/test/TomographyIfaceModelTest.h
@@ -3,6 +3,7 @@
 
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidKernel/ConfigService.h"
 #include "MantidKernel/FacilityInfo.h"
 
 #include "MantidQtCustomInterfaces/Tomography/TomographyIfaceModel.h"
@@ -171,25 +172,6 @@ public:
     TS_ASSERT_EQUALS(cmds.size(), 0);
   }
 
-  void test_submitFailEmptyDefinition() {
-    TomographyIfaceModel model;
-
-    TSM_ASSERT_THROWS("Exception not thrown as expected - submit local",
-                      model.doSubmitReconstructionJob("Local"),
-                      std::invalid_argument);
-  }
-
-  void test_submitFailEmptyTool() {
-    TomographyIfaceModel model;
-
-    model.setupComputeResource();
-    model.setupRunTool("Local");
-    model.usingTool("TomoPy");
-    TSM_ASSERT_THROWS("Exception not thrown as expected - submit local",
-                      model.doSubmitReconstructionJob("Local"),
-                      std::invalid_argument);
-  }
-
   void test_cancelFail() {
     TomographyIfaceModel model;
 
@@ -200,23 +182,6 @@ public:
                       model.doCancelJobs("Local", ids), std::invalid_argument);
   }
 
-  void test_runCustomCommandLocally() {
-    TomographyIfaceModel model;
-
-    model.setupComputeResource();
-    model.setupRunTool("Local");
-    model.usingTool("Custom command");
-
-    auto d = std::make_shared<ToolConfigCustom>("fail",
-                                                "/scriptpath/ --some params");
-    model.setCurrentToolSettings(d);
-    model.doSubmitReconstructionJob("Local");
-  }
-
-  void test_setupToolsTomoPy() { dryRunToolLocal("TomoPy", "gridrec"); }
-
-  void test_setupToolsAstra() { dryRunToolLocal("Astra", "FBP3D_CUDA"); }
-
   void test_loadFITSFail() {
     TomographyIfaceModel model;
 
@@ -261,21 +226,21 @@ public:
 
     model.setCurrentToolSettings(d);
 
-    const std::string resource = TestableTomographyIfaceModel::g_SCARFName;
+    const bool local = false;
 
-    std::string actualRun;
+    std::string actualRunnable;
+    std::string allOpts;
     std::vector<std::string> actualArgsVector;
-    model.makeRunnableWithOptions(resource, actualRun, actualArgsVector);
+    model.prepareSubmissionArguments(local, actualRunnable, actualArgsVector,
+                                     allOpts);
 
     std::string expectedRunnable = "/scriptPath/";
     // the space at the end is necessary, because of how
     // constructSingleStringFromVector works
     std::vector<std::string> expectedArgsVector{
         "--some params --some other params "};
-    TS_ASSERT_EQUALS(actualRun, expectedRunnable);
-
-    // checks size and elements
-    TS_ASSERT(actualArgsVector == expectedArgsVector);
+    doTestExpectedRunnableAndArguments(expectedRunnable, actualRunnable,
+                                       expectedArgsVector, actualArgsVector);
   }
 
   void test_makeLocalRunnableWithOptionsCustom() {
@@ -297,20 +262,22 @@ public:
 
     model.setCurrentToolSettings(d);
 
-    const std::string resource = model.localComputeResource();
+    const bool local = true;
+
+    std::string actualRunnable;
+    std::string allOpts;
 
-    std::string actualRun;
     std::vector<std::string> actualArgsVector;
-    model.makeRunnableWithOptions(resource, actualRun, actualArgsVector);
+    model.prepareSubmissionArguments(local, actualRunnable, actualArgsVector,
+                                     allOpts);
 
     std::string expectedRunnable = "python";
     // the space at the end is necessary, because of how
     // constructSingleStringFromVector works
     std::vector<std::string> expectedArgsVector{
-        "/scriptPath/ --some params --some other params "};
-    TS_ASSERT_EQUALS(actualRun, expectedRunnable);
-    // checks size and elements
-    TS_ASSERT(actualArgsVector == expectedArgsVector);
+        "/scriptPath/", "--some params --some other params "};
+    doTestExpectedRunnableAndArguments(expectedRunnable, actualRunnable,
+                                       expectedArgsVector, actualArgsVector);
   }
 
   void test_makeRemoteRunnableWithOptions() {
@@ -337,11 +304,13 @@ public:
 
     model.setCurrentToolSettings(d);
 
-    const std::string resource = TestableTomographyIfaceModel::g_SCARFName;
+    const bool local = false;
 
+    std::string allOpts;
     std::string actualRunnable;
     std::vector<std::string> actualArgsVector;
-    model.makeRunnableWithOptions(resource, actualRunnable, actualArgsVector);
+    model.prepareSubmissionArguments(local, actualRunnable, actualArgsVector,
+                                     allOpts);
 
     std::vector<std::string> expectedArgsVector{
         "--tool=tomopy", "--algorithm=gridrec", "--num-iter=5",
@@ -353,7 +322,7 @@ public:
         "--median-filter-size=3", "--cor=0.000000", "--rotation=0",
         "--max-angle=360.000000", "--circular-mask=0.940000",
         "--out-img-format=png"};
-    doTestExpectedRunnableAndArguemnts(expectedRunnable, actualRunnable,
+    doTestExpectedRunnableAndArguments(expectedRunnable, actualRunnable,
                                        expectedArgsVector, actualArgsVector);
   }
 
@@ -381,12 +350,14 @@ public:
 
     model.setCurrentToolSettings(d);
 
-    const std::string resource = model.localComputeResource();
+    const bool local = true;
 
     // should be just the externalInterpretor path
     std::string actualRunnable;
+    std::string allOpts;
     std::vector<std::string> actualArgsVector;
-    model.makeRunnableWithOptions(resource, actualRunnable, actualArgsVector);
+    model.prepareSubmissionArguments(local, actualRunnable, actualArgsVector,
+                                     allOpts);
 
     std::string expectedRunnable = "python";
     std::vector<std::string> expectedArgsVector{
@@ -402,7 +373,7 @@ public:
         "--max-angle=360.000000", "--circular-mask=0.940000",
         "--out-img-format=png"};
 
-    doTestExpectedRunnableAndArguemnts(expectedRunnable, actualRunnable,
+    doTestExpectedRunnableAndArguments(expectedRunnable, actualRunnable,
                                        expectedArgsVector, actualArgsVector);
   }
 
@@ -413,7 +384,7 @@ private:
     TestableTomographyIfaceModel() : TomographyIfaceModel() {}
   };
 
-  void doTestExpectedRunnableAndArguemnts(
+  void doTestExpectedRunnableAndArguments(
       const std::string &expectedRunnable, const std::string &actualRunnable,
       const std::vector<std::string> &expectedArguments,
       const std::vector<std::string> &actualArguments) {
@@ -430,37 +401,6 @@ private:
       TS_ASSERT_EQUALS(expectedArguments[i], actualArguments[i]);
     }
   }
-  void dryRunToolLocal(const std::string &tool, const std::string &method,
-                       const std::string &resource = "Local") {
-    TomographyIfaceModel model;
-    model.setupComputeResource();
-    model.setupRunTool(model.localComputeResource());
-    model.usingTool(tool);
-    model.setCurrentToolMethod(method);
-
-    TSM_ASSERT_EQUALS("Unexpected number of reconstruction tools",
-                      model.reconTools().size(), 5);
-
-    auto localSts = model.jobsStatusLocal();
-    TSM_ASSERT_EQUALS("Unexpected number of jobs (local)", localSts.size(), 0);
-
-    // default/empty paths, to make sure nothing will be found
-    TomoPathsConfig paths;
-    model.setTomoPathsConfig(paths);
-
-    // paths that don't make sense, so nothing gets executed even if you have a
-    // local installation of tomopy available
-    std::shared_ptr<ToolConfigTomoPy> d(
-        new ToolConfigTomoPy("fail /not_exitant_script_path/", "/out/",
-                             "/dark/", "/flat/", "/sample/"));
-    model.setCurrentToolSettings(d);
-    model.doSubmitReconstructionJob(resource);
-
-    model.refreshLocalJobsInfo();
-    localSts = model.jobsStatusLocal();
-    TSM_ASSERT_EQUALS("Unexpected number of jobs (local), after refreshing",
-                      localSts.size(), 1);
-  }
 };
 
 #endif // MANTID_CUSTOMINTERFACES_TOMOGRAPHYIFACEMODELTEST_H
diff --git a/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h b/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h
index 4f30f6668928100b1aade576958511d7d6834ec3..9872b9e9366795bc841cff867aca6002c66a763d 100644
--- a/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h
+++ b/MantidQt/CustomInterfaces/test/TomographyIfacePresenterTest.h
@@ -665,7 +665,7 @@ public:
         testing::Mock::VerifyAndClearExpectations(&mockView))
   }
 
-  void test_sillySessionLocal() {
+  void test_sillySessionRemote() {
     // the user does a few silly things...
     testing::NiceMock<MockTomographyIfaceView> mockView;
     MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView);
@@ -727,10 +727,11 @@ public:
         testing::Mock::VerifyAndClearExpectations(&mockView))
   }
 
-  void test_sillySessionLocalRemote() {
+  void test_sillySessionLocal() {
     // the user does a few silly things...
     testing::NiceMock<MockTomographyIfaceView> mockView;
-    MantidQt::CustomInterfaces::TomographyIfacePresenter pres(&mockView);
+    MantidQt::CustomInterfaces::TomographyIfacePresenter *pres =
+        new MantidQt::CustomInterfaces::TomographyIfacePresenter(&mockView);
 
     EXPECT_CALL(mockView, systemSettings()).Times(0);
 
@@ -739,12 +740,12 @@ public:
         .WillOnce(Return(TomoPathsConfig()));
 
     // user changes some paths
-    pres.notify(ITomographyIfacePresenter::TomoPathsChanged);
+    pres->notify(ITomographyIfacePresenter::TomoPathsChanged);
     EXPECT_CALL(mockView, currentComputeResource())
         .WillRepeatedly(Return("Local"));
 
     // user changes the compute resource
-    pres.notify(ITomographyIfacePresenter::CompResourceChanged);
+    pres->notify(ITomographyIfacePresenter::CompResourceChanged);
 
     EXPECT_CALL(mockView, currentReconTool())
         .Times(2)
@@ -756,9 +757,9 @@ public:
         .WillOnce(Return(TomoPathsConfig()));
 
     // the tool changed event sets up the tool's paths
-    pres.notify(ITomographyIfacePresenter::ToolChanged);
+    pres->notify(ITomographyIfacePresenter::ToolChanged);
     // user opens dialog and sets up a reconstruction tool
-    pres.notify(ITomographyIfacePresenter::SetupReconTool);
+    pres->notify(ITomographyIfacePresenter::SetupReconTool);
 
     TomoPathsConfig pathsCfg;
     EXPECT_CALL(mockView, currentPathsConfig())
@@ -780,7 +781,8 @@ public:
     EXPECT_CALL(mockView, userWarning(testing::_, testing::_)).Times(0);
 
     // finally, user tries to run a reconstruction job
-    pres.notify(ITomographyIfacePresenter::RunReconstruct);
+    pres->notify(ITomographyIfacePresenter::RunReconstruct);
+
     TSM_ASSERT(
         "Mock not used as expected. Some EXPECT_CALL conditions were not "
         "satisfied.",
diff --git a/MantidQt/CustomInterfaces/test/TomographyViewMock.h b/MantidQt/CustomInterfaces/test/TomographyViewMock.h
index fc6fd704096b8e4ffdd232073ed5d0e1c52a7a4b..006a6263acd1222aed4659921114753970dbc6c7 100644
--- a/MantidQt/CustomInterfaces/test/TomographyViewMock.h
+++ b/MantidQt/CustomInterfaces/test/TomographyViewMock.h
@@ -125,6 +125,11 @@ public:
 
   // virtual void runAggregateBands(Mantid::API::IAlgorithm_sptr alg)
   MOCK_METHOD1(runAggregateBands, void(Mantid::API::IAlgorithm_sptr alg));
+
+  //   virtual bool userConfirmation(const std::string &title, const std::string
+  //   &body)
+  MOCK_METHOD2(userConfirmation,
+               bool(const std::string &title, const std::string &body));
 };
 
 GCC_DIAG_ON_SUGGEST_OVERRIDE
diff --git a/MantidQt/MantidWidgets/CMakeLists.txt b/MantidQt/MantidWidgets/CMakeLists.txt
index e1a947158e21eb28c66a71c498940b443a6c2189..e8e15d5862eec33acfe303e23f082c2481c26c9f 100644
--- a/MantidQt/MantidWidgets/CMakeLists.txt
+++ b/MantidQt/MantidWidgets/CMakeLists.txt
@@ -84,13 +84,13 @@ set ( SRC_FILES
 	src/InstrumentView/XIntegrationControl.cpp
 	src/LineEditWithClear.cpp
 	src/LogValueSelector.cpp
-	src/MantidTreeWidget.cpp
-	src/MantidTreeWidgetItem.cpp
 	src/MWDiag.cpp
 	src/MWRunFiles.cpp
 	src/MWView.cpp
 	src/MantidHelpWindow.cpp
 	src/MantidSurfacePlotDialog.cpp
+	src/MantidTreeWidget.cpp
+	src/MantidTreeWidgetItem.cpp
 	src/MantidWSIndexDialog.cpp
 	src/MessageDisplay.cpp
 	src/MultifitSetupDialog.cpp
@@ -114,14 +114,15 @@ set ( SRC_FILES
 	src/SlitCalculator.cpp
 	src/StringDialogEditor.cpp
 	src/StringEditorFactory.cpp
+	src/TrackedAction.cpp
 	src/UserFunctionDialog.cpp
 	src/WorkspaceEditorFactory.cpp
+	src/WorkspacePresenter/ADSAdapter.cpp
+	src/WorkspacePresenter/QWorkspaceDockView.cpp
+	src/WorkspacePresenter/WorkspacePresenter.cpp
 	src/WorkspaceSelector.cpp
 	src/pqHelpWindow.cxx
 	src/pythonCalc.cpp
-    src/WorkspacePresenter/WorkspacePresenter.cpp
-    src/WorkspacePresenter/ADSAdapter.cpp
-	src/WorkspacePresenter/QWorkspaceDockView.cpp
 )
 
 # Header files with Q_OBJECT that qmake will "moc"
@@ -183,6 +184,7 @@ set ( MOC_FILES
     inc/MantidQtMantidWidgets/SlitCalculator.h
     inc/MantidQtMantidWidgets/StringDialogEditor.h
     inc/MantidQtMantidWidgets/StringEditorFactory.h
+    inc/MantidQtMantidWidgets/TrackedAction.h
     inc/MantidQtMantidWidgets/UserFunctionDialog.h
     inc/MantidQtMantidWidgets/WorkspaceEditorFactory.h
     inc/MantidQtMantidWidgets/WorkspaceSelector.h
@@ -231,6 +233,7 @@ set ( INC_FILES
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorGenerateNotebook.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorGroupRowsCommand.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorImportTableCommand.h
+	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMainPresenter.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorNewTableCommand.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorOneLevelTreeManager.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorOpenTableCommand.h
@@ -252,7 +255,6 @@ set ( INC_FILES
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorView.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorWhiteList.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorWorkspaceCommand.h
-    inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMainPresenter.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/GenericDataProcessorPresenter.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/GenericDataProcessorPresenterFactory.h
 	inc/MantidQtMantidWidgets/DataProcessorUI/ParseKeyValueString.h
@@ -315,14 +317,13 @@ set ( INC_FILES
 	inc/MantidQtMantidWidgets/MuonFitDataSelector.h
 	inc/MantidQtMantidWidgets/MuonFunctionBrowser.h
 	inc/MantidQtMantidWidgets/ProgressPresenter.h
-    inc/MantidQtMantidWidgets/ProgressableView.h
-    inc/MantidQtMantidWidgets/ProgressPresenter.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/ViewNotifiable.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspaceProviderNotifiable.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspacePresenter.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspaceProvider.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/ADSAdapter.h
-    inc/MantidQtMantidWidgets/WorkspacePresenter/IWorkspaceDockView.h
+	inc/MantidQtMantidWidgets/ProgressableView.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/ADSAdapter.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/IWorkspaceDockView.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/ViewNotifiable.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspacePresenter.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspaceProvider.h
+	inc/MantidQtMantidWidgets/WorkspacePresenter/WorkspaceProviderNotifiable.h
 )
 
 # QtDesigner UI files to process
@@ -360,22 +361,23 @@ set ( TEST_PY_FILES
 )
 
 set ( TEST_FILES
-  AlgorithmHintStrategyTest.h
-  DataProcessorUI/DataProcessorPostprocessingAlgorithmTest.h
-  DataProcessorUI/DataProcessorPreprocessingAlgorithmTest.h
-  DataProcessorUI/DataProcessorProcessingAlgorithmBaseTest.h
-  DataProcessorUI/DataProcessorProcessingAlgorithmTest.h
-  DataProcessorUI/DataProcessorCommandsTest.h
-  DataProcessorUI/DataProcessorGenerateNotebookTest.h
-  DataProcessorUI/DataProcessorOneLevelTreeManagerTest.h
-  DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h
-  DataProcessorUI/DataProcessorWhiteListTest.h
-  DataProcessorUI/GenericDataProcessorPresenterTest.h
-  DataProcessorUI/ParseKeyValueStringTest.h
-  DataProcessorUI/QDataProcessorOneLevelTreeModelTest.h
-  DataProcessorUI/QDataProcessorTwoLevelTreeModelTest.h
-  WorkspacePresenter/WorkspacePresenterTest.h
-  WorkspacePresenter/ADSAdapterTest.h
+	AlgorithmHintStrategyTest.h
+	TrackedActionTest.h
+	DataProcessorUI/DataProcessorCommandsTest.h
+	DataProcessorUI/DataProcessorGenerateNotebookTest.h
+	DataProcessorUI/DataProcessorOneLevelTreeManagerTest.h
+	DataProcessorUI/DataProcessorPostprocessingAlgorithmTest.h
+	DataProcessorUI/DataProcessorPreprocessingAlgorithmTest.h
+	DataProcessorUI/DataProcessorProcessingAlgorithmBaseTest.h
+	DataProcessorUI/DataProcessorProcessingAlgorithmTest.h
+	DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h
+	DataProcessorUI/DataProcessorWhiteListTest.h
+	DataProcessorUI/GenericDataProcessorPresenterTest.h
+	DataProcessorUI/ParseKeyValueStringTest.h
+	DataProcessorUI/QDataProcessorOneLevelTreeModelTest.h
+	DataProcessorUI/QDataProcessorTwoLevelTreeModelTest.h
+	WorkspacePresenter/ADSAdapterTest.h
+	WorkspacePresenter/WorkspacePresenterTest.h
 )
 
 find_package (Qt4 REQUIRED QtHelp QtWebKit QtNetwork QUIET)
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMockObjects.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMockObjects.h
index 05341ea16a0283f10960843278af07c38b65f509..fe44edda61a55fd1eb293f65309d0e9d134b865d 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMockObjects.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/DataProcessorUI/DataProcessorMockObjects.h
@@ -108,17 +108,20 @@ public:
                      bool(const std::string &prompt, const std::string &title));
   MOCK_CONST_METHOD2(giveUserWarning,
                      void(const std::string &prompt, const std::string &title));
+  MOCK_METHOD0(publishCommandsMocked, void());
 
 private:
   // Calls we don't care about
   const std::map<std::string, QVariant> &options() const override {
     return m_options;
   };
+
   std::vector<DataProcessorCommand_uptr> publishCommands() override {
     std::vector<DataProcessorCommand_uptr> commands;
     for (size_t i = 0; i < 27; i++)
       commands.push_back(
           Mantid::Kernel::make_unique<DataProcessorAppendRowCommand>(this));
+    publishCommandsMocked();
     return commands;
   };
   std::set<std::string> getTableList() const {
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
index 0ca9c6f49759c18d65f0dc5ffc6674a66a8622aa..952c7bee461b06cdfe4e74a637759aad0d66c18d 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
@@ -135,6 +135,8 @@ private:
   QtProperty *m_maxIterations;
   /// EvaluationType property
   QtProperty *m_evaluationType;
+  /// Peak radius property
+  QtProperty *m_peakRadius;
 
   // Fit properties
   /// Output property
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h
index d333b85018a54e1ec190425df60636c2e125adc8..d0e88e72c1c9e4060a2721e8cdadaa7e3ab91f5c 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitPropertyBrowser.h
@@ -151,6 +151,8 @@ public:
   void normaliseData(bool on) { m_shouldBeNormalised = on; }
   /// Get the max number of iterations
   int maxIterations() const;
+  /// Get the peak radius for peak functions
+  int getPeakRadius() const;
 
   /// Get the start X
   double startX() const;
@@ -413,6 +415,7 @@ protected:
   QtProperty *m_ignoreInvalidData;
   QtProperty *m_costFunction;
   QtProperty *m_maxIterations;
+  QtProperty *m_peakRadius;
   QtProperty *m_logValue;
   QtProperty *m_plotDiff;
   QtProperty *m_plotCompositeMembers;
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidget.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidget.h
index d3bf033cfff2659719377a5ed0b641790467c7ce..06913abfbdff3e0b133ed279862cff1f3c8a7fa6 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidget.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidget.h
@@ -3,13 +3,18 @@
 
 #include "InstrumentWidgetTypes.h"
 #include "MantidGLWidget.h"
-#include <MantidQtMantidWidgets/WidgetDllOption.h>
+#include "UnwrappedSurface.h"
 
 #include "MantidAPI/AlgorithmObserver.h"
+#include "MantidAPI/IMaskWorkspace.h"
+#include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/IPeaksWorkspace_fwd.h"
+#include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/Workspace.h"
 #include "MantidQtAPI/GraphOptions.h"
 #include "MantidQtAPI/WorkspaceObserver.h"
+
+#include <MantidQtMantidWidgets/WidgetDllOption.h>
 #include <boost/shared_ptr.hpp>
 
 namespace Mantid {
@@ -152,6 +157,7 @@ signals:
   void requestSelectComponent(const QString &);
   void preDeletingHandle();
   void clearingHandle();
+  void maskedWorkspaceOverlayed();
 
 protected:
   /// Implements AlgorithmObserver's finish handler
@@ -287,7 +293,16 @@ private:
   void renameHandle(const std::string &oldName,
                     const std::string &newName) override;
   void clearADSHandle() override;
-
+  /// overlay a peaks workspace on the projection surface
+  void overlayPeaksWorkspace(Mantid::API::IPeaksWorkspace_sptr ws);
+  /// overlay a masked workspace on the projection surface
+  void overlayMaskedWorkspace(Mantid::API::IMaskWorkspace_sptr ws);
+  /// overlay a table workspace with shape parameters on the projection surface
+  void overlayShapesWorkspace(Mantid::API::ITableWorkspace_sptr);
+  /// get a workspace from the ADS
+  Mantid::API::Workspace_sptr getWorkspaceFromADS(const std::string &name);
+  /// get a handle to the unwrapped surface
+  boost::shared_ptr<UnwrappedSurface> getUnwrappedSurface();
   /// Load tabs on the widget form a project file
   void loadTabs(const std::string &lines) const;
   /// Save tabs on the widget to a string
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidgetMaskTab.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidgetMaskTab.h
index a8719e43ad483aecab06d9f1721a28c307af7abc..b52f31104694d8d6c7d74e694c6b48adc5638765 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidgetMaskTab.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/InstrumentWidgetMaskTab.h
@@ -95,6 +95,7 @@ protected slots:
   void storeBinMask();
   void storeMask();
   void clearMask();
+  void saveShapesToTable() const;
   void saveInvertedMaskToWorkspace();
   void saveInvertedMaskToFile();
   void saveMaskToWorkspace();
@@ -108,7 +109,7 @@ protected slots:
   void saveExcludeGroupToFile();
   void showSaveMenuTooltip(QAction *);
   void toggleMaskGroup();
-
+  void enableApplyButtons();
   void doubleChanged(QtProperty *);
 
 protected:
@@ -123,7 +124,6 @@ protected:
   void saveMaskingToCalFile(bool invertMask = false);
   void saveMaskingToTableWorkspace(bool invertMask = false);
   std::string generateMaskWorkspaceName(bool temp = false) const;
-  void enableApplyButtons();
   void setSelectActivity();
   Mode getMode() const;
   /// Get mask/group border color
@@ -165,6 +165,7 @@ protected:
 
   QPushButton *m_applyToData;
   QPushButton *m_applyToView;
+  QPushButton *m_saveShapesToTable;
   QPushButton *m_clearAll;
   QPushButton *m_saveButton;
   bool m_maskBins;
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/ProjectionSurface.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/ProjectionSurface.h
index 074b64bd3dba59115d495806e44c5e6f861cde42..946390ce43908b30df7a952a01929ec255f77753 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/ProjectionSurface.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/ProjectionSurface.h
@@ -227,6 +227,10 @@ public:
   void changeBorderColor(const QColor &color) {
     m_maskShapes.changeBorderColor(color);
   }
+  /// Save masks to a table workspace
+  void saveShapesToTableWorkspace();
+  /// Load masks from a table workspace
+  void loadShapesFromTableWorkspace(Mantid::API::ITableWorkspace_const_sptr ws);
 
   //-----------------------------------
   //    Peaks overlay methods
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/Shape2DCollection.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/Shape2DCollection.h
index a817239b347ff514d8a960b6bc023a8ae796f087..e53d4a2e579899e65c55251487870ce9d0259a29 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/Shape2DCollection.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/InstrumentView/Shape2DCollection.h
@@ -1,6 +1,8 @@
 #ifndef MANTIDPLOT_SHAPE2DCOLLECTION_H_
 #define MANTIDPLOT_SHAPE2DCOLLECTION_H_
 
+#include "MantidAPI/ITableWorkspace.h"
+
 #include "Shape2D.h"
 #include "RectF.h"
 
@@ -85,6 +87,10 @@ public:
 
   /// Change border color of all shapes.
   void changeBorderColor(const QColor &color);
+  /// Save shape collection to a Table workspace
+  void saveToTableWorkspace();
+  /// Load shape collectio from a Table workspace
+  void loadFromTableWorkspace(Mantid::API::ITableWorkspace_const_sptr ws);
   /// Load settings for the shape 2D collection from a project file
   virtual void loadFromProject(const std::string &lines);
   /// Save settings for the shape 2D collection to a project file
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h
index da23a5ca868e4c6b8d6ced837c4ef732314b1928..6ac6f86e7a671e852fa4506f28d17b19d59c0146 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.h
@@ -137,10 +137,8 @@ public:
   };
   /// Options for the live button
   enum LiveButtonOpts {
-    Hide,       ///< Don't use the live button
-    AlwaysShow, ///< Show whether a connection is possible or not (will be
-    /// disabled)
-    ShowIfCanConnect ///< Only show if able to connect to the live data server
+    Hide, ///< Don't use the live button
+    Show, ///< Display the live button
   };
 
   /// Default constructor
@@ -175,7 +173,6 @@ public:
   void liveButtonState(LiveButtonOpts);
 
   // Standard setters/getters
-  void liveButtonSetEnabled(bool);
   void liveButtonSetChecked(bool);
   bool liveButtonIsChecked() const;
   bool isEmpty() const;
@@ -238,8 +235,6 @@ signals:
   void fileFindingFinished();
   /// Emitted when the live button is toggled
   void liveButtonPressed(bool);
-  /// Signal emitted after asynchronous checking of live stream availability
-  void liveButtonSetEnabledSignal(bool);
   /// Emitted when inspection of any found files is completed
   void fileInspectionFinished();
 
@@ -278,8 +273,6 @@ private:
   /// displays the validator red star if either m_fileProblem or
   /// m_entryNumProblem are not empty
   void refreshValidator();
-  /// Called asynchronously to check the availability of the live stream
-  void checkLiveConnection();
   /// Turn on/off display of validator red star (default is on)
   void setValidatorDisplay(bool display);
 
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui
index 6edbb9057145dede6af2f9b6857fbfc818a05270..eb3246fe18b3aefd454ed534fbc5799683080457 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/MWRunFiles.ui
@@ -20,7 +20,16 @@
    <string>Form</string>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
-   <property name="margin">
+   <property name="leftMargin">
+    <number>0</number>
+   </property>
+   <property name="topMargin">
+    <number>0</number>
+   </property>
+   <property name="rightMargin">
+    <number>0</number>
+   </property>
+   <property name="bottomMargin">
     <number>0</number>
    </property>
    <item>
@@ -32,9 +41,6 @@
    </item>
    <item>
     <widget class="QLineEdit" name="fileEditor">
-     <property name="maxLength">
-       <number>500000</number>
-     </property>
      <property name="sizePolicy">
       <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
        <horstretch>0</horstretch>
@@ -47,6 +53,9 @@
        <height>0</height>
       </size>
      </property>
+     <property name="maxLength">
+      <number>500000</number>
+     </property>
     </widget>
    </item>
    <item>
@@ -154,9 +163,6 @@
    </item>
    <item>
     <widget class="QPushButton" name="liveButton">
-     <property name="enabled">
-      <bool>false</bool>
-     </property>
      <property name="toolTip">
       <string>Enabled if a connection can be made to your default instrument</string>
      </property>
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
index 7fc240e5522749d63481e80cf77352e7576e2a06..fb8699ca92b92bd9eee2e17c068b53fa0fdfc488 100644
--- a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
@@ -8,8 +8,11 @@
 #include "MantidQtMantidWidgets/RangeSelector.h"
 #include "MantidQtAPI/MantidWidget.h"
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 
+#include <Poco/NObserver.h>
+
 #include <QActionGroup>
 #include <QHBoxLayout>
 #include <QLabel>
diff --git a/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/TrackedAction.h b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/TrackedAction.h
new file mode 100644
index 0000000000000000000000000000000000000000..9186fc6da17ae45f30c3562941efb8352b596942
--- /dev/null
+++ b/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/TrackedAction.h
@@ -0,0 +1,64 @@
+#ifndef MANTID_MANTIDWIDGETS_TRACKEDACTION_H_
+#define MANTID_MANTIDWIDGETS_TRACKEDACTION_H_
+
+#include "WidgetDllOption.h"
+#include <QAction>
+
+namespace MantidQt {
+namespace MantidWidgets {
+
+/** TrackedAction : This is a version of QAction that tracks usage through the
+  Mantid usage service
+
+  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 EXPORT_OPT_MANTIDQT_MANTIDWIDGETS TrackedAction : public QAction {
+  Q_OBJECT
+public:
+  TrackedAction(QObject *parent);
+  TrackedAction(const QString &text, QObject *parent);
+  TrackedAction(const QIcon &icon, const QString &text, QObject *parent);
+  virtual ~TrackedAction() = default;
+
+  void setTrackingName(const std::string &name);
+  std::string getTrackingName() const;
+
+  void setIsTracking(const bool enableTracking);
+  bool getIsTracking() const;
+
+protected:
+  virtual std::string generateTrackingName() const;
+  virtual void registerUsage(const std::string &name);
+
+private:
+  void setupTracking();
+  bool m_isTracking;
+  mutable std::string m_trackingName;
+
+public slots:
+  void trackActivation(const bool checked);
+};
+
+} // namespace MantidWidgets
+} // namespace Mantid
+
+#endif /* MANTID_MANTIDWIDGETS_TRACKEDACTION_H_ */
\ No newline at end of file
diff --git a/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorOneLevelTreeManager.cpp b/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorOneLevelTreeManager.cpp
index c8a059e20d30de80a26a0cac200cacc0130a63e4..5bc413b37a6d64298b90c830028ef35883217365 100644
--- a/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorOneLevelTreeManager.cpp
+++ b/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorOneLevelTreeManager.cpp
@@ -20,6 +20,7 @@
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorSeparatorCommand.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/QDataProcessorOneLevelTreeModel.h"
 #include "MantidKernel/make_unique.h"
+#include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/split.hpp>
 
diff --git a/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorTwoLevelTreeManager.cpp b/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorTwoLevelTreeManager.cpp
index 250a97c49295091c612e6ef33aa46cd60a19c0f4..4e201ad6808585ebe19e1d02d0619fcf8304da6c 100644
--- a/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorTwoLevelTreeManager.cpp
+++ b/MantidQt/MantidWidgets/src/DataProcessorUI/DataProcessorTwoLevelTreeManager.cpp
@@ -25,6 +25,7 @@
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorSeparatorCommand.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/QDataProcessorTwoLevelTreeModel.h"
 #include "MantidKernel/make_unique.h"
+#include <boost/algorithm/string/classification.hpp>
 #include <boost/algorithm/string/join.hpp>
 #include <boost/algorithm/string/split.hpp>
 
@@ -367,6 +368,10 @@ void DataProcessorTwoLevelTreeManager::pasteSelected(const std::string &text) {
 void DataProcessorTwoLevelTreeManager::newTable(
     const DataProcessorWhiteList &whitelist) {
 
+  size_t nrows = m_ws->rowCount();
+  for (size_t row = 0; row < nrows; row++)
+    m_ws->removeRow(0);
+
   m_model.reset(new QDataProcessorTwoLevelTreeModel(
       createDefaultWorkspace(whitelist), whitelist));
 }
diff --git a/MantidQt/MantidWidgets/src/DataProcessorUI/GenericDataProcessorPresenter.cpp b/MantidQt/MantidWidgets/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
index 57158352343d44c3faa22205bde63dba53170af2..b46972caa7a88748ffbfc40b72ce5e47b0d62ef0 100644
--- a/MantidQt/MantidWidgets/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
+++ b/MantidQt/MantidWidgets/src/DataProcessorUI/GenericDataProcessorPresenter.cpp
@@ -194,6 +194,10 @@ void GenericDataProcessorPresenter::process() {
 
   const auto items = m_manager->selectedData(true);
 
+  // Don't bother continuing if there are no items to process
+  if (items.size() == 0)
+    return;
+
   // Progress: each group and each row within count as a progress step.
   int progress = 0;
   int maxProgress = (int)(items.size());
diff --git a/MantidQt/MantidWidgets/src/DataProcessorUI/QDataProcessorWidget.cpp b/MantidQt/MantidWidgets/src/DataProcessorUI/QDataProcessorWidget.cpp
index 73d2f0d176ff5a9c14b4f2d86af7dda51a55dec2..afc2cc5cca755254d96d4c4a19a27b4b3a1562fd 100644
--- a/MantidQt/MantidWidgets/src/DataProcessorUI/QDataProcessorWidget.cpp
+++ b/MantidQt/MantidWidgets/src/DataProcessorUI/QDataProcessorWidget.cpp
@@ -1,5 +1,4 @@
 #include "MantidQtMantidWidgets/DataProcessorUI/QDataProcessorWidget.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/MantidWidget.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorCommandAdapter.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorPresenter.h"
@@ -184,7 +183,7 @@ std::string QDataProcessorWidget::requestNotebookPath() {
 
   // We won't use QFileDialog directly here as using the NativeDialog option
   // causes problems on MacOS.
-  QString qfilename = API::FileDialogHandler::getSaveFileName(
+  QString qfilename = QFileDialog::getSaveFileName(
       this, "Save notebook file", QDir::currentPath(),
       "IPython Notebook files (*.ipynb);;All files (*)",
       new QString("IPython Notebook files (*.ipynb)"));
diff --git a/MantidQt/MantidWidgets/src/DisplayCurveFit.cpp b/MantidQt/MantidWidgets/src/DisplayCurveFit.cpp
index b49b7c0bf8248b56b421722544d5b4715d7199ef..c57a493a679a350f3ee0e3898c7331b7b0b1e72c 100644
--- a/MantidQt/MantidWidgets/src/DisplayCurveFit.cpp
+++ b/MantidQt/MantidWidgets/src/DisplayCurveFit.cpp
@@ -1,3 +1,4 @@
+#include "MantidKernel/Logger.h"
 #include "MantidQtMantidWidgets/DisplayCurveFit.h"
 // includes for workspace handling
 
diff --git a/MantidQt/MantidWidgets/src/DoubleDialogEditor.cpp b/MantidQt/MantidWidgets/src/DoubleDialogEditor.cpp
index d45b46f7c6976f9ab1c87c8ee6ba747efc3badcc..7c68cae72a15ace3a33d13e0209596850eff1480 100644
--- a/MantidQt/MantidWidgets/src/DoubleDialogEditor.cpp
+++ b/MantidQt/MantidWidgets/src/DoubleDialogEditor.cpp
@@ -3,7 +3,6 @@
 #include <QHBoxLayout>
 #include <QLineEdit>
 #include <QPushButton>
-#include <QFileDialog>
 #include <QLabel>
 #include <QDialog>
 #include <QSettings>
diff --git a/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp b/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
index 1ed2d41fbd275cd37c417f4bac0b3ffd25271413..a3b9bedbbe12411be85b4709ad902e9ad7e1476f 100644
--- a/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
+++ b/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
@@ -201,6 +201,15 @@ void FitOptionsBrowser::createCommonProperties() {
                 &FitOptionsBrowser::getStringEnumProperty,
                 &FitOptionsBrowser::setStringEnumProperty);
   }
+  // Create PeakRadius property
+  m_peakRadius = m_intManager->addProperty("Peak Radius");
+  {
+    m_intManager->setValue(m_peakRadius, 0);
+    m_intManager->setMinimum(m_peakRadius, 0);
+    m_browser->addProperty(m_peakRadius);
+    addProperty("PeakRadius", m_peakRadius, &FitOptionsBrowser::getIntProperty,
+                &FitOptionsBrowser::setIntProperty);
+  }
 }
 
 void FitOptionsBrowser::createSimultaneousFitProperties() {
diff --git a/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp b/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
index fb7e55f7326a2d93a72e21a82cc60913aa47c5b6..d2b71f940712a0cf907eba61a8ba3f00fe2c0b64 100644
--- a/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
+++ b/MantidQt/MantidWidgets/src/FitPropertyBrowser.cpp
@@ -55,6 +55,7 @@
 #include <QUrl>
 
 #include <algorithm>
+#include <iostream>
 
 namespace MantidQt {
 using API::MantidDesktopServices;
@@ -67,29 +68,31 @@ namespace MantidWidgets {
  * @param mantidui :: The UI form for MantidPlot
  */
 FitPropertyBrowser::FitPropertyBrowser(QWidget *parent, QObject *mantidui)
-    : QDockWidget("Fit Function", parent), m_workspaceIndex(NULL),
-      m_startX(NULL), m_endX(NULL), m_output(NULL), m_minimizer(NULL),
-      m_ignoreInvalidData(NULL), m_costFunction(NULL), m_maxIterations(NULL),
-      m_logValue(NULL), m_plotDiff(NULL), m_plotCompositeMembers(NULL),
-      m_convolveMembers(NULL), m_rawData(NULL), m_xColumn(NULL),
-      m_yColumn(NULL), m_errColumn(NULL), m_showParamErrors(NULL),
-      m_evaluationType(nullptr), m_compositeFunction(), m_browser(NULL),
-      m_fitActionUndoFit(NULL), m_fitActionSeqFit(NULL), m_fitActionFit(NULL),
-      m_fitActionEvaluate(NULL), m_functionsGroup(NULL), m_settingsGroup(NULL),
-      m_customSettingsGroup(NULL), m_changeSlotsEnabled(false),
+    : QDockWidget("Fit Function", parent), m_workspaceIndex(nullptr),
+      m_startX(nullptr), m_endX(nullptr), m_output(nullptr),
+      m_minimizer(nullptr), m_ignoreInvalidData(nullptr),
+      m_costFunction(nullptr), m_maxIterations(nullptr), m_peakRadius(nullptr),
+      m_logValue(nullptr), m_plotDiff(nullptr), m_plotCompositeMembers(nullptr),
+      m_convolveMembers(nullptr), m_rawData(nullptr), m_xColumn(nullptr),
+      m_yColumn(nullptr), m_errColumn(nullptr), m_showParamErrors(nullptr),
+      m_evaluationType(nullptr), m_compositeFunction(), m_browser(nullptr),
+      m_fitActionUndoFit(nullptr), m_fitActionSeqFit(nullptr),
+      m_fitActionFit(nullptr), m_fitActionEvaluate(nullptr),
+      m_functionsGroup(nullptr), m_settingsGroup(nullptr),
+      m_customSettingsGroup(nullptr), m_changeSlotsEnabled(false),
       m_guessOutputName(true),
       m_updateObserver(*this, &FitPropertyBrowser::handleFactoryUpdate),
-      m_fitMapper(NULL), m_fitMenu(NULL), m_displayActionPlotGuess(NULL),
-      m_displayActionQuality(NULL), m_displayActionClearAll(NULL),
-      m_setupActionCustomSetup(NULL), m_setupActionRemove(NULL), m_tip(NULL),
-      m_fitSelector(NULL), m_fitTree(NULL), m_currentHandler(0),
-      m_defaultFunction("Gaussian"), m_defaultPeak("Gaussian"),
-      m_defaultBackground("LinearBackground"), m_index_(0), m_peakToolOn(false),
-      m_auto_back(false),
+      m_fitMapper(nullptr), m_fitMenu(nullptr),
+      m_displayActionPlotGuess(nullptr), m_displayActionQuality(nullptr),
+      m_displayActionClearAll(nullptr), m_setupActionCustomSetup(nullptr),
+      m_setupActionRemove(nullptr), m_tip(nullptr), m_fitSelector(nullptr),
+      m_fitTree(nullptr), m_currentHandler(0), m_defaultFunction("Gaussian"),
+      m_defaultPeak("Gaussian"), m_defaultBackground("LinearBackground"),
+      m_index_(0), m_peakToolOn(false), m_auto_back(false),
       m_autoBgName(QString::fromStdString(
           Mantid::Kernel::ConfigService::Instance().getString(
               "curvefitting.autoBackground"))),
-      m_autoBackground(NULL), m_decimals(-1), m_mantidui(mantidui),
+      m_autoBackground(nullptr), m_decimals(-1), m_mantidui(mantidui),
       m_shouldBeNormalised(false) {
   // Make sure plugins are loaded
   std::string libpath =
@@ -177,7 +180,7 @@ void FitPropertyBrowser::init() {
                << "Conjugate gradient (Fletcher-Reeves imp.)"
                << "Conjugate gradient (Polak-Ribiere imp.)"
                << "BFGS"
-               << "Damping";
+               << "Damped GaussNewton";
 
   m_ignoreInvalidData = m_boolManager->addProperty("Ignore invalid data");
   setIgnoreInvalidData(settings.value("Ignore invalid data", false).toBool());
@@ -192,6 +195,10 @@ void FitPropertyBrowser::init() {
   m_intManager->setValue(m_maxIterations,
                          settings.value("Max Iterations", 500).toInt());
 
+  m_peakRadius = m_intManager->addProperty("Peak Radius");
+  m_intManager->setValue(m_peakRadius,
+                         settings.value("Peak Radius", 0).toInt());
+
   m_plotDiff = m_boolManager->addProperty("Plot Difference");
   bool plotDiff = settings.value("Plot Difference", QVariant(true)).toBool();
   m_boolManager->setValue(m_plotDiff, plotDiff);
@@ -240,6 +247,7 @@ void FitPropertyBrowser::init() {
   settingsGroup->addSubProperty(m_ignoreInvalidData);
   settingsGroup->addSubProperty(m_costFunction);
   settingsGroup->addSubProperty(m_maxIterations);
+  settingsGroup->addSubProperty(m_peakRadius);
   settingsGroup->addSubProperty(m_plotDiff);
   settingsGroup->addSubProperty(m_plotCompositeMembers);
   settingsGroup->addSubProperty(m_convolveMembers);
@@ -670,7 +678,7 @@ void FitPropertyBrowser::acceptFit() {
   if (items.size() != 1)
     return;
 
-  if (items[0]->parent() == NULL)
+  if (items[0]->parent() == nullptr)
     return;
 
   PropertyHandler *h = getHandler()->findHandler(cf);
@@ -690,7 +698,7 @@ void FitPropertyBrowser::createCompositeFunction(
     const Mantid::API::IFunction_sptr func) {
   if (m_compositeFunction) {
     emit functionRemoved();
-    m_autoBackground = NULL;
+    m_autoBackground = nullptr;
   }
   if (!func) {
     m_compositeFunction.reset(new Mantid::API::CompositeFunction);
@@ -748,7 +756,7 @@ void FitPropertyBrowser::popupMenu(const QPoint &) {
   bool isFunctionsGroup = ci == m_functionsGroup;
   bool isSettingsGroup = ci == m_settingsGroup;
   bool isASetting = ci->parent() == m_settingsGroup;
-  bool isFunction = getHandler()->findFunction(ci) != NULL;
+  bool isFunction = getHandler()->findFunction(ci) != nullptr;
   bool isCompositeFunction =
       isFunction && getHandler()->findCompositeFunction(ci);
 
@@ -1145,6 +1153,11 @@ int FitPropertyBrowser::maxIterations() const {
   return m_intManager->value(m_maxIterations);
 }
 
+/// Get the peak radius for peak functions
+int FitPropertyBrowser::getPeakRadius() const {
+  return m_intManager->value(m_peakRadius);
+}
+
 /// Get the registered function names
 void FitPropertyBrowser::populateFunctionNames() {
   const std::vector<std::string> names =
@@ -1272,11 +1285,14 @@ void FitPropertyBrowser::intChanged(QtProperty *prop) {
     if (!h)
       return;
     h->setFunctionWorkspace();
-  } else if (prop == m_maxIterations) {
+  } else if (prop == m_maxIterations || prop == m_peakRadius) {
     QSettings settings;
     settings.beginGroup("Mantid/FitBrowser");
     int val = m_intManager->value(prop);
     settings.setValue(prop->propertyName(), val);
+    if (prop == m_peakRadius) {
+      sendParameterChanged(m_compositeFunction.get());
+    }
   } else { // it could be an attribute
     PropertyHandler *h = getHandler()->findHandler(prop);
     if (!h)
@@ -1523,6 +1539,7 @@ void FitPropertyBrowser::doFit(int maxIterations) {
     alg->setProperty("IgnoreInvalidData", ignoreInvalidData());
     alg->setPropertyValue("CostFunction", costFunction());
     alg->setProperty("MaxIterations", maxIterations);
+    alg->setProperty("PeakRadius", getPeakRadius());
     if (!isHistogramFit()) {
       alg->setProperty("Normalise", m_shouldBeNormalised);
       // Always output each composite function but not necessarily plot it
@@ -1762,7 +1779,7 @@ void FitPropertyBrowser::currentItemChanged(QtBrowserItem *current) {
   if (current) {
     m_currentHandler = getHandler()->findHandler(current->property());
   } else {
-    m_currentHandler = NULL;
+    m_currentHandler = nullptr;
   }
   emit currentChanged();
 }
@@ -2013,7 +2030,7 @@ void FitPropertyBrowser::hasConstraints(QtProperty *parProp, bool &hasTie,
   }
 }
 
-/** Returns the tie property for a parameter property, or NULL
+/** Returns the tie property for a parameter property, or nullptr
  * @param parProp :: parameter property
  */
 QtProperty *FitPropertyBrowser::getTieProperty(QtProperty *parProp) const {
@@ -2023,7 +2040,7 @@ QtProperty *FitPropertyBrowser::getTieProperty(QtProperty *parProp) const {
       return subs[i];
     }
   }
-  return NULL;
+  return nullptr;
 }
 
 /**
@@ -2159,7 +2176,7 @@ void FitPropertyBrowser::clearAllPlots() { emit removeFitCurves(); }
 QtProperty *
 FitPropertyBrowser::addDoubleProperty(const QString &name,
                                       QtDoublePropertyManager *manager) const {
-  if (manager == NULL)
+  if (manager == nullptr)
     manager = m_doubleManager;
   QtProperty *prop = manager->addProperty(name);
   manager->setDecimals(prop, m_decimals);
@@ -2327,11 +2344,11 @@ void FitPropertyBrowser::addAutoBackground() {
   PropertyHandler *ch = currentHandler();
   if (m_autoBackground) { // remove old background
     if (ch == m_autoBackground) {
-      ch = NULL;
+      ch = nullptr;
     }
     hasPlot = m_autoBackground->hasPlot();
     m_autoBackground->removeFunction();
-    m_autoBackground = NULL;
+    m_autoBackground = nullptr;
   }
   // Create the function
   PropertyHandler *h = getHandler()->addFunction(m_autoBgName.toStdString());
@@ -2445,7 +2462,7 @@ void FitPropertyBrowser::removeLogValue() {
   if (isWorkspaceAGroup())
     return;
   m_settingsGroup->property()->removeSubProperty(m_logValue);
-  m_logValue = NULL;
+  m_logValue = nullptr;
 }
 
 void FitPropertyBrowser::sequentialFit() {
@@ -2849,7 +2866,8 @@ FitPropertyBrowser::createMatrixFromTableWorkspace() const {
       return boost::shared_ptr<Mantid::API::Workspace>();
     const size_t rowCount = tws->rowCount();
     if (rowCount == 0) {
-      QMessageBox::critical(NULL, "Mantid - Error", "TableWorkspace is empty.");
+      QMessageBox::critical(nullptr, "Mantid - Error",
+                            "TableWorkspace is empty.");
       return boost::shared_ptr<Mantid::API::Workspace>();
     }
 
@@ -2858,7 +2876,8 @@ FitPropertyBrowser::createMatrixFromTableWorkspace() const {
     // get the x column
     int ix = m_columnManager->value(m_xColumn);
     if (ix >= static_cast<int>(columns.size())) {
-      QMessageBox::critical(NULL, "Mantid - Error", "X column was not found.");
+      QMessageBox::critical(nullptr, "Mantid - Error",
+                            "X column was not found.");
       return boost::shared_ptr<Mantid::API::Workspace>();
     }
     auto xcol = tws->getColumn(columns[ix]);
@@ -2866,7 +2885,8 @@ FitPropertyBrowser::createMatrixFromTableWorkspace() const {
     // get the y column
     int iy = m_columnManager->value(m_yColumn);
     if (iy >= static_cast<int>(columns.size())) {
-      QMessageBox::critical(NULL, "Mantid - Error", "Y column was not found.");
+      QMessageBox::critical(nullptr, "Mantid - Error",
+                            "Y column was not found.");
       return boost::shared_ptr<Mantid::API::Workspace>();
     }
     auto ycol = tws->getColumn(columns[iy]);
@@ -2875,7 +2895,7 @@ FitPropertyBrowser::createMatrixFromTableWorkspace() const {
     int ie =
         m_columnManager->value(m_errColumn) - 1; // first entry is empty string
     if (ie >= 0 && ie >= static_cast<int>(columns.size())) {
-      QMessageBox::critical(NULL, "Mantid - Error",
+      QMessageBox::critical(nullptr, "Mantid - Error",
                             "Error column was not found.");
       return boost::shared_ptr<Mantid::API::Workspace>();
     }
@@ -2897,7 +2917,7 @@ FitPropertyBrowser::createMatrixFromTableWorkspace() const {
 
     return mws;
   } catch (std::exception &e) {
-    QMessageBox::critical(NULL, "Mantid - Error", e.what());
+    QMessageBox::critical(nullptr, "Mantid - Error", e.what());
     return boost::shared_ptr<Mantid::API::Workspace>();
   }
 }
@@ -2953,7 +2973,7 @@ void FitPropertyBrowser::minimizerChanged() {
   auto &properties = minzer->getProperties();
   for (auto it = properties.begin(); it != properties.end(); ++it) {
     QString propName = QString::fromStdString((**it).name());
-    QtProperty *prop = NULL;
+    QtProperty *prop = nullptr;
     if (auto prp =
             dynamic_cast<Mantid::Kernel::PropertyWithValue<bool> *>(*it)) {
       prop = m_boolManager->addProperty(propName);
diff --git a/MantidQt/MantidWidgets/src/FormulaDialogEditor.cpp b/MantidQt/MantidWidgets/src/FormulaDialogEditor.cpp
index 253787cd1a23547c671b1f7849875f39dc289608..b35535076cbed264ae02905ebbfb3b5b66c10b9b 100644
--- a/MantidQt/MantidWidgets/src/FormulaDialogEditor.cpp
+++ b/MantidQt/MantidWidgets/src/FormulaDialogEditor.cpp
@@ -1,7 +1,6 @@
 #include "MantidQtMantidWidgets/FormulaDialogEditor.h"
 #include "MantidQtMantidWidgets/UserFunctionDialog.h"
 
-#include <QFileDialog>
 #include <QSettings>
 
 namespace MantidQt {
diff --git a/MantidQt/MantidWidgets/src/FunctionBrowser.cpp b/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
index 549e42b145966af368d7086d8b74eb8496757959..f4d523be29d3dae76e2497473db785c7606ae802 100644
--- a/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
+++ b/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
@@ -37,6 +37,7 @@
 #include <QMetaMethod>
 #include <QTreeWidget>
 
+#include <boost/lexical_cast.hpp>
 #include <algorithm>
 
 namespace {
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp
index 7824ad8d701be064879232d01bc4478d04a020c1..f8c0b1457ec127795a7719b6502928bce0c61aff 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentActor.cpp
@@ -16,6 +16,7 @@
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/IMaskWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/SpectrumInfo.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
 #include "MantidGeometry/Objects/Object.h"
@@ -634,8 +635,8 @@ void InstrumentActor::resetColors() {
   m_colors.resize(m_specIntegrs.size());
 
   auto sharedWorkspace = getWorkspace();
+  const auto &spectrumInfo = sharedWorkspace->spectrumInfo();
 
-  Instrument_const_sptr inst = getInstrument();
   IMaskWorkspace_sptr mask = getMaskWorkspaceIfExists();
 
   for (int iwi = 0; iwi < int(m_specIntegrs.size()); iwi++) {
@@ -649,7 +650,7 @@ void InstrumentActor::resetColors() {
       if (mask) {
         masked = mask->isMasked(dets);
       } else {
-        masked = inst->isDetectorMasked(dets);
+        masked = spectrumInfo.hasDetectors(wi) && spectrumInfo.isMasked(wi);
       }
 
       if (masked) {
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidget.cpp b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidget.cpp
index aef9bea4e6f2dfff6267cde040cc2571741ac060..745ce6d2b5437bd4a7e0afc293fc25054ecc63f0 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidget.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidget.cpp
@@ -9,6 +9,7 @@
 #include "MantidQtMantidWidgets/InstrumentView/InstrumentWidgetTreeTab.h"
 
 #include "MantidAPI/Axis.h"
+#include "MantidAPI/IMaskWorkspace.h"
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/Workspace.h"
@@ -51,8 +52,6 @@
 #include <QVBoxLayout>
 #include <QWidget>
 
-#include "MantidQtAPI/FileDialogHandler.h"
-
 #include <numeric>
 #include <stdexcept>
 
@@ -317,8 +316,8 @@ InstrumentWidgetTab *InstrumentWidget::getTab(const Tab tab) const {
 QString InstrumentWidget::getSaveFileName(const QString &title,
                                           const QString &filters,
                                           QString *selectedFilter) {
-  QString filename = MantidQt::API::FileDialogHandler::getSaveFileName(
-      this, title, m_savedialog_dir, filters, selectedFilter);
+  QString filename = QFileDialog::getSaveFileName(this, title, m_savedialog_dir,
+                                                  filters, selectedFilter);
 
   // If its empty, they cancelled the dialog
   if (!filename.isEmpty()) {
@@ -676,9 +675,9 @@ void InstrumentWidget::saveImage(QString filename) {
 * Use the file dialog to select a filename to save grouping.
 */
 QString InstrumentWidget::getSaveGroupingFilename() {
-  QString filename = MantidQt::API::FileDialogHandler::getSaveFileName(
-      this, "Save grouping file", m_savedialog_dir,
-      "Grouping (*.xml);;All files (*)");
+  QString filename =
+      QFileDialog::getSaveFileName(this, "Save grouping file", m_savedialog_dir,
+                                   "Grouping (*.xml);;All files (*)");
 
   // If its empty, they cancelled the dialog
   if (!filename.isEmpty()) {
@@ -936,39 +935,30 @@ void InstrumentWidget::setColorMapAutoscaling(bool on) {
 */
 bool InstrumentWidget::overlay(const QString &wsName) {
   using namespace Mantid::API;
-  Workspace_sptr workspace;
-  bool success(false);
-  try {
-    workspace = AnalysisDataService::Instance().retrieve(wsName.toStdString());
-  } catch (std::runtime_error) {
-    QMessageBox::warning(this, "MantidPlot - Warning",
-                         "No workspace called '" + wsName + "' found. ");
-    return success;
-  }
+
+  auto workspace = getWorkspaceFromADS(wsName.toStdString());
 
   auto pws = boost::dynamic_pointer_cast<IPeaksWorkspace>(workspace);
-  if (!pws) {
+  auto table = boost::dynamic_pointer_cast<ITableWorkspace>(workspace);
+  auto mask = boost::dynamic_pointer_cast<IMaskWorkspace>(workspace);
+
+  if (!pws && !table && !mask) {
     QMessageBox::warning(this, "MantidPlot - Warning",
                          "Work space called '" + wsName +
                              "' is not suitable."
                              " Please select another workspace. ");
-    return success;
+    return false;
   }
 
-  auto surface = boost::dynamic_pointer_cast<UnwrappedSurface>(getSurface());
-  if (!surface) {
-    QMessageBox::warning(
-        this, "MantidPlot - Warning",
-        "Please change to an unwrapped view to see peak labels.");
-    return success;
+  if (pws) {
+    overlayPeaksWorkspace(pws);
+  } else if (table) {
+    overlayShapesWorkspace(table);
+  } else if (mask) {
+    overlayMaskedWorkspace(mask);
   }
 
-  if (pws && surface) {
-    surface->setPeaksWorkspace(pws);
-    updateInstrumentView();
-    success = true;
-  }
-  return success;
+  return true;
 }
 
 /**
@@ -1282,6 +1272,76 @@ void InstrumentWidget::clearADSHandle() {
   close();
 }
 
+/**
+ * Overlay a peaks workspace on the surface projection
+ * @param ws :: peaks workspace to overlay
+ */
+void InstrumentWidget::overlayPeaksWorkspace(IPeaksWorkspace_sptr ws) {
+  auto surface = getUnwrappedSurface();
+  surface->setPeaksWorkspace(ws);
+  updateInstrumentView();
+}
+
+/**
+ * Overlay a mask workspace on the surface projection
+ * @param ws :: mask workspace to overlay
+ */
+void InstrumentWidget::overlayMaskedWorkspace(IMaskWorkspace_sptr ws) {
+  auto actor = getInstrumentActor();
+  actor->setMaskMatrixWorkspace(
+      boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(ws));
+  actor->updateColors();
+  updateInstrumentDetectors();
+  emit maskedWorkspaceOverlayed();
+}
+
+/**
+ * Overlay a table workspace containing shape parameters
+ * @param ws :: a workspace of shape parameters to create
+ */
+void InstrumentWidget::overlayShapesWorkspace(ITableWorkspace_sptr ws) {
+  auto surface = getUnwrappedSurface();
+  if (surface) {
+    surface->loadShapesFromTableWorkspace(ws);
+    updateInstrumentView();
+  }
+}
+
+/**
+ * Get a workspace from the ADS using its name
+ * @param name :: name of the workspace
+ * @return a handle to the workspace (null if not found)
+ */
+Workspace_sptr InstrumentWidget::getWorkspaceFromADS(const std::string &name) {
+  Workspace_sptr workspace;
+
+  try {
+    workspace = AnalysisDataService::Instance().retrieve(name);
+  } catch (std::runtime_error) {
+    QMessageBox::warning(this, "MantidPlot - Warning",
+                         "No workspace called '" +
+                             QString::fromStdString(name) + "' found. ");
+    return nullptr;
+  }
+
+  return workspace;
+}
+
+/**
+ * Get an unwrapped surface
+ * @return a handle to the unwrapped surface (or null if view was not found).
+ */
+boost::shared_ptr<UnwrappedSurface> InstrumentWidget::getUnwrappedSurface() {
+  auto surface = boost::dynamic_pointer_cast<UnwrappedSurface>(getSurface());
+  if (!surface) {
+    QMessageBox::warning(
+        this, "MantidPlot - Warning",
+        "Please change to an unwrapped view to overlay a workspace.");
+    return nullptr;
+  }
+  return surface;
+}
+
 int InstrumentWidget::getCurrentTab() const {
   return mControlsTab->currentIndex();
 }
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetMaskTab.cpp b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetMaskTab.cpp
index e78ba4deb84688dc8aa2cbdb972c0b92eb28f4f9..1e87d7507804688a27db3503c6be5c8ba15484ba 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetMaskTab.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetMaskTab.cpp
@@ -39,7 +39,6 @@
 #include <QAction>
 #include <QApplication>
 #include <QCheckBox>
-#include <QFileDialog>
 #include <QGridLayout>
 #include <QGroupBox>
 #include <QHBoxLayout>
@@ -201,6 +200,12 @@ InstrumentWidgetMaskTab::InstrumentWidgetMaskTab(InstrumentWidget *instrWidget)
   m_applyToView->setToolTip("Apply current mask to the view.");
   connect(m_applyToView, SIGNAL(clicked()), this, SLOT(applyMaskToView()));
 
+  m_saveShapesToTable = new QPushButton("Save Shapes to Table");
+  m_saveShapesToTable->setToolTip(
+      "Store the current Mask/ROI/Group shapes as a table");
+  connect(m_saveShapesToTable, SIGNAL(clicked()), this,
+          SLOT(saveShapesToTable()));
+
   m_clearAll = new QPushButton("Clear All");
   m_clearAll->setToolTip(
       "Clear all masking that have not been applied to the data.");
@@ -314,8 +319,9 @@ InstrumentWidgetMaskTab::InstrumentWidgetMaskTab(InstrumentWidget *instrWidget)
   QGroupBox *box = new QGroupBox("View");
   QGridLayout *buttons = new QGridLayout();
   buttons->addWidget(m_applyToView, 0, 0, 1, 2);
-  buttons->addWidget(m_saveButton, 1, 0);
-  buttons->addWidget(m_clearAll, 1, 1);
+  buttons->addWidget(m_saveShapesToTable, 1, 0, 1, 2);
+  buttons->addWidget(m_saveButton, 2, 0);
+  buttons->addWidget(m_clearAll, 2, 1);
 
   box->setLayout(buttons);
   layout->addWidget(box);
@@ -325,6 +331,9 @@ InstrumentWidgetMaskTab::InstrumentWidgetMaskTab(InstrumentWidget *instrWidget)
   buttons->addWidget(m_applyToData, 0, 0);
   box->setLayout(buttons);
   layout->addWidget(box);
+
+  connect(m_instrWidget, SIGNAL(maskedWorkspaceOverlayed()), this,
+          SLOT(enableApplyButtons()));
 }
 
 /**
@@ -579,6 +588,13 @@ void InstrumentWidgetMaskTab::setProperties() {
   shapeChanged();
 }
 
+/**
+ * Save shapes to a table workspace
+ */
+void InstrumentWidgetMaskTab::saveShapesToTable() const {
+  m_instrWidget->getSurface()->saveShapesToTableWorkspace();
+}
+
 void InstrumentWidgetMaskTab::doubleChanged(QtProperty *prop) {
   if (!m_userEditing)
     return;
@@ -1046,6 +1062,7 @@ void InstrumentWidgetMaskTab::enableApplyButtons() {
     m_applyToData->setEnabled(false);
     m_applyToView->setEnabled(false);
   }
+  m_saveShapesToTable->setEnabled(hasMaskShapes);
   m_saveButton->setEnabled(hasDetectorMask && (!enableBinMasking));
   m_clearAll->setEnabled(hasMask);
   setActivity();
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetRenderTab.cpp b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetRenderTab.cpp
index bac87256e2ef321ea30d470e2d73b6a50d5c6f6f..02d89b5281a1d4f5f4d885ee279d02390fb8c0f2 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetRenderTab.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/InstrumentWidgetRenderTab.cpp
@@ -12,7 +12,6 @@
 #include <QLabel>
 #include <QComboBox>
 #include <QCheckBox>
-#include <QFileDialog>
 #include <QFileInfo>
 #include <QSettings>
 #include <QAction>
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/ProjectionSurface.cpp b/MantidQt/MantidWidgets/src/InstrumentView/ProjectionSurface.cpp
index 99f4d7b8e58f784cb2db13a6a189e83408c9d419..b3b27eacd102e1821021bf5aa057be5f8c508de9 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/ProjectionSurface.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/ProjectionSurface.cpp
@@ -316,11 +316,15 @@ void ProjectionSurface::updateView(bool picking) {
 }
 
 void ProjectionSurface::updateDetectors() {
+  // updating detectors should not reset the view rect
+  // cache the value here are reapply after updating the detectors
+  auto viewRectCache = m_viewRect;
   clear();
   this->init();
   // if integration range in the instrument actor has changed
   // update visiblity of peak markers
   setPeakVisibility();
+  m_viewRect = viewRectCache;
 }
 
 /// Send a redraw request to the surface owner
@@ -593,6 +597,22 @@ void ProjectionSurface::startCreatingFreeShape(const QColor &borderColor,
   emit signalToStartCreatingFreeShape(borderColor, fillColor);
 }
 
+/**
+ * Save shapes drawn on the view to a table workspace
+ */
+void ProjectionSurface::saveShapesToTableWorkspace() {
+  m_maskShapes.saveToTableWorkspace();
+}
+
+/**
+ * Load shapes from a table workspace on to the view.
+ * @param ws :: table workspace to load shapes from
+ */
+void ProjectionSurface::loadShapesFromTableWorkspace(
+    Mantid::API::ITableWorkspace_const_sptr ws) {
+  m_maskShapes.loadFromTableWorkspace(ws);
+}
+
 /**
 * Return a combined list of peak parkers from all overlays
 * @param detID :: The detector ID of interest
diff --git a/MantidQt/MantidWidgets/src/InstrumentView/Shape2DCollection.cpp b/MantidQt/MantidWidgets/src/InstrumentView/Shape2DCollection.cpp
index e9240f8787d1accc77a95a276b3adf059e83ff27..7681c5c89c3a7097d30949552fbb7cfa5762da82 100644
--- a/MantidQt/MantidWidgets/src/InstrumentView/Shape2DCollection.cpp
+++ b/MantidQt/MantidWidgets/src/InstrumentView/Shape2DCollection.cpp
@@ -1,4 +1,8 @@
 #include "MantidQtMantidWidgets/InstrumentView/Shape2DCollection.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceFactory.h"
 
 #include <QPainter>
 #include <QMouseEvent>
@@ -621,6 +625,56 @@ void Shape2DCollection::changeBorderColor(const QColor &color) {
   foreach (Shape2D *shape, m_shapes) { shape->setColor(color); }
 }
 
+/**
+ * Save this shape collection to a table workspace
+ *
+ * This will create a table workspace called MaskShapes with one column for the
+ * index of the shape and one containing the serialised parameters of the shape
+ */
+void Shape2DCollection::saveToTableWorkspace() {
+  using namespace Mantid::API;
+  auto table = WorkspaceFactory::Instance().createTable();
+  table->addColumn("str", "Index");
+  table->addColumn("str", "Parameters");
+
+  size_t count = 0;
+  for (auto shape : m_shapes) {
+    auto shapeStr = shape->saveToProject();
+    TableRow row = table->appendRow();
+    row << std::to_string(count) << shapeStr;
+    ++count;
+  }
+
+  AnalysisDataService::Instance().addOrReplace("MaskShapes", table);
+}
+
+/**
+ * Load a collection of shapes from a table workspace
+ *
+ * This expects a table workspace with a column called parameters from which to
+ * load collection of shapes from.
+ *
+ * @param ws :: table workspace to load shapes from.
+ */
+void Shape2DCollection::loadFromTableWorkspace(
+    Mantid::API::ITableWorkspace_const_sptr ws) {
+  using namespace Mantid::API;
+  auto columnNames = ws->getColumnNames();
+
+  // Check if the column exists
+  if (std::find(columnNames.cbegin(), columnNames.cend(), "Parameters") ==
+      columnNames.cend())
+    return;
+
+  ConstColumnVector<std::string> col = ws->getVector("Parameters");
+  for (size_t i = 0; i < ws->rowCount(); ++i) {
+    const auto params = col[i];
+    auto shape = Shape2D::loadFromProject(params);
+    m_shapes.append(shape);
+  }
+  emit shapeCreated();
+}
+
 /**
 * Add a Shape2D object allowing free drawing.
 * @param poly :: Initial shape.
@@ -672,7 +726,8 @@ void Shape2DCollection::loadFromProject(const std::string &lines) {
   API::TSVSerialiser tsv(lines);
   for (auto shapeLines : tsv.sections("shape")) {
     Shape2D *shape = Shape2D::loadFromProject(shapeLines);
-    addShape(shape, false);
+    m_shapes.push_back(shape);
+    emit shapeCreated();
   }
 }
 
diff --git a/MantidQt/MantidWidgets/src/MWDiag.cpp b/MantidQt/MantidWidgets/src/MWDiag.cpp
index bc6867f12cb989ac9cdb25828204bd7c4c1452df..a832a84b69149bbc34ced9d3a2c15afb6b5faee2 100644
--- a/MantidQt/MantidWidgets/src/MWDiag.cpp
+++ b/MantidQt/MantidWidgets/src/MWDiag.cpp
@@ -2,7 +2,6 @@
 #include "MantidQtMantidWidgets/DiagResults.h"
 #include "MantidQtMantidWidgets/MWRunFiles.h"
 #include "MantidQtAPI/AlgorithmInputHistory.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
@@ -492,7 +491,7 @@ QString MWDiag::openFileDialog(const bool save, const QStringList &exts) {
 
   QString filename;
   if (save) {
-    filename = FileDialogHandler::getSaveFileName(
+    filename = QFileDialog::getSaveFileName(
         this, "Save file", m_prevSets.value("save file dir", "").toString(),
         filter);
     if (!filename.isEmpty()) {
diff --git a/MantidQt/MantidWidgets/src/MWRunFiles.cpp b/MantidQt/MantidWidgets/src/MWRunFiles.cpp
index a5addee02c46f293b713933a22b1833408911e85..cca9d2599fe2bbe7af578fc12c44a35275f1f473 100644
--- a/MantidQt/MantidWidgets/src/MWRunFiles.cpp
+++ b/MantidQt/MantidWidgets/src/MWRunFiles.cpp
@@ -227,10 +227,6 @@ MWRunFiles::MWRunFiles(QWidget *parent)
   doButtonOpt(m_buttonOpt);
 
   liveButtonState(m_liveButtonState);
-  connect(this, SIGNAL(liveButtonSetEnabledSignal(bool)), m_uiForm.liveButton,
-          SLOT(setEnabled(bool)));
-  connect(this, SIGNAL(liveButtonSetEnabledSignal(bool)), m_uiForm.liveButton,
-          SLOT(show()));
   connect(m_uiForm.liveButton, SIGNAL(toggled(bool)), this,
           SIGNAL(liveButtonPressed(bool)));
 
@@ -450,30 +446,11 @@ void MWRunFiles::liveButtonState(const LiveButtonOpts option) {
   m_liveButtonState = option;
   if (m_liveButtonState == Hide) {
     m_uiForm.liveButton->hide();
-  } else {
-    liveButtonSetEnabled(false); // This setting ensures right outcome if the
-                                 // connection check fails
-    // Checks (asynchronously) whether it's possible to connect to the user's
-    // default instrument
-    QtConcurrent::run(this, &MWRunFiles::checkLiveConnection);
-    if (m_liveButtonState == AlwaysShow) {
-      m_uiForm.liveButton->show();
-    }
+  } else if (m_liveButtonState == Show) {
+    m_uiForm.liveButton->show();
   }
 }
 
-void MWRunFiles::checkLiveConnection() {
-  // Checks whether it's possible to connect to the user's default instrument
-  if (LiveListenerFactory::Instance().checkConnection(
-          ConfigService::Instance().getInstrument().name())) {
-    emit liveButtonSetEnabledSignal(true);
-  }
-}
-
-void MWRunFiles::liveButtonSetEnabled(const bool enabled) {
-  m_uiForm.liveButton->setEnabled(enabled);
-}
-
 void MWRunFiles::liveButtonSetChecked(const bool checked) {
   m_uiForm.liveButton->setChecked(checked);
 }
@@ -997,13 +974,13 @@ QString MWRunFiles::openFileDialog() {
     if (!file.isEmpty())
       filenames.append(file);
   } else if (m_allowMultipleFiles) {
-    filenames =
-        QFileDialog::getOpenFileNames(this, "Open file", dir, m_fileFilter, 0,
-                                      QFileDialog::DontResolveSymlinks);
+    filenames = QFileDialog::getOpenFileNames(this, "Open file", dir,
+                                              m_fileFilter, nullptr,
+                                              QFileDialog::DontResolveSymlinks);
   } else {
     QString file =
-        QFileDialog::getOpenFileName(this, "Open file", dir, m_fileFilter, 0,
-                                     QFileDialog::DontResolveSymlinks);
+        QFileDialog::getOpenFileName(this, "Open file", dir, m_fileFilter,
+                                     nullptr, QFileDialog::DontResolveSymlinks);
     if (!file.isEmpty())
       filenames.append(file);
   }
diff --git a/MantidQt/MantidWidgets/src/MantidTreeWidgetItem.cpp b/MantidQt/MantidWidgets/src/MantidTreeWidgetItem.cpp
index eed5ee7694e3f0f25a8f75263acd06e986e33218..3febd4801807e6f68728b8703c7b0f9267cf90c3 100644
--- a/MantidQt/MantidWidgets/src/MantidTreeWidgetItem.cpp
+++ b/MantidQt/MantidWidgets/src/MantidTreeWidgetItem.cpp
@@ -2,6 +2,7 @@
 #include "MantidQtMantidWidgets/MantidTreeWidget.h"
 
 #include <MantidAPI/Workspace.h>
+#include "MantidAPI/WorkspaceHistory.h"
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
diff --git a/MantidQt/MantidWidgets/src/MantidWSIndexDialog.cpp b/MantidQt/MantidWidgets/src/MantidWSIndexDialog.cpp
index 03f7883d3fa109d5d25c265d37a265b4ab05a476..f208541830a3cd8d507bd1e8bb93d66759e12faa 100644
--- a/MantidQt/MantidWidgets/src/MantidWSIndexDialog.cpp
+++ b/MantidQt/MantidWidgets/src/MantidWSIndexDialog.cpp
@@ -1,7 +1,5 @@
-//----------------------------------
-// Includes
-//----------------------------------
 #include "MantidQtMantidWidgets/MantidWSIndexDialog.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/Axis.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/SpectraDetectorTypes.h"
diff --git a/MantidQt/MantidWidgets/src/MuonFitPropertyBrowser.cpp b/MantidQt/MantidWidgets/src/MuonFitPropertyBrowser.cpp
index cfa570583f7a7c04d5db9f9ada88282388769f09..49d9ca84a7b9eb82302be339daf53963a40b3a06 100644
--- a/MantidQt/MantidWidgets/src/MuonFitPropertyBrowser.cpp
+++ b/MantidQt/MantidWidgets/src/MuonFitPropertyBrowser.cpp
@@ -4,6 +4,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/TableRow.h"
+#include "MantidAPI/WorkspaceGroup.h"
 #include "MantidQtMantidWidgets/StringEditorFactory.h"
 
 // Suppress a warning coming out of code that isn't ours
diff --git a/MantidQt/MantidWidgets/src/ProcessingAlgoWidget.cpp b/MantidQt/MantidWidgets/src/ProcessingAlgoWidget.cpp
index f7b08ce64b7621d3bb0432b0026ad3ebac7e76f6..b6b356851b6aa264b658d7baad5771112b395fa4 100644
--- a/MantidQt/MantidWidgets/src/ProcessingAlgoWidget.cpp
+++ b/MantidQt/MantidWidgets/src/ProcessingAlgoWidget.cpp
@@ -2,7 +2,6 @@
 #include <Qsci/qscilexerpython.h>
 #include "MantidAPI/Algorithm.h"
 #include "MantidAPI/AlgorithmManager.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include <iosfwd>
 #include <fstream>
 #include <QFileInfo>
@@ -75,7 +74,7 @@ void ProcessingAlgoWidget::saveSettings() {
 /** Slot called when the save button is clicked */
 void ProcessingAlgoWidget::btnSaveClicked() {
   // Save to a .py file
-  QString fileselection = MantidQt::API::FileDialogHandler::getSaveFileName(
+  QString fileselection = QFileDialog::getSaveFileName(
       this, "Save a Python Script", QFileInfo(m_lastFile).absoluteFilePath(),
       "Python scripts (*.py);;All files (*)");
   if (!fileselection.isEmpty()) {
diff --git a/MantidQt/MantidWidgets/src/SaveWorkspaces.cpp b/MantidQt/MantidWidgets/src/SaveWorkspaces.cpp
index e0582c8b5fdf186f37fc6543e36a1f463532942e..076773096edc72c0bbf301612da4bb82288b8d1f 100644
--- a/MantidQt/MantidWidgets/src/SaveWorkspaces.cpp
+++ b/MantidQt/MantidWidgets/src/SaveWorkspaces.cpp
@@ -2,7 +2,6 @@
 // Includes
 //----------------------
 #include "MantidQtMantidWidgets/SaveWorkspaces.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileProperty.h"
@@ -11,16 +10,17 @@
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/ConfigService.h"
 
-#include <QLabel>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QPushButton>
-#include <QDoubleValidator>
 #include <QCloseEvent>
-#include <QShowEvent>
+#include <QDoubleValidator>
+#include <QFileDialog>
 #include <QGroupBox>
-#include <QSettings>
+#include <QHBoxLayout>
+#include <QLabel>
 #include <QMessageBox>
+#include <QPushButton>
+#include <QSettings>
+#include <QShowEvent>
+#include <QVBoxLayout>
 
 namespace {
 void setDetectorNamesOnCanSasFormat(QString &saveCommands,
@@ -387,8 +387,8 @@ void SaveWorkspaces::saveFileBrowse() {
   QFileDialog::Option userCon = m_append->isChecked()
                                     ? QFileDialog::DontConfirmOverwrite
                                     : static_cast<QFileDialog::Option>(0);
-  QString oFile = API::FileDialogHandler::getSaveFileName(
-      this, title, prevPath, filter, NULL, userCon);
+  QString oFile = QFileDialog::getSaveFileName(this, title, prevPath, filter,
+                                               NULL, userCon);
 
   if (!oFile.isEmpty()) {
     m_fNameEdit->setText(oFile);
diff --git a/MantidQt/MantidWidgets/src/ScriptEditor.cpp b/MantidQt/MantidWidgets/src/ScriptEditor.cpp
index 8b1abc4605119336449d7ae817dd3411022c9db2..2eabd6fcbabc29a9293750129b0c0bc1b6360068 100644
--- a/MantidQt/MantidWidgets/src/ScriptEditor.cpp
+++ b/MantidQt/MantidWidgets/src/ScriptEditor.cpp
@@ -3,12 +3,10 @@
 //-----------------------------------------------
 #include "MantidQtMantidWidgets/ScriptEditor.h"
 #include "MantidQtMantidWidgets/FindReplaceDialog.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 
 // Qt
 #include <QApplication>
 #include <QFile>
-#include <QFileInfo>
 #include <QFileDialog>
 
 #include <QTextStream>
@@ -260,8 +258,8 @@ QSize ScriptEditor::sizeHint() const { return QSize(600, 500); }
 void ScriptEditor::saveAs() {
   QString selectedFilter;
   QString filter = "Scripts (*.py *.PY);;All Files (*)";
-  QString filename = MantidQt::API::FileDialogHandler::getSaveFileName(
-      NULL, "MantidPlot - Save", "", filter, &selectedFilter);
+  QString filename = QFileDialog::getSaveFileName(NULL, "MantidPlot - Save", "",
+                                                  filter, &selectedFilter);
 
   if (filename.isEmpty()) {
     throw SaveCancelledException();
diff --git a/MantidQt/MantidWidgets/src/StringDialogEditor.cpp b/MantidQt/MantidWidgets/src/StringDialogEditor.cpp
index c9da15cc8c0a8ae5634104bc8c3c64574b8fa047..2254036b33141aee89a81565e5a422427feb98bf 100644
--- a/MantidQt/MantidWidgets/src/StringDialogEditor.cpp
+++ b/MantidQt/MantidWidgets/src/StringDialogEditor.cpp
@@ -3,7 +3,6 @@
 #include <QHBoxLayout>
 #include <QLineEdit>
 #include <QPushButton>
-#include <QFileDialog>
 #include <QLabel>
 #include <QDialog>
 #include <QSettings>
diff --git a/MantidQt/MantidWidgets/src/TrackedAction.cpp b/MantidQt/MantidWidgets/src/TrackedAction.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d94c3259e5cf0fc5cb329df7ae51c1d670b95b8e
--- /dev/null
+++ b/MantidQt/MantidWidgets/src/TrackedAction.cpp
@@ -0,0 +1,100 @@
+#include "MantidQtMantidWidgets/TrackedAction.h"
+#include "MantidKernel/UsageService.h"
+#include <QCoreApplication>
+
+namespace MantidQt {
+namespace MantidWidgets {
+
+/** Constructor
+*   @param parent The parent of this action
+**/
+TrackedAction::TrackedAction(QObject *parent)
+    : QAction(parent), m_isTracking(true), m_trackingName() {
+  setupTracking();
+}
+
+/** Constructor
+*   @param text The text for the action
+*   @param parent The parent of this action
+**/
+TrackedAction::TrackedAction(const QString &text, QObject *parent)
+    : QAction(text, parent), m_isTracking(true), m_trackingName() {
+  setupTracking();
+}
+
+/** Constructor
+*   @param icon The icon for the action
+*   @param text The text for the action
+*   @param parent The parent of this action
+**/
+TrackedAction::TrackedAction(const QIcon &icon, const QString &text,
+                             QObject *parent)
+    : QAction(icon, text, parent), m_isTracking(true), m_trackingName() {
+  setupTracking();
+}
+
+/** Sets the tracking name for this action
+*   @param name the tracking name for this action
+**/
+void TrackedAction::setTrackingName(const std::string &name) {
+  m_trackingName = name;
+}
+
+/** Gets the tracking name for this action
+*   If the tacking name is not set a default name will be generated using
+*   generateTrackingName
+*   @returns The tracking name for this action
+**/
+std::string TrackedAction::getTrackingName() const {
+  if (m_trackingName.empty()) {
+    m_trackingName = generateTrackingName();
+  }
+  return m_trackingName;
+}
+
+/** Sets whether this action is tracking usage
+*   @param enableTracking True if the action should tracking usage
+**/
+void TrackedAction::setIsTracking(const bool enableTracking) {
+  m_isTracking = enableTracking;
+}
+
+/** Gets whether this action is tracking usage
+*   @returns True if the action is tracking usage
+**/
+bool TrackedAction::getIsTracking() const { return m_isTracking; }
+
+/** Sets up tracking for the class
+**/
+void TrackedAction::setupTracking() {
+  connect(this, SIGNAL(triggered(bool)), this, SLOT(trackActivation(bool)));
+}
+
+/** Creates a tracking name from the action text
+*   @returns A generated name using ApplicationName->ActionText
+**/
+std::string TrackedAction::generateTrackingName() const {
+  return QCoreApplication::applicationName().toStdString() + "->" +
+         QAction::text().remove("&").remove(" ").toStdString();
+}
+
+/** Registers the feature usage if usage is enabled
+*   @param checked Whether the QAction is checked
+**/
+void TrackedAction::trackActivation(const bool checked) {
+  UNUSED_ARG(checked);
+  if (m_isTracking) {
+    // do tracking
+    registerUsage(getTrackingName());
+  }
+}
+
+/** Registers the feature usage with the usage service
+*   @param name The name to use when registering usage
+**/
+void TrackedAction::registerUsage(const std::string &name) {
+  Mantid::Kernel::UsageService::Instance().registerFeatureUsage("Feature", name,
+                                                                false);
+}
+} // namespace MantidWidgets
+} // namespace Mantid
diff --git a/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorGenerateNotebookTest.h b/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorGenerateNotebookTest.h
index b3c7f4b3ec37c10b448fa69d4bdd1124411b9c9b..e411fe24dcaf46a3d2f5a8846f411dce334f5f7d 100644
--- a/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorGenerateNotebookTest.h
+++ b/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorGenerateNotebookTest.h
@@ -5,6 +5,10 @@
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/split.hpp>
+
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorGenerateNotebook.h"
 #include "MantidQtMantidWidgets/DataProcessorUI/DataProcessorVectorString.h"
diff --git a/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h b/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h
index 36caca5e12dfe14ebd689a5ad0613825f15f37ed..680b9238846271ee6d88e7b599dc990f417909ee 100644
--- a/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h
+++ b/MantidQt/MantidWidgets/test/DataProcessorUI/DataProcessorTwoLevelTreeManagerTest.h
@@ -319,6 +319,19 @@ public:
     TS_ASSERT_EQUALS(data[1][1], fourthRow);
   }
 
+  void test_new_table_clears_model() {
+    NiceMock<MockDataProcessorPresenter> presenter;
+    auto table = reflTable();
+    auto whitelist = reflWhitelist();
+    DataProcessorTwoLevelTreeManager manager(&presenter, whitelist);
+
+    TS_ASSERT_THROWS_NOTHING(manager.newTable(table, whitelist));
+    TS_ASSERT_EQUALS(manager.getTableWorkspace()->rowCount(), 4);
+
+    TS_ASSERT_THROWS_NOTHING(manager.newTable(whitelist));
+    TS_ASSERT_EQUALS(manager.getTableWorkspace()->rowCount(), 0);
+  }
+
   void test_transfer_fails_no_group() {
     NiceMock<MockDataProcessorPresenter> presenter;
     DataProcessorTwoLevelTreeManager manager(&presenter, reflWhitelist());
diff --git a/MantidQt/MantidWidgets/test/TrackedActionTest.h b/MantidQt/MantidWidgets/test/TrackedActionTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..5be95a63207ef5de85c46b378721e3321cd47e7c
--- /dev/null
+++ b/MantidQt/MantidWidgets/test/TrackedActionTest.h
@@ -0,0 +1,80 @@
+#ifndef MANTID_MANTIDWIDGETS_TRACKEDACTIONEST_H_
+#define MANTID_MANTIDWIDGETS_TRACKEDACTIONEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidQtMantidWidgets/TrackedAction.h"
+#include <QCoreApplication>
+
+using MantidQt::MantidWidgets::TrackedAction;
+
+class TrackedActionTest : public CxxTest::TestSuite {
+  // inner class
+  class TestableTrackedAction : public TrackedAction {
+  public:
+    TestableTrackedAction(QObject *parent)
+        : TrackedAction(parent), m_lastName(){};
+    TestableTrackedAction(const QString &text, QObject *parent)
+        : TrackedAction(text, parent), m_lastName(){};
+    TestableTrackedAction(const QIcon &icon, const QString &text,
+                          QObject *parent)
+        : TrackedAction(icon, text, parent), m_lastName(){};
+
+    std::string getLastUsedName() const { return m_lastName; };
+
+  protected:
+    void registerUsage(const std::string &name) override { m_lastName = name; };
+
+  private:
+    std::string m_lastName;
+  };
+
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static TrackedActionTest *createSuite() { return new TrackedActionTest(); }
+  static void destroySuite(TrackedActionTest *suite) { delete suite; }
+
+  void testIsTrackingGetSetGet() {
+    QObject parent;
+    TestableTrackedAction action(&parent);
+
+    TS_ASSERT_EQUALS(action.getIsTracking(), true); // default state
+    action.setIsTracking(false);
+    TS_ASSERT_EQUALS(action.getIsTracking(), false); // altered state
+  }
+
+  void testTrackingNameGetSetGet() {
+    QObject parent;
+    TestableTrackedAction action(QString::fromStdString("TestName"), &parent);
+
+    std::string appNamePrefix =
+        QCoreApplication::applicationName().toStdString() + "->";
+
+    TS_ASSERT_EQUALS(action.getTrackingName(),
+                     appNamePrefix + "TestName"); // default state
+    action.setTrackingName("TestName2");
+    TS_ASSERT_EQUALS(action.getTrackingName(), "TestName2"); // altered state
+  }
+
+  void testTrackingCallLogic() {
+    QObject parent;
+    TestableTrackedAction action(QString::fromStdString("TestName"), &parent);
+
+    // tracking should be on by default
+    TS_ASSERT_EQUALS(action.getIsTracking(), true); // default state
+    TS_ASSERT_EQUALS(action.getLastUsedName(), ""); // default state
+
+    action.setTrackingName("ShouldTrack");
+    action.trigger();
+    TS_ASSERT_EQUALS(action.getLastUsedName(),
+                     "ShouldTrack"); // tracking occurred state
+    action.setIsTracking(false);
+    action.setTrackingName("ShouldNotTrack");
+    action.trigger();
+    TS_ASSERT_DIFFERS(action.getLastUsedName(),
+                      "ShouldNotTrack"); // Should not have tracked
+  }
+};
+
+#endif /* MANTID_MANTIDWIDGETS_TRACKEDACTIONEST_H_ */
\ No newline at end of file
diff --git a/MantidQt/MantidWidgets/test/WorkspacePresenter/ADSAdapterTest.h b/MantidQt/MantidWidgets/test/WorkspacePresenter/ADSAdapterTest.h
index 6aa92ce63da6c4259520973f87b30423874ecd3c..b113580f74fc8b734db9e21f8c94b001c6c1409a 100644
--- a/MantidQt/MantidWidgets/test/WorkspacePresenter/ADSAdapterTest.h
+++ b/MantidQt/MantidWidgets/test/WorkspacePresenter/ADSAdapterTest.h
@@ -26,7 +26,7 @@ public:
   }
 
   void testLoadWorkspaceIntoADS() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     EXPECT_CALL(*mockPresenter.get(),
                 notifyFromWorkspaceProvider(NotifyFlag::WorkspaceLoaded))
@@ -38,7 +38,7 @@ public:
   }
 
   void testRemoveWorkspaceFromADS() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp", wksp);
 
@@ -52,8 +52,8 @@ public:
   }
 
   void testClearADS() {
-    auto wksp1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto wksp2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto wksp2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp1", wksp1);
     AnalysisDataService::Instance().add("wksp2", wksp2);
@@ -68,7 +68,7 @@ public:
   }
 
   void testRenameWorkspace() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("wksp", wksp);
     EXPECT_CALL(*mockPresenter.get(),
                 notifyFromWorkspaceProvider(NotifyFlag::WorkspaceRenamed))
@@ -102,12 +102,12 @@ public:
   }
 
   void testWorkspaceGroupUpdated() {
-    auto wksp1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto wksp2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto wksp3 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto wksp2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto wksp3 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     auto group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(0, 10, 10, "group");
+        WorkspaceCreationHelper::createWorkspaceGroup(0, 10, 10, "group");
 
     AnalysisDataService::Instance().add("wksp1", wksp1);
     AnalysisDataService::Instance().add("wksp2", wksp2);
@@ -127,4 +127,4 @@ public:
 private:
   boost::shared_ptr<NiceMock<MockWorkspaceProviderNotifiable>> mockPresenter;
   ADSAdapter adapter;
-};
\ No newline at end of file
+};
diff --git a/MantidQt/MantidWidgets/test/WorkspacePresenter/WorkspacePresenterTest.h b/MantidQt/MantidWidgets/test/WorkspacePresenter/WorkspacePresenterTest.h
index e014cfd3f3c222d670ea9e9609e36ca0ecd4fb45..3d0ebddeca4e12019690b0a6ac1515edfe5d09cf 100644
--- a/MantidQt/MantidWidgets/test/WorkspacePresenter/WorkspacePresenterTest.h
+++ b/MantidQt/MantidWidgets/test/WorkspacePresenter/WorkspacePresenterTest.h
@@ -8,6 +8,7 @@
 #include <MantidAPI/AlgorithmManager.h>
 #include <MantidAPI/AnalysisDataService.h>
 #include <MantidAPI/FrameworkManager.h>
+#include <MantidAPI/WorkspaceGroup.h>
 #include <MantidTestHelpers/WorkspaceCreationHelper.h>
 
 #include <algorithm>
@@ -52,7 +53,7 @@ public:
   }
 
   void testLoadWorkspaceExternal() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     EXPECT_CALL(*mockView.get(), updateTree(_)).Times(AtLeast(1));
 
@@ -64,8 +65,8 @@ public:
   }
 
   void testDeleteWorkspacesFromDockWithPrompt() {
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
     AnalysisDataService::Instance().add("ws2", ws2);
 
@@ -88,8 +89,8 @@ public:
   }
 
   void testDeleteWorkspacesFromDockWithPromptUserDecline() {
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
     AnalysisDataService::Instance().add("ws2", ws2);
 
@@ -110,8 +111,8 @@ public:
   }
 
   void testDeleteWorkspacesFromDockWithoutPrompt() {
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
     AnalysisDataService::Instance().add("ws2", ws2);
 
@@ -144,7 +145,7 @@ public:
   }
 
   void testDeleteWorkspacesExternal() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp", wksp);
 
@@ -156,7 +157,7 @@ public:
   }
 
   void testADSCleared() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp", wksp);
 
@@ -180,7 +181,7 @@ public:
   }
 
   void testRenameWorkspaceExternal() {
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp", wksp);
 
@@ -194,8 +195,8 @@ public:
   }
 
   void testWorkspacesGrouped() {
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
     AnalysisDataService::Instance().add("ws2", ws2);
     ::testing::DefaultValue<StringList>::Set(StringList{"ws1", "ws2"});
@@ -235,8 +236,8 @@ public:
 
   void testGroupAlreadyExistsUserConfirm() {
     createGroup("NewGroup");
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto ws2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto ws2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
     AnalysisDataService::Instance().add("ws2", ws2);
 
@@ -356,7 +357,7 @@ public:
     std::string groupName = "group";
     createGroup(groupName);
 
-    auto wksp = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto wksp = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("wksp", wksp);
 
     EXPECT_CALL(*mockView.get(), updateTree(_)).Times(AtLeast(1));
@@ -629,7 +630,7 @@ public:
 
   void testClearUBMatrix() {
     ::testing::DefaultValue<StringList>::Set(StringList{"ws1"});
-    auto ws1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+    auto ws1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
     AnalysisDataService::Instance().add("ws1", ws1);
 
     // Setup a UB matrix before attempting to remove it
@@ -665,9 +666,9 @@ private:
 
   void createGroup(std::string groupName) {
     auto group =
-        WorkspaceCreationHelper::CreateWorkspaceGroup(0, 10, 10, groupName);
-    auto wksp1 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
-    auto wksp2 = WorkspaceCreationHelper::Create2DWorkspace(10, 10);
+        WorkspaceCreationHelper::createWorkspaceGroup(0, 10, 10, groupName);
+    auto wksp1 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
+    auto wksp2 = WorkspaceCreationHelper::create2DWorkspace(10, 10);
 
     AnalysisDataService::Instance().add("wksp1", wksp1);
     AnalysisDataService::Instance().add("wksp2", wksp2);
@@ -678,4 +679,4 @@ private:
   void removeGroup(std::string groupName) {
     AnalysisDataService::Instance().deepRemoveGroup(groupName);
   }
-};
\ No newline at end of file
+};
diff --git a/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp b/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp
index bffc65231b13fa68deae4972de28d18d21b1e40d..28d73d639fb48ebb0cce65961e3c0f00631f5b29 100644
--- a/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp
+++ b/MantidQt/RefDetectorViewer/src/RefMatrixWSImageView.cpp
@@ -1,6 +1,7 @@
 #include "MantidQtRefDetectorViewer/RefMatrixWSImageView.h"
 #include "MantidQtSpectrumViewer/ArrayDataSource.h"
 #include "MantidQtRefDetectorViewer/RefIVConnections.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/WorkspaceProperty.h"
 #include "MantidAPI/Algorithm.h"
 #include "MantidKernel/System.h"
diff --git a/MantidQt/SliceViewer/src/LinePlotOptions.cpp b/MantidQt/SliceViewer/src/LinePlotOptions.cpp
index cf8e90709dc88ace4dd9989d9c064a4c0806e41b..959c39b6fded0ca09420718f4a18ebd3d4ddb38b 100644
--- a/MantidQt/SliceViewer/src/LinePlotOptions.cpp
+++ b/MantidQt/SliceViewer/src/LinePlotOptions.cpp
@@ -1,3 +1,4 @@
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "../inc/MantidQtSliceViewer/LinePlotOptions.h"
 #include "MantidQtAPI/TSVSerialiser.h"
 
diff --git a/MantidQt/SliceViewer/src/LineViewer.cpp b/MantidQt/SliceViewer/src/LineViewer.cpp
index 39a66108343a0b48f230bb3e1277ff9c32ce6ead..0d5009c641600fdf4e3e103fa4549107955047e5 100644
--- a/MantidQt/SliceViewer/src/LineViewer.cpp
+++ b/MantidQt/SliceViewer/src/LineViewer.cpp
@@ -6,6 +6,7 @@
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/UsageService.h"
 #include "MantidKernel/VMD.h"
 #include "MantidQtAPI/AlgorithmRunner.h"
diff --git a/MantidQt/SliceViewer/src/SliceViewer.cpp b/MantidQt/SliceViewer/src/SliceViewer.cpp
index b58a99e996165e71230e6ac98b3978a678e8c203..248f90eab330f5ee7dfb8650120c53b96b5c9194 100644
--- a/MantidQt/SliceViewer/src/SliceViewer.cpp
+++ b/MantidQt/SliceViewer/src/SliceViewer.cpp
@@ -4,7 +4,9 @@
 #include <vector>
 #include <boost/make_shared.hpp>
 
+#include "MantidKernel/Strings.h"
 #include "MantidKernel/UsageService.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/CoordTransform.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/IMDIterator.h"
@@ -20,7 +22,6 @@
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidGeometry/MDGeometry/MDTypes.h"
 #include "MantidKernel/ReadLock.h"
-#include "MantidQtAPI/FileDialogHandler.h"
 #include "MantidQtAPI/PlotAxis.h"
 #include "MantidQtAPI/MantidDesktopServices.h"
 #include "MantidQtAPI/MdSettings.h"
@@ -1295,7 +1296,7 @@ QString SliceViewer::ensurePngExtension(const QString &fname) const {
 void SliceViewer::saveImage(const QString &filename) {
   QString fileselection;
   if (filename.isEmpty()) {
-    fileselection = MantidQt::API::FileDialogHandler::getSaveFileName(
+    fileselection = QFileDialog::getSaveFileName(
         this, tr("Pick a file to which to save the image"),
         QFileInfo(m_lastSavedFile).absoluteFilePath(),
         tr("PNG files(*.png *.png)"));
diff --git a/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h b/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h
index 7bca2c99e66e46df18b2b7fb44e6b840d095856c..f7a9bf7d1aa29ac95e5389be8016cb2f0cfb534c 100644
--- a/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h
+++ b/MantidQt/SliceViewer/test/CompositePeaksPresenterTest.h
@@ -6,6 +6,7 @@
 #include "MantidQtSliceViewer/CompositePeaksPresenter.h"
 #include "MantidQtSliceViewer/NullPeaksPresenter.h"
 #include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MockObjects.h"
 
 using namespace MantidQt::SliceViewer;
diff --git a/MantidQt/SliceViewer/test/MockObjects.h b/MantidQt/SliceViewer/test/MockObjects.h
index e0e55c75e222408b01bf4019c306de5801c54852..e62e17e9431759d6c09fb1e7474fd039e07830f0 100644
--- a/MantidQt/SliceViewer/test/MockObjects.h
+++ b/MantidQt/SliceViewer/test/MockObjects.h
@@ -6,6 +6,7 @@
 #include "MantidGeometry/Crystal/IPeak.h"
 #include "MantidGeometry/Crystal/PeakTransform.h"
 #include "MantidGeometry/Crystal/PeakTransformFactory.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidKernel/UnitLabel.h"
 #include "MantidKernel/WarningSuppressions.h"
 #include "MantidQtSliceViewer/PeakOverlayView.h"
diff --git a/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp b/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp
index 998a2b34757dc97815b994bd4abf4e935414009f..7adf2e811d1f4d43de43e5b50b40c2dd5db006ea 100644
--- a/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp
+++ b/MantidQt/SpectrumViewer/src/MatrixWSDataSource.cpp
@@ -15,6 +15,7 @@
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/ISpectrum.h"
 #include "MantidGeometry/Instrument/Detector.h"
+#include "MantidGeometry/Instrument/Goniometer.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/Unit.h"
diff --git a/Testing/Data/SystemTest/ENGINX193749_calibration_spec651.nxs.md5 b/Testing/Data/SystemTest/ENGINX193749_calibration_spec651.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..08de317c6839811bcfd49e5a88a462a541fb5d26
--- /dev/null
+++ b/Testing/Data/SystemTest/ENGINX193749_calibration_spec651.nxs.md5
@@ -0,0 +1 @@
+cf09048bb10e7e10c381c92db5373225
diff --git a/Testing/Data/SystemTest/ENGINX236516_vanadium_bank1.nxs.md5 b/Testing/Data/SystemTest/ENGINX236516_vanadium_bank1.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1503e40c721663cac288cd83fa32eae2c5a6f13c
--- /dev/null
+++ b/Testing/Data/SystemTest/ENGINX236516_vanadium_bank1.nxs.md5
@@ -0,0 +1 @@
+e5262f4b8faee3aeb0670dc6a6a79c70
diff --git a/Testing/Data/SystemTest/EVS14188-90_peaks.nxs.md5 b/Testing/Data/SystemTest/EVS14188-90_peaks.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c78bd5e0903037b655801518b920b48f52296ccd
--- /dev/null
+++ b/Testing/Data/SystemTest/EVS14188-90_peaks.nxs.md5
@@ -0,0 +1 @@
+ad4f858fb125ca3baeb53e176a84f725
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DIAMON2D.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DIAMON2D.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..51fe156bfa8fc9cb9bf315e6095c47fc69d4fe18
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DIAMON2D.dat.md5
@@ -0,0 +1 @@
+6932c34dc495a3dff1b9922e312695f3
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DMN15102LS.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DMN15102LS.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..dc0dc9d49667a41bd04bb827b704909b5107b7a2
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/DMN15102LS.dat.md5
@@ -0,0 +1 @@
+82099c7fbc6dc3a8de4b9217ae563ed5
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER6C.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER6C.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..0aeaf584df8229b0ec0a53b56160613e46e2607a
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER6C.dat.md5
@@ -0,0 +1 @@
+da35838eaec5e81808242156059412a0
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER7C.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER7C.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1b5f52b11b677af80fcde7db5b85665c36ef8745
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER7C.dat.md5
@@ -0,0 +1 @@
+6a995d22ba05590931b142e9feab0d88
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER8C.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER8C.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..553bf242eda15c07a79145b6eaceffb2fdf4d878
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/PALMER8C.dat.md5
@@ -0,0 +1 @@
+2ab8ce743107eb738ba99094c9957cb7
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VESUVIOLS.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VESUVIOLS.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..92928d169bc74d5f766629c1f1cf1bcaeb81472e
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VESUVIOLS.dat.md5
@@ -0,0 +1 @@
+58c89b19a947308dd4609e6743f26434
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VIBRBEAM.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VIBRBEAM.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..51fe156bfa8fc9cb9bf315e6095c47fc69d4fe18
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/VIBRBEAM.dat.md5
@@ -0,0 +1 @@
+6932c34dc495a3dff1b9922e312695f3
diff --git a/Testing/Data/SystemTest/FittingTestProblems/CUTEst/YFITU.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/YFITU.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..582f18effd743287f207425d817e48d3b98fe1fe
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/CUTEst/YFITU.dat.md5
@@ -0,0 +1 @@
+8a9dd1453a5133b7f273838ebf932482
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Bennett5.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Bennett5.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..51fe156bfa8fc9cb9bf315e6095c47fc69d4fe18
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Bennett5.dat.md5
@@ -0,0 +1 @@
+6932c34dc495a3dff1b9922e312695f3
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/BoxBOD.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/BoxBOD.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5cb9652e59f25ca445e4c978d5545a4f625c744c
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/BoxBOD.dat.md5
@@ -0,0 +1 @@
+be28381269aeec353f6272ebc50d378e
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut1.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut1.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..391b51d07825b50d45de7b7f56463aad8bb3b920
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut1.dat.md5
@@ -0,0 +1 @@
+fe023591c01067f2ba0b4a2f71da39b6
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut2.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut2.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c41cfaad110eb6958b12641f9e851bf004e16697
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Chwirut2.dat.md5
@@ -0,0 +1 @@
+03c03c5ce0965a569e9c5eb79a275ed0
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/DanWood.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/DanWood.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..07efbd62ffb3a666eabd50e8c7e9be645f037e36
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/DanWood.dat.md5
@@ -0,0 +1 @@
+3021097cf0fae99affd670d1e8e0ffa4
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/ENSO.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/ENSO.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..f4fb9ce4df0f0d5c29584b399b8744c0ebff03ad
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/ENSO.dat.md5
@@ -0,0 +1 @@
+4a09069042123934377380f82dae3b05
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Eckerle4.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Eckerle4.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..3fd84a8abf876cf1501153e8b996de4a0be61650
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Eckerle4.dat.md5
@@ -0,0 +1 @@
+d5c6719f27ca3177fbe207455b95b8ed
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss1.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss1.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5745b7d6cceba8e3907368ce02b239cc44ae61a9
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss1.dat.md5
@@ -0,0 +1 @@
+8192d4256dc45613dd1e44e115330f5e
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss2.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss2.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..6436dc8037c16ccc9b9da7b9ef5458ecc503a910
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss2.dat.md5
@@ -0,0 +1 @@
+09e1e27e2df64ea776d60b04e4f8e56a
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss3.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss3.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..e9ca6d92c5c65500d247ec9a742824d0e72a354c
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Gauss3.dat.md5
@@ -0,0 +1 @@
+63f81fbacbb68705d4cc3e34b40d0f5e
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Hahn1.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Hahn1.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..ca3ad5c0e96de9a0037a97a5e2084c302a10622e
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Hahn1.dat.md5
@@ -0,0 +1 @@
+490de048c82e4e2e4a2ce93500ea3dc9
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Kirby2.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Kirby2.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..2bba9aaa8b0f6c0b51b6cb8031f3c7900b88dd0d
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Kirby2.dat.md5
@@ -0,0 +1 @@
+527d973fc9afbb3f5dc2461071ddc854
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos1.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos1.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..7d318d06287b41514b11072347b0776b7473d6bf
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos1.dat.md5
@@ -0,0 +1 @@
+294e0a2ee9e98d13f707b76fb139e364
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos2.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos2.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..f97dd2c9cb610861a791df25c0b6c98145ca2a2c
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos2.dat.md5
@@ -0,0 +1 @@
+cde7f529948475c64f733f1de64c428e
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos3.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos3.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..22df8dcd95a68020c876e4e118a7c4b6be15911e
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Lanczos3.dat.md5
@@ -0,0 +1 @@
+22653ff912c702db9c769eb9352427fe
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH09.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH09.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..62949647dc8c58fb617d35277e2676a648f566c6
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH09.dat.md5
@@ -0,0 +1 @@
+38fb721b88ab95ecbd39bbc31c7b80ea
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH10.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH10.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..317c0ad767661188889ef9a86b2d3785a7e06c37
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH10.dat.md5
@@ -0,0 +1 @@
+a615c3047d837b06598dd34b6a0df56c
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH17.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH17.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c35f10855d39ee4bb144e86d812498baf1abeebb
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/MGH17.dat.md5
@@ -0,0 +1 @@
+3bc29da66158998faecec51f3cdd9dd6
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1a.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1a.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..e1da9bd946ef1c56b06738eac7579cc06542ab6a
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1a.dat.md5
@@ -0,0 +1 @@
+984c8d2b2efdd3d3e24efeba48a9fd92
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1b.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1b.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..3afa276210a262dfbea8beaa5ed3dfde43f0169a
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1b.dat.md5
@@ -0,0 +1 @@
+28b7e399c1588c77b12e241780c91040
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1c.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1c.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..57f69bfd22edbe0383602b872717b72014589f54
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1c.dat.md5
@@ -0,0 +1 @@
+06cde8a4e094c290a618dc7bb7b6fcc3
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1d.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1d.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..3b1dfd0812037d2266cab6d3d39c85c42b16e74a
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Misra1d.dat.md5
@@ -0,0 +1 @@
+1e7286e296105a708ad93c891614e307
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Nelson.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Nelson.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c44dab0c7ed9f7156e26855a77fe238acbca98b3
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Nelson.dat.md5
@@ -0,0 +1 @@
+7aa2c811325939e074dad698053b5412
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat42.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat42.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..c77bc76f40a563bb19ceaac009c9be8e24c11776
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat42.dat.md5
@@ -0,0 +1 @@
+cca8ea6f5087b155060c8f243d02e9cd
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat43.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat43.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..9b63e65b352695e4c4faefb90e950d476967c7f8
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Rat43.dat.md5
@@ -0,0 +1 @@
+b0d1db54d68fec53a4d998cc4f69927a
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Roszman1.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Roszman1.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..01ce65814f851796da32ed09581e2c34d4c83997
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Roszman1.dat.md5
@@ -0,0 +1 @@
+ce3f6494693655f59b49714c30ccd219
diff --git a/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Thurber.dat.md5 b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Thurber.dat.md5
new file mode 100644
index 0000000000000000000000000000000000000000..f41a064e3d372ba0637102d192a0080b90b4ee2e
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/NIST_nonlinear_regression/Thurber.dat.md5
@@ -0,0 +1 @@
+96fd4140cf2abc03ac4cad8b113895a1
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak19.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak19.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..6a8ae3f42c96e524ab42e4835b2f7c8f52ee0b08
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak19.txt.md5
@@ -0,0 +1 @@
+b268192abbc9c076a51e47234fef04d6
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak20.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak20.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..b5d5f45fce93f4e1453cbf8ccf202fcf06c2a051
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak20.txt.md5
@@ -0,0 +1 @@
+0b042ae6660bd794774847c13e4316c8
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak23.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak23.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..076027fde429d181ef3d798cb830a9aa78984e8e
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak23.txt.md5
@@ -0,0 +1 @@
+c154a8fe628c0db7c10921a7babfafbe
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak5.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak5.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..890edc97ae79032ec5cc643f713bcf16f8fe53af
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak5.txt.md5
@@ -0,0 +1 @@
+5ff4214f4e5e9f45a0632045e502d6ff
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak6.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak6.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..267878e2bf72585cd8c47ced6dee0d4818a7ec24
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX193749_calibration_peak6.txt.md5
@@ -0,0 +1 @@
+c02038557722f6f601a11641c13b8f55
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_10brk.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_10brk.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..ffd53c9261d7e90ddead7c467706ca5cb7c42b73
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_10brk.txt.md5
@@ -0,0 +1 @@
+80561f35628e26b957fd8fbab5502d93
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_20brk.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_20brk.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..bc381407d5b4b92845a823352128426b75b33808
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/ENGINX236516_vanadium_bank1_20brk.txt.md5
@@ -0,0 +1 @@
+68bf0586cce1d875e162423a2447b9b5
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_1.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_1.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..0cce87070041d390e557819869f4ee0a10253710
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_1.txt.md5
@@ -0,0 +1 @@
+05994950f8867e839a687a536b677595
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_2.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_2.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..0307a07e4e514ac8a77a8fb5f6251dce7cf9e610
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/EVS14188-90_Gaussian_peaks_2.txt.md5
@@ -0,0 +1 @@
+139c8317571234cda311afbef9a286f5
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/GEMpeak1.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/GEMpeak1.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..7cca87602774f12f15b50b5d023d7a64de96f541
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/GEMpeak1.txt.md5
@@ -0,0 +1 @@
+39a5f5d5585fb2821d9b887d18e80197
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak1.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak1.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..fe852094540c203dbea2f3c827552e956ee13ec3
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak1.txt.md5
@@ -0,0 +1 @@
+9d6bc75a57b064126aab14e7c5eb32ea
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak2.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak2.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..f3915ecf82b0d35195f89fd3c3d17e9c5ad29425
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak2.txt.md5
@@ -0,0 +1 @@
+61fb6cec75bdd035361dbaea6710e96c
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak3.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak3.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..ff5ea373233eb3831910caf5145033f27d36946b
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak3.txt.md5
@@ -0,0 +1 @@
+655d1a9f81d2e2b0095dd108819d918a
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak4.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak4.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..96c3969ea0c0f95a7a17865e8d4ce9a180616812
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak4.txt.md5
@@ -0,0 +1 @@
+f41f1751f64e2c895d9dddaf0a8dbbce
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak5.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak5.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..7237c12ba27659d616aa75dc03aa520563f6ae25
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak5.txt.md5
@@ -0,0 +1 @@
+25620760fec116854cd419e7aad4b047
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak6.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak6.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..5c3b9f825d57229ef73decfa5de9a0eca05144ae
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak6.txt.md5
@@ -0,0 +1 @@
+046092c6b317018ca4f21af0cf6a11fb
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak7.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak7.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..d85f9fda11f316e745a3c93b36cbec3da3c68066
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak7.txt.md5
@@ -0,0 +1 @@
+eb629c8b1b5fceb83fcd92f97598ef00
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak8.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak8.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..81ce182db601f672d2fa89ebb17f1f82c093c0a5
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak8.txt.md5
@@ -0,0 +1 @@
+7e013fa7700c776316a6643b4185a203
diff --git a/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak9.txt.md5 b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak9.txt.md5
new file mode 100644
index 0000000000000000000000000000000000000000..67a6df33aa1e77b462a0a01666ba10effd27f78b
--- /dev/null
+++ b/Testing/Data/SystemTest/FittingTestProblems/Neutron_data/WISH17701_peak9.txt.md5
@@ -0,0 +1 @@
+0350effd9980b5f25823d8b67bb6c7d3
diff --git a/Testing/Data/SystemTest/GEM63437_focused_bank3.nxs.md5 b/Testing/Data/SystemTest/GEM63437_focused_bank3.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..4849a0bb040c8fe38eb3162a5f1e102cc91efccb
--- /dev/null
+++ b/Testing/Data/SystemTest/GEM63437_focused_bank3.nxs.md5
@@ -0,0 +1 @@
+14aa520da8b7aa7421db00d42a08e2dc
diff --git a/Testing/Data/SystemTest/WISH17701_calibration_panel103_tube3.nxs.md5 b/Testing/Data/SystemTest/WISH17701_calibration_panel103_tube3.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..493e99c0d094050cce0d657d4513fdf1d793ad22
--- /dev/null
+++ b/Testing/Data/SystemTest/WISH17701_calibration_panel103_tube3.nxs.md5
@@ -0,0 +1 @@
+a32c3ce038d1c0cb85a08b8bddab5101
diff --git a/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py b/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py
index 609b5476ed90dc964e0117cb2fcccd048c2f40ad..804d2d3ad6c8ccd6851e7fc95f5dfe9a944fa03e 100644
--- a/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py
+++ b/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic.py
@@ -49,8 +49,9 @@ class DirectInelasticDiagnostic(MantidStressTest):
         # Save the masked spectra nmubers to a simple ASCII file for comparison
         self.saved_diag_file = os.path.join(ms.config['defaultsave.directory'], 'CurrentDirectInelasticDiag.txt')
         handle = file(self.saved_diag_file, 'w')
+        spectrumInfo = sample_ws.spectrumInfo()
         for index in range(sample_ws.getNumberHistograms()):
-            if sample_ws.getDetector(index).isMasked():
+            if spectrumInfo.isMasked(index):
                 spec_no = sample_ws.getSpectrum(index).getSpectrumNo()
                 handle.write(str(spec_no) + '\n')
         handle.close()
diff --git a/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py b/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py
index 2b002c01a0a5740143bfa445b6d6a42b8168fca8..3c79e78655b74815194651e8506eb1f7376533a4 100644
--- a/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py
+++ b/Testing/SystemTests/tests/analysis/DirectInelasticDiagnostic2.py
@@ -71,8 +71,9 @@ class DirectInelasticDiagnostic2(MantidStressTest):
         self.saved_diag_file = os.path.join(config['defaultsave.directory'],
                                             'CurrentDirectInelasticDiag2.txt')
         handle = file(self.saved_diag_file, 'w')
+        spectrumInfo = sample.spectrumInfo()
         for index in range(sample.getNumberHistograms()):
-            if sample.getDetector(index).isMasked():
+            if spectrumInfo.isMasked(index):
                 spec_no = sample.getSpectrum(index).getSpectrumNo()
                 handle.write(str(spec_no) + '\n')
         handle.close()
diff --git a/Testing/SystemTests/tests/analysis/FittingBenchmarks.py b/Testing/SystemTests/tests/analysis/FittingBenchmarks.py
new file mode 100644
index 0000000000000000000000000000000000000000..ea2d43b7efa47b6a92cfd895e731bd24737d24fa
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/FittingBenchmarks.py
@@ -0,0 +1,152 @@
+"""
+This systemtest tests that the fit executes with different minimizers for the fitting test problems used for benchmarking minimizers.
+
+Note the complete benchmarking suite is not tested here since I find this takes too long, but enough to provide
+an additional health test of Mantid fitting and to test that the scripts used for fit minimizer benchmarking are working.
+
+Fitting problem are stored as follows in the FittingTestProblems directory:
+
+        CUTEst/
+        NIST_nonlinear_regression/
+        Neutron_data/
+
+For more information what these problems are see the Mantid FittingMinimizers concept page.
+"""
+from __future__ import (absolute_import, division, print_function)
+
+import unittest
+import stresstesting
+
+import os
+
+import mantid.simpleapi as msapi
+import fitting_benchmarking as fitbk
+import results_output as fitout
+
+
+class FittingBenchmarkTests(unittest.TestCase):
+
+    def setUp(self):
+        self.color_scale = [(1.1, 'ranking-top-1'),
+                            (1.33, 'ranking-top-2'),
+                            (1.75, 'ranking-med-3'),
+                            (3, 'ranking-low-4'),
+                            (float('nan'), 'ranking-low-5')
+                            ]
+
+        # Create the path for the specific fitting test files location
+        input_data_dir = msapi.config['datasearch.directories'].split(';')[0]
+        self.base_problem_files_dir = os.path.join(input_data_dir, 'FittingTestProblems')
+
+    def test_all_nist_problem(self):
+        """
+        Runs benchmark on all NIST problems on about half of the available Mantid minimizers
+        and without using weights.
+        """
+
+        minimizers = ['BFGS', 'Conjugate gradient (Fletcher-Reeves imp.)',
+                      'Conjugate gradient (Polak-Ribiere imp.)', 'Damped GaussNewton']
+        group_names = ['NIST, "lower" difficulty', 'NIST, "average" difficulty', 'NIST, "higher" difficulty']
+        group_suffix_names = ['nist_lower', 'nist_average', 'nist_higher']
+
+        use_errors = False
+
+        nist_group_dir = os.path.join(self.base_problem_files_dir, 'NIST_nonlinear_regression')
+
+        # test that fit executes on all NIST problems against a number of different minimizers
+        problems, results_per_group = fitbk.do_fitting_benchmark(nist_group_dir=nist_group_dir,
+                                                                 minimizers=minimizers, use_errors=use_errors)
+
+        # test that can print individual group tables
+        for idx, group_results in enumerate(results_per_group):
+            print("\n\n")
+            print("********************************************************")
+            print("**************** RESULTS FOR GROUP {0}, {1} ************".format(idx+1,
+                                                                                    group_names[idx]))
+            print("********************************************************")
+            fitout.print_group_results_tables(minimizers, group_results, problems[idx],
+                                              group_name=group_suffix_names[idx], use_errors=use_errors,
+                                              simple_text=True, rst=True, save_to_file=False,
+                                              color_scale=self.color_scale)
+
+        # test that can print summary tables
+        header = '\n\n**************** OVERALL SUMMARY - ALL GROUPS ******** \n\n'
+        print(header)
+        fitout.print_overall_results_table(minimizers, results_per_group, problems, group_names,
+                                           use_errors=use_errors, save_to_file=False)
+
+    def test_all_cutest_problem(self):
+        """
+        Runs benchmark on all CUTEst problems on about half of the available Mantid minimizers
+        and with using weights.
+        """
+        minimizers = ['Levenberg-Marquardt', 'Levenberg-MarquardtMD',
+                      'Simplex', 'SteepestDescent', 'Trust Region']
+        group_suffix_names = ['cutest']
+
+        use_errors = True
+
+        cutest_group_dir = os.path.join(self.base_problem_files_dir, 'CUTEst')
+
+        # test that fit executes on all NIST problems against a number of different minimizers
+        problems, results_per_group = fitbk.do_fitting_benchmark(cutest_group_dir=cutest_group_dir,
+                                                                 minimizers=minimizers, use_errors=use_errors)
+
+        # test that can print individual group table
+        for idx, group_results in enumerate(results_per_group):
+            fitout.print_group_results_tables(minimizers, group_results, problems[idx],
+                                              group_name=group_suffix_names[idx], use_errors=use_errors,
+                                              simple_text=True, rst=True, save_to_file=False,
+                                              color_scale=self.color_scale)
+
+    def test_all_neutron_data_problem(self):
+        """
+        Runs benchmark on all neutron data problems on one minimizers
+        and using weights.
+        """
+        minimizers = ['Trust Region']
+        group_suffix_names = ['neutron_data']
+
+        use_errors = True
+
+        neutron_data_group_dirs = [os.path.join(self.base_problem_files_dir, 'Neutron_data')]
+
+        # test that fit executes on all Neutron data problems
+        problems, results_per_group = fitbk.do_fitting_benchmark(neutron_data_group_dirs=neutron_data_group_dirs,
+                                                                 minimizers=minimizers, use_errors=use_errors)
+
+        # test that can print individual group table
+        for idx, group_results in enumerate(results_per_group):
+            fitout.print_group_results_tables(minimizers, group_results, problems[idx],
+                                              group_name=group_suffix_names[idx], use_errors=use_errors,
+                                              simple_text=True, rst=True, save_to_file=False,
+                                              color_scale=self.color_scale)
+
+
+# Run the unittest tests defined above as a Mantid system test
+class FittingBenchmars(stresstesting.MantidStressTest):
+
+    _success = False
+
+    def __init__(self, *args, **kwargs):
+        # super(FittingBenchmarkTests, self).__init__(*args, **kwargs)
+        # old-style
+        stresstesting.MantidStressTest.__init__(self, *args, **kwargs)
+        self._success = False
+
+    def requiredFile(self):
+        return None
+
+    def runTest(self):
+
+        self._success = False
+        # Custom code to create and run this single test suite
+        suite = unittest.TestSuite()
+        suite.addTest(unittest.makeSuite(FittingBenchmarkTests, "test") )
+        runner = unittest.TextTestRunner()
+        # Run and check success
+        res = runner.run(suite)
+        self._success = res.wasSuccessful()
+
+    def validate(self):
+        return self._success
diff --git a/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
index 7523cfc37ac82a79add468e9658b29f6b0a570cc..2c56de5abdedd246fd7a825aca98c931a669f77c 100644
--- a/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
+++ b/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
@@ -1024,6 +1024,7 @@ class ISISIndirectInelasticConvFit(ISISIndirectInelasticBase):
             BackgroundType=self.bg,
             SpecMin=self.spectra_min,
             SpecMax=self.spectra_max,
+            PeakRadius=5,
             OutputWorkspace='result')
 
     def _validate_properties(self):
diff --git a/Testing/SystemTests/tests/analysis/POLDILoadRunsTest.py b/Testing/SystemTests/tests/analysis/POLDILoadRunsTest.py
index 2ef837b95142f93b620701fe998afbf30ecbc21f..8a70bb994f9f551b1e95d44827b2ed91b6fede64 100644
--- a/Testing/SystemTests/tests/analysis/POLDILoadRunsTest.py
+++ b/Testing/SystemTests/tests/analysis/POLDILoadRunsTest.py
@@ -139,8 +139,8 @@ class POLDILoadRunsTest(stresstesting.MantidStressTest):
                       OutputWorkspace='twoWorkspacesMerged')
 
         wsMerged = AnalysisDataService.retrieve("twoWorkspacesMerged_data_6904")
-        self.assertEquals(len([True for x in range(wsMerged.getNumberHistograms()) if wsMerged.getDetector(
-            x).isMasked()]), 36)
+        specInfoMerged = wsMerged.spectrumInfo()
+        self.assertEquals(len([True for x in range(wsMerged.getNumberHistograms()) if specInfoMerged.isMasked(x)]), 36)
 
         self.clearAnalysisDataService()
 
@@ -150,8 +150,8 @@ class POLDILoadRunsTest(stresstesting.MantidStressTest):
                       OutputWorkspace='twoWorkspacesMerged')
 
         wsMerged = AnalysisDataService.retrieve("twoWorkspacesMerged_data_6904")
-        self.assertEquals(len([True for x in range(wsMerged.getNumberHistograms()) if wsMerged.getDetector(
-            x).isMasked()]), 49)
+        specInfoMerged = wsMerged.spectrumInfo()
+        self.assertEquals(len([True for x in range(wsMerged.getNumberHistograms()) if specInfoMerged.isMasked(x)]), 49)
 
         self.clearAnalysisDataService()
 
@@ -160,8 +160,8 @@ class POLDILoadRunsTest(stresstesting.MantidStressTest):
                       OutputWorkspace='twoWorkspacesMerged')
 
         wsMerged = AnalysisDataService.retrieve("twoWorkspacesMerged_data_6904")
-        self.assertEquals(len([True for x in range(wsMerged.getNumberHistograms()) if wsMerged.getDetector(
-            x).isMasked()]), 12)
+        specInfoMerged = wsMerged.spectrumInfo()
+        self.assertEquals( len([True for x in range(wsMerged.getNumberHistograms()) if specInfoMerged.isMasked(x)]), 12)
 
         self.clearAnalysisDataService()
 
diff --git a/Testing/SystemTests/tests/analysis/SNAPRedux.py b/Testing/SystemTests/tests/analysis/SNAPRedux.py
new file mode 100644
index 0000000000000000000000000000000000000000..85a2dcbb3d11f4be3637247117799c68d2f2fa62
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/SNAPRedux.py
@@ -0,0 +1,63 @@
+#pylint: disable=no-init,invalid-name,attribute-defined-outside-init
+from __future__ import (absolute_import, division, print_function)
+import stresstesting
+from mantid.simpleapi import *
+import os
+
+
+def _skip_test():
+    """Helper function to determine if we run the test"""
+    import platform
+
+    # Only runs on RHEL6 at the moment
+    return "Linux" not in platform.platform()
+
+
+def getSaveDir():
+    """determine where to save - the current working directory"""
+    return os.path.abspath(os.path.curdir)
+
+
+def do_cleanup():
+    Files = [os.path.join('d_spacing', 'SNAP_34172_2_4_Grouping.dat'),
+             os.path.join('gsas', 'SNAP_34172_2_4_Grouping.gsa'),
+             os.path.join('fullprof', 'SNAP_34172_2_4_Grouping-0.dat'),
+             os.path.join('fullprof', 'SNAP_34172_2_4_Grouping-1.dat'),
+             os.path.join('nexus', 'SNAP_34172_2_4_Grouping.nxs')]
+    savedir = getSaveDir()
+    for filename in Files:
+        absfile = os.path.join(savedir, filename)
+        if os.path.exists(absfile):
+            os.remove(absfile)
+    for direc in ['d_spacing', 'gsas', 'fullprof', 'nexus']:
+        direc = os.path.join(savedir, direc)
+        if os.listdir(direc) == []:
+            os.rmdir(direc)
+
+    return True
+
+
+class SNAP_short(stresstesting.MantidStressTest):
+    def skipTests(self):
+        return _skip_test()
+
+    def cleanup(self):
+        do_cleanup()
+        return True
+
+    def requiredFiles(self):
+        files = []
+        files.append("SNAP_34172_event.nxs")
+        return files
+
+    def runTest(self):
+        # run the actual code
+        SNAPReduce(RunNumbers='34172', Masking='Horizontal', Binning='0.9,-0.004,6',
+                   Normalization='Extracted from Data', PeakClippingWindowSize=7,
+                   SmoothingRange=5, GroupDetectorsBy='2_4 Grouping',
+                   SaveData=True, OutputDirectory=getSaveDir())
+
+    def validate(self):
+        self.tolerance = 1.0e-2
+        # default validation of workspace to processed nexus is right
+        return ('SNAP_34172_2_4_Grouping_nor','SNAP_34172_2_4_Grouping_nor.nxs')
diff --git a/Testing/SystemTests/tests/analysis/WishMasking.py b/Testing/SystemTests/tests/analysis/WishMasking.py
index b34e9bd7fdb5366cf9627e31b79a0f9cc705ffa7..59bd853d66371bfc28cab183bcf9017fa35d2b0f 100644
--- a/Testing/SystemTests/tests/analysis/WishMasking.py
+++ b/Testing/SystemTests/tests/analysis/WishMasking.py
@@ -62,8 +62,8 @@ class WishMasking(stresstesting.MantidStressTest):
         masking_edge = 9
 
                 # Test the 'isMasked' property on the detectors of the original workspace
-        self.assertTrue( ws.getDetector(masking_edge).isMasked() )
-        self.assertTrue( not ws.getDetector(masking_edge + 1).isMasked() )
+        self.assertTrue( ws.spectrumInfo().isMasked(masking_edge) )
+        self.assertTrue( not ws.spectrumInfo().isMasked(masking_edge + 1) )
 
                 # Extract a masking workspace
         ExtractMask( InputWorkspace=ws, OutputWorkspace='masking_wish_workspace' )
@@ -74,8 +74,8 @@ class WishMasking(stresstesting.MantidStressTest):
                 # Test the 'isMasked' property on the detectors of the masked workspace
                 # The following tests have been added even though they are broken because extracted workspaces currently do not preserve the
                 # Masking flags (buty they SHOULD!). Hopefully the broken functionality will be fixed and I can enable them.
-                #self.assertTrue( mask_ws.getDetector(masking_edge).isMasked() )
-                #self.assertTrue( not mask_ws.getDetector(masking_edge + 1).isMasked() )
+                #self.assertTrue( mask_ws.spectrumInfo().isMasked(masking_edge) )
+                #self.assertTrue( not mask_ws.spectrumInfo().isMasked(masking_edge + 1) )
 
                 # Save masking
         mask_file = 'wish_masking_system_test_mask_file_temp.xml'
@@ -101,7 +101,7 @@ class WishMasking(stresstesting.MantidStressTest):
 
                 # Testing that the isMasking is the same on both sides of the masking boundary.
         # If things were working properly the following would not pass!
-        self.assertTrue( mask_ws.getDetector(masking_edge).isMasked() == mask_ws.getDetector(masking_edge + 1).isMasked() )
+        self.assertTrue( mask_ws.spectrumInfo().isMasked(masking_edge) == mask_ws.spectrumInfo().isMasked(masking_edge + 1) )
                 ## END CHARACTERISATION TESTS
 
                 #Test creation with normal masking
diff --git a/Testing/SystemTests/tests/analysis/reference/SNAP_34172_2_4_Grouping_nor.nxs.md5 b/Testing/SystemTests/tests/analysis/reference/SNAP_34172_2_4_Grouping_nor.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..218741c01fad2569fcb820d0d846fcf0ff580989
--- /dev/null
+++ b/Testing/SystemTests/tests/analysis/reference/SNAP_34172_2_4_Grouping_nor.nxs.md5
@@ -0,0 +1 @@
+648aeeed791af5dea783e6550a3fab97
diff --git a/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx b/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
index e2d7b74be215cfb5fc3e6bf9ce31f990435435d6..1eea242716f9c91443fd197a60ca0e5ca611bcfd 100644
--- a/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
+++ b/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
@@ -12,7 +12,6 @@
 #include "MantidVatesAPI/ADSWorkspaceProvider.h"
 #include "MantidVatesAPI/FieldDataToMetadata.h"
 #include "MantidVatesAPI/FilteringUpdateProgressAction.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/VatesXMLDefinitions.h"
 #include "MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h"
 #include "MantidVatesAPI/vtkDataSetToWsName.h"
@@ -142,8 +141,7 @@ int vtkSplatterPlot::RequestInformation(vtkInformation *,
     try {
       std::string scalarName = "signal";
       m_presenter = Mantid::Kernel::make_unique<vtkSplatterPlotFactory>(
-            boost::make_shared<NoThresholdRange>(), scalarName, m_numberPoints,
-            m_topPercentile);
+          scalarName, m_numberPoints, m_topPercentile);
 
       // Get the info objects
       vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
diff --git a/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx b/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx
index 9b89a559be79e5689be7c0ffedbe62fd4ef10df3..d2146f524f8806d3be8498174f3e0a0b9fb316ec 100644
--- a/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx
+++ b/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWNexusReader.cxx
@@ -17,7 +17,6 @@
 #include "MantidVatesAPI/vtkMDHexFactory.h"
 #include "MantidVatesAPI/vtkMDQuadFactory.h"
 #include "MantidVatesAPI/vtkMDLineFactory.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 #include "MantidVatesAPI/FilteringUpdateProgressAction.h"
 #include "MantidVatesAPI/MDLoadingViewAdapter.h"
 
@@ -26,8 +25,6 @@
 vtkStandardNewMacro(vtkMDEWNexusReader)
 
     using namespace Mantid::VATES;
-using Mantid::Geometry::IMDDimension_sptr;
-using Mantid::Geometry::IMDDimension_sptr;
 
 vtkMDEWNexusReader::vtkMDEWNexusReader()
     : FileName{nullptr}, m_loadInMemory{false}, m_depth{1}, m_time{0},
@@ -106,15 +103,14 @@ int vtkMDEWNexusReader::RequestData(
   FilterUpdateProgressAction<vtkMDEWNexusReader> drawingProgressAction(
       this, "Drawing...");
 
-  ThresholdRange_scptr thresholdRange =
-      boost::make_shared<IgnoreZerosThresholdRange>();
-  auto hexahedronFactory = Mantid::Kernel::make_unique<vtkMDHexFactory>(
-      thresholdRange, m_normalization);
+  auto hexahedronFactory =
+      Mantid::Kernel::make_unique<vtkMDHexFactory>(m_normalization);
 
-  hexahedronFactory->setSuccessor(Mantid::Kernel::make_unique<vtkMDQuadFactory>(
-                                      thresholdRange, m_normalization))
-      .setSuccessor(Mantid::Kernel::make_unique<vtkMDLineFactory>(
-          thresholdRange, m_normalization));
+  hexahedronFactory
+      ->setSuccessor(
+          Mantid::Kernel::make_unique<vtkMDQuadFactory>(m_normalization))
+      .setSuccessor(
+          Mantid::Kernel::make_unique<vtkMDLineFactory>(m_normalization));
 
   hexahedronFactory->setTime(m_time);
   vtkDataSet *product = m_presenter->execute(
diff --git a/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWReader.h b/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWReader.h
index 333149bdb6a93b522c33903777768a7d3bd94f63..856e29e821ad0c483c91c7c85d57bbd173a3c15e 100644
--- a/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWReader.h
+++ b/Vates/ParaviewPlugins/ParaViewReaders/MDEWNexusReader/vtkMDEWReader.h
@@ -4,6 +4,7 @@
 #include "MantidVatesAPI/MultiDimensionalDbPresenter.h"
 #include "MantidMDAlgorithms/WidthParameter.h"
 #include "MantidVatesAPI/EscalatingRebinningActionManager.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
 #include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidKernel/MultiThreaded.h"
diff --git a/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx b/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx
index f3f12e33b0ad6777cb3fd3f67cf86316caeae3e2..73433a07b5ba3746911699d106f17e463e4a805d 100644
--- a/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx
+++ b/Vates/ParaviewPlugins/ParaViewReaders/MDHWNexusReader/vtkMDHWNexusReader.cxx
@@ -17,14 +17,12 @@
 #include "MantidVatesAPI/TimeToTimeStep.h"
 #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h"
 #include "MantidVatesAPI/vtkMDHistoHexFactory.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 #include "MantidVatesAPI/FilteringUpdateProgressAction.h"
 #include "MantidVatesAPI/MDLoadingViewAdapter.h"
 
 vtkStandardNewMacro(vtkMDHWNexusReader)
 
     using namespace Mantid::VATES;
-using Mantid::Geometry::IMDDimension_sptr;
 
 vtkMDHWNexusReader::vtkMDHWNexusReader()
     : FileName{nullptr}, m_loadInMemory(false), m_depth(1), m_time(0),
@@ -106,16 +104,13 @@ int vtkMDHWNexusReader::RequestData(
   FilterUpdateProgressAction<vtkMDHWNexusReader> drawingProgressAction(
       this, "Drawing...");
 
-  ThresholdRange_scptr thresholdRange =
-      boost::make_shared<IgnoreZerosThresholdRange>();
-
   // Will attempt to handle drawing in 4D case and then in 3D case
   // if that fails.
   auto factory =
       Mantid::Kernel::make_unique<vtkMDHistoHex4DFactory<TimeToTimeStep>>(
-          thresholdRange, m_normalizationOption, m_time);
-  factory->setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(
-      thresholdRange, m_normalizationOption));
+          m_normalizationOption, m_time);
+  factory->setSuccessor(
+      Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(m_normalizationOption));
 
   auto product = m_presenter->execute(factory.get(), loadingProgressAction,
                                       drawingProgressAction);
diff --git a/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx b/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx
index fa274fb335ff9451192f58d46e6c8a418f026616..79612fb5ea998b6149f131a7ed844683387b9899 100644
--- a/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx
+++ b/Vates/ParaviewPlugins/ParaViewReaders/NexusPeaksReader/vtkNexusPeaksReader.cxx
@@ -29,8 +29,6 @@
 vtkStandardNewMacro(vtkNexusPeaksReader)
 
 using namespace Mantid::VATES;
-using Mantid::Geometry::IMDDimension_sptr;
-using Mantid::Geometry::IMDDimension_sptr;
 using Mantid::API::Workspace_sptr;
 using Mantid::API::AnalysisDataService;
 
diff --git a/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx b/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx
index 9e62f3296499533a89de8f88905807cbdbb1f226..813c2cca0c462627466ceeddf33b4f881d44f026 100644
--- a/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx
+++ b/Vates/ParaviewPlugins/ParaViewReaders/PeaksReader/vtkPeaksReader.cxx
@@ -28,13 +28,11 @@
 vtkStandardNewMacro(vtkPeaksReader)
 
 using namespace Mantid::VATES;
-using Mantid::Geometry::IMDDimension_sptr;
-using Mantid::Geometry::IMDDimension_sptr;
 using Mantid::API::Workspace_sptr;
 using Mantid::API::AnalysisDataService;
 
 vtkPeaksReader::vtkPeaksReader()
-    : FileName{NULL}, m_isSetup{false}, m_uintPeakMarkerSize{0.3},
+    : FileName{nullptr}, m_isSetup{false}, m_uintPeakMarkerSize{0.3},
       m_dimensions{1} {
   this->SetNumberOfInputPorts(0);
   this->SetNumberOfOutputPorts(1);
diff --git a/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx b/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx
index 86c98e0ac9ae8db90a391acd87ce4fc1cb6c1b4f..3587d242d44d88daeeb34ce363d09b3cdb832631 100644
--- a/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx
+++ b/Vates/ParaviewPlugins/ParaViewSources/MDEWSource/vtkMDEWSource.cxx
@@ -22,7 +22,6 @@
 #include "MantidVatesAPI/vtkMDLineFactory.h"
 #include "MantidVatesAPI/vtkMD0DFactory.h"
 #include "MantidVatesAPI/FilteringUpdateProgressAction.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 #include "MantidKernel/WarningSuppressions.h"
 
 #include <boost/optional.hpp>
@@ -175,16 +174,14 @@ int vtkMDEWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf
     FilterUpdateProgressAction<vtkMDEWSource> loadingProgressUpdate(this, "Loading...");
     FilterUpdateProgressAction<vtkMDEWSource> drawingProgressUpdate(this, "Drawing...");
 
-    ThresholdRange_scptr thresholdRange =
-        boost::make_shared<IgnoreZerosThresholdRange>();
-    auto hexahedronFactory = Mantid::Kernel::make_unique<vtkMDHexFactory>(
-        thresholdRange, m_normalization);
+    auto hexahedronFactory =
+        Mantid::Kernel::make_unique<vtkMDHexFactory>(m_normalization);
 
-    hexahedronFactory->setSuccessor(
-                         Mantid::Kernel::make_unique<vtkMDQuadFactory>(
-                             thresholdRange, m_normalization))
-        .setSuccessor(Mantid::Kernel::make_unique<vtkMDLineFactory>(
-            thresholdRange, m_normalization))
+    hexahedronFactory
+        ->setSuccessor(
+            Mantid::Kernel::make_unique<vtkMDQuadFactory>(m_normalization))
+        .setSuccessor(
+            Mantid::Kernel::make_unique<vtkMDLineFactory>(m_normalization))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMD0DFactory>());
 
     hexahedronFactory->setTime(m_time);
@@ -233,15 +230,13 @@ int vtkMDEWSource::RequestInformation(
     vtkInformation *vtkNotUsed(request),
     vtkInformationVector **vtkNotUsed(inputVector),
     vtkInformationVector *outputVector) {
-  if (m_presenter == NULL && !m_wsName.empty()) {
+  if (!m_presenter && !m_wsName.empty()) {
     std::unique_ptr<MDLoadingView> view =
         Mantid::Kernel::make_unique<MDLoadingViewAdapter<vtkMDEWSource>>(this);
     m_presenter = Mantid::Kernel::make_unique<MDEWInMemoryLoadingPresenter>(
         std::move(view),
         new ADSWorkspaceProvider<Mantid::API::IMDEventWorkspace>, m_wsName);
-    if (!m_presenter->canReadFile()) {
-      vtkErrorMacro(<< "Cannot fetch the specified workspace from Mantid ADS.");
-    } else {
+    if (m_presenter->canReadFile()) {
       // If the MDEvent workspace has had top level splitting applied to it,
       // then use the a deptgit stah of 1
       auto workspaceProvider = Mantid::Kernel::make_unique<ADSWorkspaceProvider<Mantid::API::IMDEventWorkspace>>();
@@ -252,6 +247,8 @@ int vtkMDEWSource::RequestInformation(
 
       m_presenter->executeLoadMetadata();
       setTimeRange(outputVector);
+    } else {
+      vtkErrorMacro(<< "Cannot fetch the specified workspace from Mantid ADS.");
     }
   }
   return 1;
diff --git a/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx b/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx
index 22b43222196b781b921e14f638eaa89b49cb576f..34025b8c8eb3de51d8c9b0b7d7396e375a85e355 100644
--- a/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx
+++ b/Vates/ParaviewPlugins/ParaViewSources/MDHWSource/vtkMDHWSource.cxx
@@ -20,7 +20,6 @@
 #include "MantidVatesAPI/vtkMDHistoLineFactory.h"
 #include "MantidVatesAPI/vtkMD0DFactory.h"
 #include "MantidVatesAPI/FilteringUpdateProgressAction.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 
 using namespace Mantid::VATES;
 
@@ -154,22 +153,20 @@ int vtkMDHWSource::RequestData(vtkInformation *, vtkInformationVector **, vtkInf
     FilterUpdateProgressAction<vtkMDHWSource> loadingProgressUpdate(this, "Loading...");
     FilterUpdateProgressAction<vtkMDHWSource> drawingProgressUpdate(this, "Drawing...");
 
-    ThresholdRange_scptr thresholdRange =
-        boost::make_shared<IgnoreZerosThresholdRange>();
-
     /*
     Will attempt to handle drawing in 4D case and then in 3D case if that fails, and so on down to 1D
     */
     auto factory =
         Mantid::Kernel::make_unique<vtkMDHistoHex4DFactory<TimeToTimeStep>>(
-            thresholdRange, m_normalizationOption, m_time);
+            m_normalizationOption, m_time);
 
-    factory->setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(
-                              thresholdRange, m_normalizationOption))
+    factory
+        ->setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(
+            m_normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoQuadFactory>(
-            thresholdRange, m_normalizationOption))
+            m_normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoLineFactory>(
-            thresholdRange, m_normalizationOption))
+            m_normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMD0DFactory>());
 
     auto product = m_presenter->execute(factory.get(), loadingProgressUpdate,
diff --git a/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx b/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
index 20cac969d71d002fcbf98f10b26f0c952da089ff..4767ff540bb2e682515738808b76e5b0c0492183 100644
--- a/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
+++ b/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
@@ -20,8 +20,6 @@
 vtkStandardNewMacro(vtkPeaksSource)
 
 using namespace Mantid::VATES;
-using Mantid::Geometry::IMDDimension_sptr;
-using Mantid::Geometry::IMDDimension_sptr;
 using Mantid::API::Workspace_sptr;
 using Mantid::API::AnalysisDataService;
 
diff --git a/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx b/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx
index d607310440f8b68c6fcdb0e63170f4530c0dddbc..97368a421c14118d1932e938c69e19e1ad5065e3 100644
--- a/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx
+++ b/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx
@@ -68,4 +68,4 @@ void vtkSinglePeakMarkerSource::SetPosition3(double position3)
 {
   m_position3 = position3;
   this->Modified();
-}
\ No newline at end of file
+}
diff --git a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt b/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt
index 3ad9523a000aef68d45dba67c509f5e72d5759ef..d9c5a349a9d73b798f72e170ec4f50a62b610907 100644
--- a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt
+++ b/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/CMakeLists.txt
@@ -4,7 +4,6 @@ set( INC_FILES
  WidgetDllOption.h
  LowHighStepInputWidget.h
  SimpleBinInputWidget.h
- ThresholdRangeWidget.h
 )
 
 # header files that are mocced
@@ -12,14 +11,12 @@ set( HDR_FILES
   BinInputWidget.h
   LowHighStepInputWidget.h
   SimpleBinInputWidget.h
-  ThresholdRangeWidget.h
 )
 
 # source files
 set( SRC_FILES
   LowHighStepInputWidget.cpp
   SimpleBinInputWidget.cpp
-  ThresholdRangeWidget.cpp
 )
 
 # Handle QtWidget header files
@@ -40,8 +37,5 @@ endif ()
 
 add_definitions( -DIN_MANTIDPARAVIEWQT_MANTIDPARAVIEWWIDGETS )
 
-# Put library into subfolder.
-#SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewQtWidgets PVPlugins)
-
 install( TARGETS MantidParaViewQtWidgets ${SYSTEM_PACKAGE_TARGET} DESTINATION ${LIB_DIR} )
 
diff --git a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.cpp b/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.cpp
deleted file mode 100644
index a4716b05d07ff3df4fd5bcfacc704bd8ef408606..0000000000000000000000000000000000000000
--- a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-#include "ThresholdRangeWidget.h"
-#include <QLabel>
-#include <QLineEdit>
-#include <QGridLayout>
-#include <QComboBox>
-#include <QPalette>
-#include <QFont>
-#include <boost/algorithm/string.hpp>
-#include <boost/format.hpp>
-#include <QDoubleValidator>
-
-ThresholdRangeWidget::ThresholdRangeWidget(double min, double max) {
-  QVBoxLayout *layout = new QVBoxLayout;
-
-  QGridLayout *headerLayout = new QGridLayout();
-  headerLayout->addWidget(new QLabel("Thresholds"), 0, 0, 1, 2,
-                          Qt::AlignCenter);
-  layout->addLayout(headerLayout);
-
-  m_thresholdStrategyComboBox = new QComboBox;
-  m_thresholdStrategyComboBox->addItem("Ignore Zeros");
-  m_thresholdStrategyComboBox->addItem("No Threshold Range");
-  m_thresholdStrategyComboBox->addItem("Median and Below");
-  m_thresholdStrategyComboBox->addItem("User Defined");
-  connect(m_thresholdStrategyComboBox,
-          SIGNAL(currentIndexChanged(const QString &)), this,
-          SLOT(strategySelectedListener(const QString &)));
-  layout->addWidget(m_thresholdStrategyComboBox, Qt::AlignLeft);
-
-  QHBoxLayout *mmLayout = new QHBoxLayout();
-
-  mmLayout->addWidget(new QLabel("Min"));
-
-  m_minEditBox = new QLineEdit();
-  m_minEditBox->setValidator(new QDoubleValidator(this));
-  std::string minValueString = boost::str(boost::format("%0.2f") % min);
-  m_minEditBox->setText(minValueString.c_str());
-  m_minEditBox->setCursorPosition(0);
-  mmLayout->addWidget(m_minEditBox, Qt::AlignLeft);
-  m_minEditBox->setDisabled(true); // Disabled by default.
-  connect(m_minEditBox, SIGNAL(textEdited(const QString &)), this,
-          SLOT(minThresholdListener(const QString &)));
-
-  mmLayout->addWidget(new QLabel("Max"));
-
-  m_maxEditBox = new QLineEdit();
-  m_maxEditBox->setValidator(new QDoubleValidator(this));
-  std::string maxValueString = boost::str(boost::format("%0.2f") % max);
-  m_maxEditBox->setText(maxValueString.c_str());
-  m_maxEditBox->setCursorPosition(0);
-  m_maxEditBox->setDisabled(true); // Disabled by default
-  mmLayout->addWidget(m_maxEditBox, Qt::AlignLeft);
-  connect(m_maxEditBox, SIGNAL(textEdited(const QString &)), this,
-          SLOT(maxThresholdListener(const QString &)));
-
-  layout->addLayout(mmLayout);
-
-  this->setLayout(layout);
-}
-
-void ThresholdRangeWidget::strategySelectedListener(const QString &) {
-  bool disableUserControls = true;
-  if (m_thresholdStrategyComboBox->currentText() == "User Defined") {
-    disableUserControls = false;
-  }
-  m_maxEditBox->setDisabled(disableUserControls);
-  m_minEditBox->setDisabled(disableUserControls);
-
-  emit chosenStrategyChanged();
-}
-
-void ThresholdRangeWidget::maxThresholdListener(const QString &) {
-  emit maxChanged();
-}
-
-void ThresholdRangeWidget::minThresholdListener(const QString &) {
-  emit minChanged();
-}
-
-void ThresholdRangeWidget::setMaximum(double value) {
-  std::string maxValueString = boost::str(boost::format("%0.2f") % value);
-  m_maxEditBox->setText(maxValueString.c_str());
-  m_maxEditBox->setCursorPosition(0);
-}
-
-void ThresholdRangeWidget::setMinimum(double value) {
-  std::string minValueString = boost::str(boost::format("%0.2f") % value);
-  m_minEditBox->setText(minValueString.c_str());
-  m_minEditBox->setCursorPosition(0);
-}
-
-ThresholdRangeWidget::~ThresholdRangeWidget() {}
-
-QString ThresholdRangeWidget::getMaxSignal() const {
-  return m_maxEditBox->text();
-}
-
-QString ThresholdRangeWidget::getMinSignal() const {
-  return m_minEditBox->text();
-}
-
-QString ThresholdRangeWidget::getChosenStrategy() const {
-  std::string minValueString = boost::str(
-      boost::format("%i") % m_thresholdStrategyComboBox->currentIndex());
-  return QString(minValueString.c_str());
-}
diff --git a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.h b/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.h
deleted file mode 100644
index 4a89b9fc8d82f0df5e95c7fcb522f74040e4f6b7..0000000000000000000000000000000000000000
--- a/Vates/ParaviewPlugins/ParaViewWidgets/QtWidgets/ThresholdRangeWidget.h
+++ /dev/null
@@ -1,99 +0,0 @@
-#ifndef THRESHOLD_RANGE_WIDGET_H
-#define THRESHOLD_RANGE_WIDGET_H
-
-#include "WidgetDllOption.h"
-#include <qwidget.h>
-#include <qstring.h>
-#include "MantidGeometry/MDGeometry/MDTypes.h"
-#include <qlineedit.h>
-/** This is the GUI implementation of the threshold range widgets. These are
-   used to set max and min threshold values.
-
-    @author Owen Arnold Tessella/ISIS
-    @date July 04/2011
-
-    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>.
-    Code Documentation is available at: <http://doxygen.mantidproject.org>
-*/
-
-// Foward decs
-class QLabel;
-class QLayout;
-class QLineEdit;
-class QComboBox;
-
-// cppcheck-suppress class_X_Y
-class EXPORT_OPT_MANTIDPARVIEW ThresholdRangeWidget : public QWidget {
-
-  Q_OBJECT
-public:
-  Q_PROPERTY(QString MinSignal READ getMinSignal WRITE setMinSignal NOTIFY
-                 minChanged)
-  Q_PROPERTY(QString MaxSignal READ getMaxSignal WRITE setMaxSignal NOTIFY
-                 maxChanged)
-  Q_PROPERTY(QString ChosenStrategy READ getChosenStrategy WRITE
-                 setChosenStrategy NOTIFY chosenStrategyChanged)
-
-  ThresholdRangeWidget(double min, double max);
-
-  ~ThresholdRangeWidget() override;
-
-  QString getMaxSignal() const;
-  QString getMinSignal() const;
-  QString getChosenStrategy() const;
-
-  void setMaximum(double value);
-  void setMinimum(double value);
-
-  void setMinSignal(QString value) {
-    // Do nothing.
-    UNUSED_ARG(value);
-  }
-
-  void setMaxSignal(QString value) {
-    // Do nothing.
-    UNUSED_ARG(value);
-  }
-
-  void setChosenStrategy(QString value) {
-    // Do nothing.
-    UNUSED_ARG(value);
-  }
-
-Q_SIGNALS:
-  void minChanged();
-  void maxChanged();
-  void chosenStrategyChanged();
-
-private:
-  QLineEdit *m_maxEditBox;
-  QLineEdit *m_minEditBox;
-  QComboBox *m_thresholdStrategyComboBox;
-
-private slots:
-  void maxThresholdListener(const QString &);
-
-  void minThresholdListener(const QString &);
-
-  void strategySelectedListener(const QString &);
-};
-
-#endif
diff --git a/Vates/VatesAPI/CMakeLists.txt b/Vates/VatesAPI/CMakeLists.txt
index 6dcadda7cc892f968050d4f4fe4074d8fd080d4e..86deb359e6f52ab0f80d4ce6069a0de67fe22238 100644
--- a/Vates/VatesAPI/CMakeLists.txt
+++ b/Vates/VatesAPI/CMakeLists.txt
@@ -11,7 +11,6 @@ src/CompositePeaksPresenterVsi.cpp
 src/ConcretePeaksPresenterVsi.cpp
 src/EventNexusLoadingPresenter.cpp
 src/FieldDataToMetadata.cpp
-src/IgnoreZerosThresholdRange.cpp
 src/IMDDimensionComparitor.cpp
 src/LoadVTK.cpp
 src/MDEWEventNexusLoadingPresenter.cpp
@@ -21,14 +20,12 @@ src/MDHWInMemoryLoadingPresenter.cpp
 src/MDHWLoadingPresenter.cpp
 src/MDHWNexusLoadingPresenter.cpp
 src/MDLoadingViewSimple.cpp
-src/MedianAndBelowThresholdRange.cpp
 src/MetadataToFieldData.cpp
 src/MetadataToFieldData.cpp
 src/MetaDataExtractorUtils.cpp
 src/MetadataJsonManager.cpp
 src/MDLoadingPresenter.cpp
 src/Normalization.cpp
-src/NoThresholdRange.cpp
 src/ProgressAction.cpp
 src/PresenterUtilities.cpp
 src/SaveMDWorkspaceToVTK.cpp
@@ -36,7 +33,6 @@ src/SaveMDWorkspaceToVTKImpl.cpp
 src/SingleWorkspaceProvider.cpp
 src/TimeStepToTimeStep.cpp
 src/TimeToTimeStep.cpp
-src/UserDefinedThresholdRange.cpp
 src/VatesXMLDefinitions.cpp
 src/VatesConfigurations.cpp
 src/ViewFrustum.cpp
@@ -89,14 +85,11 @@ inc/MantidVatesAPI/MDLoadingPresenter.h
 inc/MantidVatesAPI/MDLoadingView.h
 inc/MantidVatesAPI/MDLoadingViewSimple.h
 inc/MantidVatesAPI/MDLoadingViewAdapter.h
-inc/MantidVatesAPI/MedianAndBelowThresholdRange.h
 inc/MantidVatesAPI/MetaDataExtractorUtils.h
 inc/MantidVatesAPI/MetadataJsonManager.h
 inc/MantidVatesAPI/Normalization.h
-inc/MantidVatesAPI/IgnoreZerosThresholdRange.h
 inc/MantidVatesAPI/IMDDimensionComparitor.h
 inc/MantidVatesAPI/MetadataToFieldData.h
-inc/MantidVatesAPI/NoThresholdRange.h
 inc/MantidVatesAPI/NullPeaksPresenterVsi.h
 inc/MantidVatesAPI/PeaksPresenterVsi.h
 inc/MantidVatesAPI/PresenterFactories.h
@@ -105,10 +98,8 @@ inc/MantidVatesAPI/SaveMDWorkspaceToVTK.h
 inc/MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h
 inc/MantidVatesAPI/SingleWorkspaceProvider.h
 inc/MantidVatesAPI/SQWLoadingPresenter.h
-inc/MantidVatesAPI/ThresholdRange.h
 inc/MantidVatesAPI/TimeStepToTimeStep.h
 inc/MantidVatesAPI/TimeToTimeStep.h
-inc/MantidVatesAPI/UserDefinedThresholdRange.h
 inc/MantidVatesAPI/VatesXMLDefinitions.h
 inc/MantidVatesAPI/VatesConfigurations.h
 inc/MantidVatesAPI/VatesKnowledgeSerializer.h
@@ -180,10 +171,6 @@ test/SingleWorkspaceProviderTest.h
 test/SQWLoadingPresenterTest.h
 test/TimeStepToTimeStepTest.h
 test/TimeToTimeStepTest.h
-test/UserDefinedThresholdRangeTest.h
-test/MedianAndBelowThresholdRangeTest.h
-test/NoThresholdRangeTest.h
-test/IgnoreZerosThresholdRangeTest.h
 test/VatesKnowledgeSerializerTest.h
 test/ViewFrustumTest.h
 test/vtkDataSetToScaledDataSetTest.h
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/FactoryChains.h b/Vates/VatesAPI/inc/MantidVatesAPI/FactoryChains.h
index ccf2463465425944fafae99fc17fec84ccbb6db3..bf7c1828b57cc90e5c88323fda9aaed41feb10cc 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/FactoryChains.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/FactoryChains.h
@@ -19,14 +19,12 @@ class MDLoadingPresenter;
 
 /// Creates a facotry chain for MDHisto workspaces
 std::unique_ptr<vtkMDHistoHex4DFactory<TimeToTimeStep>> DLLExport
-createFactoryChainForHistoWorkspace(ThresholdRange_scptr threshold,
-                                    VisualNormalization normalization,
+createFactoryChainForHistoWorkspace(VisualNormalization normalization,
                                     double time);
 
 /// Creates a factory chain for MDEvent workspaces
 std::unique_ptr<vtkMDHexFactory> DLLExport
-createFactoryChainForEventWorkspace(ThresholdRange_scptr threshold,
-                                    VisualNormalization normalization,
+createFactoryChainForEventWorkspace(VisualNormalization normalization,
                                     double time);
 
 /// Function to apply the Change-of-Basis-Matrix
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/IMDDimensionComparitor.h b/Vates/VatesAPI/inc/MantidVatesAPI/IMDDimensionComparitor.h
index b93a6371aac036b7e42f43b8213a8fe3169856d9..046285fdec3bd0b5f1f243af64476aa494b44614 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/IMDDimensionComparitor.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/IMDDimensionComparitor.h
@@ -1,7 +1,9 @@
 #ifndef IMD_DIMENSION_COMPARITOR_H
 #define IMD_DIMENSION_COMPARITOR_H
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDWorkspace.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 
 namespace Mantid {
 namespace VATES {
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/IgnoreZerosThresholdRange.h b/Vates/VatesAPI/inc/MantidVatesAPI/IgnoreZerosThresholdRange.h
deleted file mode 100644
index 2b556e3b4d27e0380c97e5c0c471bb6755a8e7af..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/inc/MantidVatesAPI/IgnoreZerosThresholdRange.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef MANTID_PARAVIEW_IGNORE_ZEROS_THRESHOLD_RANGE
-#define MANTID_PARAVIEW_IGNORE_ZEROS_THRESHOLD_RANGE
-
-#include "MantidKernel/System.h"
-#include "MantidVatesAPI/ThresholdRange.h"
-/** Set range selection to cut-out zeros.
-
- @author Owen Arnold, Tessella plc
- @date 07/07/2011
-
- 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>
- */
-
-namespace Mantid {
-namespace VATES {
-class DLLExport IgnoreZerosThresholdRange : public ThresholdRange {
-
-public:
-  IgnoreZerosThresholdRange(signal_t min, signal_t max);
-
-  IgnoreZerosThresholdRange();
-
-  void calculate() override;
-
-  signal_t getMinimum() const override;
-
-  signal_t getMaximum() const override;
-
-  ~IgnoreZerosThresholdRange() override;
-
-  bool hasCalculated() const override;
-
-  IgnoreZerosThresholdRange *clone() const override;
-
-  bool inRange(const signal_t &signal) override;
-
-private:
-  signal_t m_min;
-
-  signal_t m_max;
-};
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/MDEWEventNexusLoadingPresenter.h b/Vates/VatesAPI/inc/MantidVatesAPI/MDEWEventNexusLoadingPresenter.h
index dff9d3941cf6dbb98ec978bf5ac1a51c5a443119..66ea5eebd78561b3792d17c5dca9959469907837 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/MDEWEventNexusLoadingPresenter.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/MDEWEventNexusLoadingPresenter.h
@@ -37,7 +37,7 @@ class MDLoadingView;
 class DLLExport MDEWEventNexusLoadingPresenter : public MDEWLoadingPresenter {
 public:
   MDEWEventNexusLoadingPresenter(std::unique_ptr<MDLoadingView> view,
-                                 const std::string fileName);
+                                 const std::string &fileName);
   vtkSmartPointer<vtkDataSet>
   execute(vtkDataSetFactory *factory, ProgressAction &rebinningProgressUpdate,
           ProgressAction &drawingProgressUpdate) override;
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/MedianAndBelowThresholdRange.h b/Vates/VatesAPI/inc/MantidVatesAPI/MedianAndBelowThresholdRange.h
deleted file mode 100644
index 4ce4577975aed87178deaedc7ffcaf1d480d3b62..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/inc/MantidVatesAPI/MedianAndBelowThresholdRange.h
+++ /dev/null
@@ -1,74 +0,0 @@
-#ifndef MANTID_PARAVIEW_MEDIAN_AND_BELOW_THRESHOLD_RANGE
-#define MANTID_PARAVIEW_MEDIAN_AND_BELOW_THRESHOLD_RANGE
-
-#include "MantidKernel/System.h"
-#include "MantidVatesAPI/ThresholdRange.h"
-#include "MantidAPI/IMDWorkspace.h"
-
-/** Set range selection to cut-out zeros and provide an upper limit equal to the
- median value in the workspace.
-
- @author Owen Arnold, Tessella plc
- @date 07/07/2011
-
- 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>
- */
-
-namespace Mantid {
-namespace VATES {
-class DLLExport MedianAndBelowThresholdRange : public ThresholdRange {
-
-public:
-  MedianAndBelowThresholdRange();
-
-  void calculate() override;
-
-  signal_t getMinimum() const override;
-
-  signal_t getMaximum() const override;
-
-  ~MedianAndBelowThresholdRange() override;
-
-  bool hasCalculated() const override;
-
-  MedianAndBelowThresholdRange *clone() const override;
-
-  bool inRange(const signal_t &signal) override;
-
-  void setWorkspace(Mantid::API::Workspace_sptr workspace) override;
-
-private:
-  MedianAndBelowThresholdRange(signal_t min, signal_t max, bool isCalculated,
-                               Mantid::API::IMDWorkspace_sptr m_workspace);
-
-  signal_t m_min;
-
-  signal_t m_max;
-
-  bool m_isCalculated;
-
-  Mantid::API::IMDWorkspace_sptr m_workspace;
-};
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h b/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h
index 000b95d025f7922fe12d8edaa64973fd750c6066..ee36241b6d52b81d3233731846105e97c3b5c2ca 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/MetadataToFieldData.h
@@ -39,12 +39,12 @@ namespace VATES {
 class DLLExport MetadataToFieldData {
 public:
   /// Act as Functor.
-  void operator()(vtkFieldData *fieldData, std::string metaData,
-                  std::string id) const;
+  void operator()(vtkFieldData *fieldData, const std::string &metaData,
+                  const std::string &id) const;
 
   /// Explicit call to Functor execution.
-  void execute(vtkFieldData *fieldData, std::string metaData,
-               std::string id) const;
+  void execute(vtkFieldData *fieldData, const std::string &metaData,
+               const std::string &id) const;
 };
 }
 }
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/NoThresholdRange.h b/Vates/VatesAPI/inc/MantidVatesAPI/NoThresholdRange.h
deleted file mode 100644
index cd308bfaec09625f1280b5fb8fd1fb23e2ef3e27..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/inc/MantidVatesAPI/NoThresholdRange.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef MANTID_PARAVIEW_NO_THRESHOLD_RANGE
-#define MANTID_PARAVIEW_NO_THRESHOLD_RANGE
-
-#include "MantidKernel/System.h"
-#include "MantidVatesAPI/ThresholdRange.h"
-/** Does not constrain to any range.
-
- @author Owen Arnold, Tessella plc
- @date 07/07/2011
-
- 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>
- */
-
-namespace Mantid {
-namespace VATES {
-class DLLExport NoThresholdRange : public ThresholdRange {
-
-public:
-  NoThresholdRange();
-
-  void calculate() override;
-
-  signal_t getMinimum() const override;
-
-  signal_t getMaximum() const override;
-
-  ~NoThresholdRange() override;
-
-  bool hasCalculated() const override;
-
-  NoThresholdRange *clone() const override;
-
-  bool inRange(const signal_t &signal) override;
-
-private:
-  NoThresholdRange(signal_t min, signal_t max);
-
-  signal_t m_min;
-
-  signal_t m_max;
-};
-}
-}
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h b/Vates/VatesAPI/inc/MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h
index 2a9210ac47a8c5c3e22adeb83159ec90315f2818..24f5e2fc83ddcb5265be1f90b2dda68a73eb765f 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h
@@ -2,9 +2,10 @@
 #define VATES_API_SAVE_MD_WORKSPACE_TO_VTK_IMPL_H_
 
 #include "MantidAPI/IMDWorkspace.h"
+#include "MantidAPI/Progress.h"
 #include "MantidKernel/System.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
+#include "MantidVatesAPI/SaveMDWorkspaceToVTK.h"
 
 #include <map>
 #include <vtkSmartPointer.h>
@@ -44,12 +45,11 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 class DLLExport SaveMDWorkspaceToVTKImpl {
 public:
-  SaveMDWorkspaceToVTKImpl();
+  SaveMDWorkspaceToVTKImpl(SaveMDWorkspaceToVTK *parent = nullptr);
   ~SaveMDWorkspaceToVTKImpl() {}
   void saveMDWorkspace(Mantid::API::IMDWorkspace_sptr workspace,
                        const std::string &filename,
-                       VisualNormalization normalization,
-                       ThresholdRange_scptr thresholdRange, int recursionDepth,
+                       VisualNormalization normalization, int recursionDepth,
                        const std::string &compressorType) const;
 
   const static std::string structuredGridExtension;
@@ -57,18 +57,13 @@ public:
 
   std::vector<std::string>
   getAllowedNormalizationsInStringRepresentation() const;
-  std::vector<std::string> getAllowedThresholdsInStringRepresentation() const;
   VisualNormalization
   translateStringToVisualNormalization(const std::string normalization) const;
-  ThresholdRange_scptr
-  translateStringToThresholdRange(const std::string thresholdRange) const;
-
   bool is3DWorkspace(Mantid::API::IMDWorkspace_sptr workspace) const;
 
 private:
+  mutable API::Progress m_progress;
   std::map<std::string, VisualNormalization> m_normalizations;
-  std::vector<std::string> m_thresholds;
-
   void setupMembers();
   bool is4DWorkspace(Mantid::API::IMDWorkspace_sptr workspace) const;
   int writeDataSetToVTKFile(vtkXMLWriter *writer, vtkDataSet *dataSet,
@@ -83,7 +78,6 @@ private:
       Mantid::API::IMDWorkspace_sptr workspace, bool isHistoWorkspace) const;
   std::unique_ptr<vtkDataSetFactory>
   getDataSetFactoryChain(bool isHistWorkspace,
-                         ThresholdRange_scptr thresholdRange,
                          VisualNormalization normalization, double time) const;
   std::unique_ptr<MDLoadingPresenter>
   getPresenter(bool isHistoWorkspace, Mantid::API::IMDWorkspace_sptr workspace,
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/ThresholdRange.h b/Vates/VatesAPI/inc/MantidVatesAPI/ThresholdRange.h
deleted file mode 100644
index 9729ca81df2d5e733aa7c9383d62de6e5bbd3e78..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/inc/MantidVatesAPI/ThresholdRange.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef MANTID_PARAVIEW_THRESHOLD_RANGE
-#define MANTID_PARAVIEW_THRESHOLD_RANGE
-
-#include <boost/shared_ptr.hpp>
-#include "MantidKernel/System.h"
-#include "MantidGeometry/MDGeometry/MDTypes.h"
-#include "MantidAPI/Workspace_fwd.h"
-
-/** Abstract type promises to supply a minimum and maximum set of threshold
- range values.
-
- @author Owen Arnold, Tessella plc
- @date 30/06/2011
-
- 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>
- */
-
-namespace Mantid {
-namespace VATES {
-class DLLExport ThresholdRange {
-
-public:
-  /// Calculate the threshold range.
-  virtual void calculate() = 0;
-
-  /// Getter for the has executed status.
-  virtual bool hasCalculated() const = 0;
-
-  /// Fetch the threshold range.
-  virtual signal_t getMinimum() const = 0;
-
-  /// Fetch the threshold range minimum.
-  virtual signal_t getMaximum() const = 0;
-
-  /// Virtual constructor method.
-  virtual ThresholdRange *clone() const = 0;
-
-  /// Determine wheter the given value is within the range.
-  virtual bool inRange(const signal_t &signal) = 0;
-
-  /// Destructor
-  virtual ~ThresholdRange() {}
-
-  /// Interface allows the threshold range to accept a workspace.
-  virtual void setWorkspace(Mantid::API::Workspace_sptr) {}
-};
-
-/// ThresholdRange as a scoped pointer.
-typedef boost::shared_ptr<ThresholdRange> ThresholdRange_scptr;
-}
-}
-
-#endif
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/UserDefinedThresholdRange.h b/Vates/VatesAPI/inc/MantidVatesAPI/UserDefinedThresholdRange.h
deleted file mode 100644
index 76a4b70cbf33fc4c8d956c4be1de763602baa113..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/inc/MantidVatesAPI/UserDefinedThresholdRange.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef MANTID_PARAVIEW_USER_DEFINED_THRESHOLD_RANGE
-#define MANTID_PARAVIEW_USER_DEFINED_THRESHOLD_RANGE
-
-#include "MantidKernel/System.h"
-#include "MantidVatesAPI/ThresholdRange.h"
-/** Stores range values specified by the user.
-
- @author Owen Arnold, Tessella plc
- @date 30/06/2011
-
- 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>
- */
-
-namespace Mantid {
-namespace VATES {
-class DLLExport UserDefinedThresholdRange : public ThresholdRange {
-
-public:
-  UserDefinedThresholdRange(signal_t min, signal_t max);
-
-  void calculate() override;
-
-  signal_t getMinimum() const override;
-
-  signal_t getMaximum() const override;
-
-  ~UserDefinedThresholdRange() override;
-
-  bool hasCalculated() const override;
-
-  UserDefinedThresholdRange *clone() const override;
-
-  bool inRange(const signal_t &signal) override;
-
-private:
-  const signal_t m_min;
-
-  const signal_t m_max;
-};
-}
-}
-
-#endif
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMD0DFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMD0DFactory.h
index 038b5b324b7cf216069f93adbfbd7c1c83cd8c84..9512af51ffb9808f2458c3b84fdec3e9b8a7381d 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMD0DFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMD0DFactory.h
@@ -5,7 +5,6 @@
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "vtkUnstructuredGrid.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 
 namespace Mantid {
 namespace VATES {
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHWSignalArray.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHWSignalArray.h
index 9892284002833579869ec109a0c08ecc73e54d08..543340bcc775b2bcae8e3c8a4d367340dde8fe03 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHWSignalArray.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHWSignalArray.h
@@ -30,7 +30,8 @@
 #include "vtkVariant.h"
 #include "vtkVariantCast.h"
 
-#include "MantidDataObjects/MDHistoWorkspaceIterator.h"
+#include "MantidDataObjects/MDHistoWorkspace.h"
+#include "MantidVatesAPI/Normalization.h"
 
 namespace Mantid {
 namespace VATES {
@@ -46,9 +47,8 @@ public:
   // clang-format on
   void PrintSelf(ostream &os, vtkIndent indent) override;
 
-  void InitializeArray(
-      std::unique_ptr<Mantid::DataObjects::MDHistoWorkspaceIterator> iterator,
-      std::size_t offset, vtkIdType size);
+  void InitializeArray(Mantid::DataObjects::MDHistoWorkspace *ws,
+                       VisualNormalization normalization, std::size_t offset);
 
   // Reimplemented virtuals -- see superclasses for descriptions:
   void Initialize() override;
@@ -116,7 +116,8 @@ private:
   void operator=(const vtkMDHWSignalArray &);     // Not implemented.
 
   std::size_t m_offset;
-  std::unique_ptr<Mantid::DataObjects::MDHistoWorkspaceIterator> m_iterator;
+  API::MDNormalization m_normalization;
+  DataObjects::MDHistoWorkspace *m_ws;
   Scalar m_temporaryTuple[1];
 };
 
@@ -138,13 +139,25 @@ void vtkMDHWSignalArray<Scalar>::PrintSelf(ostream &os, vtkIndent indent) {
 //------------------------------------------------------------------------------
 template <class Scalar>
 void vtkMDHWSignalArray<Scalar>::InitializeArray(
-    std::unique_ptr<Mantid::DataObjects::MDHistoWorkspaceIterator> iterator,
-    std::size_t offset, vtkIdType size) {
-  this->MaxId = size - 1;
-  this->Size = size;
+    Mantid::DataObjects::MDHistoWorkspace *ws,
+    Mantid::VATES::VisualNormalization normalization, std::size_t offset) {
   this->NumberOfComponents = 1;
-  this->m_iterator = std::move(iterator);
+  this->m_ws = ws;
   this->m_offset = offset;
+
+  const auto nBinsX = m_ws->getXDimension()->getNBins();
+  const auto nBinsY = m_ws->getYDimension()->getNBins();
+  const auto nBinsZ = m_ws->getZDimension()->getNBins();
+  this->Size = nBinsX * nBinsY * nBinsZ;
+  this->MaxId = this->Size - 1;
+
+  if (normalization == AutoSelect) {
+    // enum to enum.
+    m_normalization =
+        static_cast<API::MDNormalization>(m_ws->displayNormalization());
+  } else {
+    m_normalization = static_cast<API::MDNormalization>(normalization);
+  }
 }
 
 //------------------------------------------------------------------------------
@@ -247,16 +260,14 @@ template <class Scalar> void vtkMDHWSignalArray<Scalar>::ClearLookup() {
 //------------------------------------------------------------------------------
 template <class Scalar>
 double *vtkMDHWSignalArray<Scalar>::GetTuple(vtkIdType i) {
-  m_iterator->jumpTo(m_offset + i);
-  m_temporaryTuple[0] = m_iterator->getNormalizedSignal();
+  m_temporaryTuple[0] = this->GetValue(i);
   return &m_temporaryTuple[0];
 }
 
 //------------------------------------------------------------------------------
 template <class Scalar>
 void vtkMDHWSignalArray<Scalar>::GetTuple(vtkIdType i, double *tuple) {
-  m_iterator->jumpTo(m_offset + i);
-  tuple[0] = m_iterator->getNormalizedSignal();
+  tuple[0] = this->GetValue(i);
 }
 
 //------------------------------------------------------------------------------
@@ -292,14 +303,22 @@ vtkIdType vtkMDHWSignalArray<Scalar>::Lookup(const Scalar &val,
 //------------------------------------------------------------------------------
 template <class Scalar>
 Scalar vtkMDHWSignalArray<Scalar>::GetValue(vtkIdType idx) const {
-  m_iterator->jumpTo(m_offset + idx);
-  return m_iterator->getNormalizedSignal();
+  auto pos = m_offset + idx;
+  switch (m_normalization) {
+  case API::NoNormalization:
+    return m_ws->getSignalAt(pos);
+  case API::VolumeNormalization:
+    return m_ws->getSignalAt(pos) * m_ws->getInverseVolume();
+  case API::NumEventsNormalization:
+    return m_ws->getSignalAt(pos) / m_ws->getNumEventsAt(pos);
+  }
+  // Should not reach here
+  return std::numeric_limits<signal_t>::quiet_NaN();
 }
 //------------------------------------------------------------------------------
 template <class Scalar>
 Scalar &vtkMDHWSignalArray<Scalar>::GetValueReference(vtkIdType idx) {
-  m_iterator->jumpTo(m_offset + idx);
-  m_temporaryTuple[0] = m_iterator->getNormalizedSignal();
+  m_temporaryTuple[0] = this->GetValue(idx);
   return m_temporaryTuple[0];
 }
 
@@ -307,8 +326,7 @@ Scalar &vtkMDHWSignalArray<Scalar>::GetValueReference(vtkIdType idx) {
 template <class Scalar>
 void vtkMDHWSignalArray<Scalar>::GetTypedTuple(vtkIdType tupleId,
                                                Scalar *tuple) const {
-  m_iterator->jumpTo(m_offset + tupleId);
-  tuple[0] = m_iterator->getNormalizedSignal();
+  tuple[0] = this->GetValue(tupleId);
 }
 
 //------------------------------------------------------------------------------
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHexFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHexFactory.h
index 6948a3f92013b513a5452685ffa56b10dd723291..a8e45ed75f613848dd052b9b13e0505515fbf8f3 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHexFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHexFactory.h
@@ -5,7 +5,6 @@
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/TimeToTimeStep.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 
@@ -58,8 +57,7 @@ class DLLExport vtkMDHexFactory : public vtkDataSetFactory {
 
 public:
   /// Constructor
-  vtkMDHexFactory(ThresholdRange_scptr thresholdRange,
-                  const VisualNormalization normalizationOption,
+  vtkMDHexFactory(const VisualNormalization normalizationOption,
                   const size_t maxDepth = 1000);
 
   /// Destructor
@@ -92,9 +90,6 @@ private:
   /// Template Method pattern to validate the factory before use.
   void validate() const override;
 
-  /// Threshold range strategy.
-  ThresholdRange_scptr m_thresholdRange;
-
   /// Normalization option and info.
   const VisualNormalization m_normalizationOption;
 
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
index 894ce675cd763cab4d3a05840e7d77c0715a40e4..8010ead4403950003918aab1848564473cf5f20c 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
@@ -32,7 +32,6 @@
 
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include "MantidVatesAPI/vtkMDHistoHexFactory.h"
 #include <vtkCellData.h>
@@ -47,8 +46,7 @@ template <typename TimeMapper>
 class DLLExport vtkMDHistoHex4DFactory : public vtkMDHistoHexFactory {
 public:
   /// Constructor
-  vtkMDHistoHex4DFactory(ThresholdRange_scptr thresholdRange,
-                         const VisualNormalization normalizationOption,
+  vtkMDHistoHex4DFactory(const VisualNormalization normalizationOption,
                          const double timestep);
 
   /// Assignment operator
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHexFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHexFactory.h
index f65dd27efee811866fb03f749ac539a2b1153722..26fcc615711b94532ac1fe18cd07e1f0895d7b45 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHexFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoHexFactory.h
@@ -33,7 +33,6 @@
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include <vtkFloatArray.h>
 #include <vtkCellData.h>
 #include <vtkHexahedron.h>
@@ -45,8 +44,7 @@ namespace VATES {
 class DLLExport vtkMDHistoHexFactory : public vtkDataSetFactory {
 public:
   /// Constructor
-  vtkMDHistoHexFactory(ThresholdRange_scptr thresholdRange,
-                       const VisualNormalization normalizationOption);
+  vtkMDHistoHexFactory(const VisualNormalization normalizationOption);
 
   /// Assignment operator
   vtkMDHistoHexFactory &operator=(const vtkMDHistoHexFactory &other);
@@ -83,9 +81,6 @@ protected:
 
   /// Normalization option
   VisualNormalization m_normalizationOption;
-
-  /// Threshold range.
-  mutable ThresholdRange_scptr m_thresholdRange;
 };
 }
 }
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
index cd47ac315d7d459914cad39e59ef3c066888c4c1..d5ad7fbd7ca1a8f3f8b22c060c8cfa242b70ddd3 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoLineFactory.h
@@ -6,7 +6,6 @@
 #include "MantidAPI/IMDWorkspace.h"
 #include "vtkUnstructuredGrid.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include <vtkNew.h>
 
@@ -43,8 +42,7 @@ namespace VATES {
 class DLLExport vtkMDHistoLineFactory : public vtkDataSetFactory {
 public:
   /// Constructor
-  vtkMDHistoLineFactory(ThresholdRange_scptr thresholdRange,
-                        const VisualNormalization normalizationOption);
+  vtkMDHistoLineFactory(const VisualNormalization normalizationOption);
 
   /// Assignment operator
   vtkMDHistoLineFactory &operator=(const vtkMDHistoLineFactory &other);
@@ -74,8 +72,6 @@ private:
   Mantid::DataObjects::MDHistoWorkspace_sptr m_workspace;
 
   VisualNormalization m_normalizationOption;
-
-  mutable ThresholdRange_scptr m_thresholdRange;
 };
 }
 }
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
index 4ee573720028353b9c2e7d683241afcfe73d3ab9..36f7f626124e7763e2e52c0a584109e0a147242b 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
@@ -3,7 +3,6 @@
 
 #include "MantidKernel/System.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 
 #include "MantidAPI/IMDWorkspace.h"
@@ -46,8 +45,7 @@ National Laboratory & European Spallation Source
 class DLLExport vtkMDHistoQuadFactory : public vtkDataSetFactory {
 public:
   /// Constructor
-  vtkMDHistoQuadFactory(ThresholdRange_scptr thresholdRange,
-                        const VisualNormalization normalizationOption);
+  vtkMDHistoQuadFactory(const VisualNormalization normalizationOption);
 
   /// Assignment operator
   vtkMDHistoQuadFactory &operator=(const vtkMDHistoQuadFactory &other);
@@ -79,8 +77,6 @@ private:
   Mantid::DataObjects::MDHistoWorkspace_sptr m_workspace;
 
   VisualNormalization m_normalizationOption;
-
-  mutable ThresholdRange_scptr m_thresholdRange;
 };
 }
 }
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDLineFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDLineFactory.h
index 192d40a49663583be0e835a113d1143069abb30a..4da0b1f42a0da1c865952cfaa79258d8a4dd0b2d 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDLineFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDLineFactory.h
@@ -3,7 +3,6 @@
 
 #include "MantidVatesAPI/Normalization.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include <boost/shared_ptr.hpp>
 
 namespace Mantid {
@@ -40,8 +39,7 @@ class DLLExport vtkMDLineFactory : public vtkDataSetFactory {
 
 public:
   /// Constructor
-  vtkMDLineFactory(ThresholdRange_scptr thresholdRange,
-                   const VisualNormalization normalizationOption);
+  vtkMDLineFactory(const VisualNormalization normalizationOption);
 
   /// Destructor
   ~vtkMDLineFactory() override;
@@ -61,9 +59,6 @@ protected:
   void validate() const override;
 
 private:
-  /// ThresholdRange functor.
-  ThresholdRange_scptr m_thresholdRange;
-
   /// Name of the scalar.
   const VisualNormalization m_normalizationOption;
 
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDQuadFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDQuadFactory.h
index 5b5a7ebe7069b2c1580757f10ff8cc837643e883..88b8003d3f429c3150e16a4f45121eded072780b 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDQuadFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkMDQuadFactory.h
@@ -2,7 +2,6 @@
 #define VATES_MD_QUAD_FACTORY
 
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 
 #include <boost/shared_ptr.hpp>
@@ -41,8 +40,7 @@ class DLLExport vtkMDQuadFactory : public vtkDataSetFactory {
 
 public:
   /// Constructor
-  vtkMDQuadFactory(ThresholdRange_scptr thresholdRange,
-                   const VisualNormalization normalizationOption);
+  vtkMDQuadFactory(const VisualNormalization normalizationOption);
 
   /// Destructor
   ~vtkMDQuadFactory() override;
@@ -62,9 +60,6 @@ protected:
   void validate() const override;
 
 private:
-  /// ThresholdRange functor.
-  ThresholdRange_scptr m_thresholdRange;
-
   /// Name of the scalar.
   const VisualNormalization m_normalizationOption;
 
diff --git a/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
index ef78869d3ea71352efbf352c69cfeb5e76e7a765..10ee7441590ca6a0427c1c00c72f5a6e39a92cf2 100644
--- a/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
+++ b/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
@@ -7,7 +7,6 @@
 #include "MantidAPI/IMDHistoWorkspace_fwd.h"
 #include "MantidDataObjects/MDEventFactory.h"
 #include "MantidDataObjects/MDEventWorkspace.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include "MantidVatesAPI/MetaDataExtractorUtils.h"
 #include "MantidVatesAPI/MetadataJsonManager.h"
@@ -55,8 +54,7 @@ typedef Mantid::signal_t (Mantid::API::IMDNode::*SigFuncIMDNodePtr)() const;
 class DLLExport vtkSplatterPlotFactory : public vtkDataSetFactory {
 public:
   /// Constructor
-  vtkSplatterPlotFactory(ThresholdRange_scptr thresholdRange,
-                         const std::string &scalarName,
+  vtkSplatterPlotFactory(const std::string &scalarName,
                          const size_t numPoints = 150000,
                          const double percentToUse = 5.0);
 
@@ -117,9 +115,6 @@ private:
   /// Add metadata
   void addMetadata() const;
 
-  /// Threshold range strategy.
-  ThresholdRange_scptr m_thresholdRange;
-
   /// Scalar name to provide on dataset.
   const std::string m_scalarName;
 
diff --git a/Vates/VatesAPI/src/ADSWorkspaceProvider.cpp b/Vates/VatesAPI/src/ADSWorkspaceProvider.cpp
index 126ebd059d4afd354c245564dc3c4d45f86db305..476f9c28c2f9806aa123ed421d976bd5d5027821 100644
--- a/Vates/VatesAPI/src/ADSWorkspaceProvider.cpp
+++ b/Vates/VatesAPI/src/ADSWorkspaceProvider.cpp
@@ -21,7 +21,7 @@ bool ADSWorkspaceProvider<Workspace_Type>::canProvideWorkspace(
   bool bCanProvide = false;
   try {
     bCanProvide =
-        (NULL !=
+        (nullptr !=
          AnalysisDataService::Instance().retrieveWS<Workspace_Type>(wsName));
   } catch (Mantid::Kernel::Exception::NotFoundError &) {
     bCanProvide = false;
diff --git a/Vates/VatesAPI/src/EventNexusLoadingPresenter.cpp b/Vates/VatesAPI/src/EventNexusLoadingPresenter.cpp
index b2fea4d15b185761d39f616efb196b96e9c56aad..36de7830aa4731e3e59f6a112e28c3f446658ccf 100644
--- a/Vates/VatesAPI/src/EventNexusLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/EventNexusLoadingPresenter.cpp
@@ -1,4 +1,5 @@
 #include "MantidVatesAPI/EventNexusLoadingPresenter.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IEventWorkspace.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
diff --git a/Vates/VatesAPI/src/FieldDataToMetadata.cpp b/Vates/VatesAPI/src/FieldDataToMetadata.cpp
index 95565ff10ab531771e78db50022c8c46f50a2d7e..561cf506093abfbd9a2cc1e379b2e11993d49856 100644
--- a/Vates/VatesAPI/src/FieldDataToMetadata.cpp
+++ b/Vates/VatesAPI/src/FieldDataToMetadata.cpp
@@ -14,17 +14,17 @@ std::string FieldDataToMetadata::operator()(vtkFieldData *fieldData,
 std::string FieldDataToMetadata::execute(vtkFieldData *fieldData,
                                          const std::string &id) const {
   std::string sXml;
-  if (fieldData == NULL) {
+  if (!fieldData) {
     throw std::runtime_error("vtkFieldData argument is null");
   }
-  vtkDataArray *arry = fieldData->GetArray(id.c_str());
-  if (arry == NULL) {
+  vtkDataArray *array = fieldData->GetArray(id.c_str());
+  if (!array) {
     throw std::runtime_error("The specified vtk array does not exist");
   }
-  if (vtkCharArray *carry = dynamic_cast<vtkCharArray *>(arry)) {
-    carry->Squeeze();
-    for (int i = 0; i < carry->GetSize(); i++) {
-      char c = carry->GetValue(i);
+  if (vtkCharArray *carray = vtkCharArray::FastDownCast(array)) {
+    carray->Squeeze();
+    for (int i = 0; i < carray->GetSize(); i++) {
+      char c = carray->GetValue(i);
       if (int(c) > 1) {
         sXml.push_back(c);
       }
diff --git a/Vates/VatesAPI/src/IMDDimensionComparitor.cpp b/Vates/VatesAPI/src/IMDDimensionComparitor.cpp
index f748933dd4ae06290d1f627057aee7da782f8503..38323a2abc4e67c1ac079c9884bfe8c06c3a885c 100644
--- a/Vates/VatesAPI/src/IMDDimensionComparitor.cpp
+++ b/Vates/VatesAPI/src/IMDDimensionComparitor.cpp
@@ -5,7 +5,7 @@ namespace VATES {
 
 IMDDimensionComparitor::IMDDimensionComparitor(
     Mantid::API::IMDWorkspace_sptr workspace)
-    : m_workspace(workspace) {}
+    : m_workspace(std::move(workspace)) {}
 
 IMDDimensionComparitor::~IMDDimensionComparitor() {}
 
@@ -21,12 +21,12 @@ bool IMDDimensionComparitor::isYDimension(
     Mantid::Geometry::IMDDimension_const_sptr queryDimension) {
   Mantid::Geometry::IMDDimension_const_sptr actualYDimension =
       m_workspace->getYDimension();
-  if (NULL == actualYDimension.get()) {
-    return false; // MDImages may have 1 dimension or more.
-  } else {
+  if (actualYDimension) {
     // Compare dimensions on the basis of their ids.
     return queryDimension->getDimensionId() ==
            actualYDimension->getDimensionId();
+  } else {
+    return false; // MDImages may have 1 dimension or more.
   }
 }
 
@@ -34,12 +34,12 @@ bool IMDDimensionComparitor::isZDimension(
     Mantid::Geometry::IMDDimension_const_sptr queryDimension) {
   Mantid::Geometry::IMDDimension_const_sptr actualZDimension =
       m_workspace->getZDimension();
-  if (NULL == actualZDimension.get()) {
-    return false; // MDImages may have 1 dimension or more.
-  } else {
+  if (actualZDimension) {
     // Compare dimensions on the basis of their ids.
     return queryDimension->getDimensionId() ==
            actualZDimension->getDimensionId();
+  } else {
+    return false; // MDImages may have 1 dimension or more.
   }
 }
 
@@ -47,13 +47,13 @@ bool IMDDimensionComparitor::istDimension(
     Mantid::Geometry::IMDDimension_const_sptr queryDimension) {
   Mantid::Geometry::IMDDimension_const_sptr actualtDimension =
       m_workspace->getTDimension();
-  if (NULL == actualtDimension.get()) {
-    return false; // MDImages may have 1 dimension or more.
-  } else {
+  if (actualtDimension) {
     // Compare dimensions on the basis of their ids.
     return queryDimension->getDimensionId() ==
            actualtDimension->getDimensionId();
+  } else {
+    return false; // MDImages may have 1 dimension or more.
   }
 }
 }
-}
\ No newline at end of file
+}
diff --git a/Vates/VatesAPI/src/IgnoreZerosThresholdRange.cpp b/Vates/VatesAPI/src/IgnoreZerosThresholdRange.cpp
deleted file mode 100644
index 949ffb5f2e6be798db99977f2a912da2773aa1a2..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/src/IgnoreZerosThresholdRange.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
-#include <stdexcept>
-
-namespace Mantid {
-namespace VATES {
-
-/**
-Constructor.
-*/
-IgnoreZerosThresholdRange::IgnoreZerosThresholdRange() : m_min(1), m_max(1) {}
-
-/**
-Constructor.
-*/
-IgnoreZerosThresholdRange::IgnoreZerosThresholdRange(signal_t min, signal_t max)
-    : m_min(min), m_max(max) {}
-
-/**
-Indicates wheter execution has occured or not.
-return : true always.
-*/
-bool IgnoreZerosThresholdRange::hasCalculated() const { return true; }
-
-/**
-Destructor.
-*/
-IgnoreZerosThresholdRange::~IgnoreZerosThresholdRange() {}
-
-/**
-Do nothing calculate method.
-*/
-void IgnoreZerosThresholdRange::calculate() {}
-
-/**
-Minimum value getter.
-@return The minimum value.
-*/
-double IgnoreZerosThresholdRange::getMinimum() const { return m_min; }
-
-/**
-Maximum value getter.
-@return The maximum value.
-*/
-double IgnoreZerosThresholdRange::getMaximum() const { return m_max; }
-
-/**
-Virtual constructor clone method.
-@return clone of original.
-*/
-IgnoreZerosThresholdRange *IgnoreZerosThresholdRange::clone() const {
-  return new IgnoreZerosThresholdRange(this->m_min, this->m_max);
-}
-
-/**
-Determine whether the signal is withing range.
-@param signal value
-@return true if the signal is in the range defined by this object.
-*/
-bool IgnoreZerosThresholdRange::inRange(const signal_t &signal) {
-  m_max = signal > m_max ? signal : m_max; // cache min and max values.
-  if (signal < m_min && 0 != signal) {
-    m_min = signal < m_min ? signal : m_min;
-  }
-  return signal != 0;
-}
-}
-}
diff --git a/Vates/VatesAPI/src/LoadVTK.cpp b/Vates/VatesAPI/src/LoadVTK.cpp
index 25e2570d3a38b6a727bfece221fbe10a557bd181..700481dc305a04233c986610747e52a0ddd41542 100644
--- a/Vates/VatesAPI/src/LoadVTK.cpp
+++ b/Vates/VatesAPI/src/LoadVTK.cpp
@@ -112,8 +112,7 @@ int LoadVTK::version() const { return 1; }
 const std::string LoadVTK::category() const { return "MDAlgorithms"; }
 
 void LoadVTK::init() {
-  std::vector<std::string> exts;
-  exts.push_back("vtk");
+  std::vector<std::string> exts{"vtk"};
   this->declareProperty(
       Kernel::make_unique<FileProperty>("Filename", "", FileProperty::Load,
                                         exts),
@@ -187,12 +186,13 @@ void LoadVTK::execMDHisto(vtkUnsignedShortArray *signals,
   double *destinationSignals = outputWS->getSignalArray();
   double *destinationErrorsSQ = outputWS->getErrorSquaredArray();
 
-  if (errorsSQ == NULL) {
+  if (errorsSQ) {
     PARALLEL_FOR_NO_WSP_CHECK()
     for (int64_t i = 0; i < nPoints; ++i) {
       PARALLEL_START_INTERUPT_REGION
       // cppcheck-suppress unreadVariable
       destinationSignals[i] = signals->GetValue(i);
+      destinationErrorsSQ[i] = errorsSQ->GetValue(i);
       if (i % frequency == 0)
         prog.report();
       PARALLEL_END_INTERUPT_REGION
@@ -204,14 +204,12 @@ void LoadVTK::execMDHisto(vtkUnsignedShortArray *signals,
       PARALLEL_START_INTERUPT_REGION
       // cppcheck-suppress unreadVariable
       destinationSignals[i] = signals->GetValue(i);
-      destinationErrorsSQ[i] = errorsSQ->GetValue(i);
       if (i % frequency == 0)
         prog.report();
       PARALLEL_END_INTERUPT_REGION
     }
     PARALLEL_CHECK_INTERUPT_REGION
   }
-
   prog.report("Complete");
   this->setProperty("OutputWorkspace", outputWS);
 }
@@ -257,16 +255,16 @@ void LoadVTK::execMDEvent(vtkDataSet *readDataset,
   ws->addDimension(dimZ);
   ws->initialize();
 
-  if (errorsSQ == NULL) {
+  if (errorsSQ) {
     PARALLEL_FOR_IF(Kernel::threadSafe(*ws))
     for (int64_t i = 0; i < nPoints; ++i) {
       PARALLEL_START_INTERUPT_REGION
       double coordinates[3];
       readDataset->GetPoint(i, coordinates);
       float signal = signals->GetValue(i);
-
+      float errorSQ = errorsSQ->GetValue(i);
       if (signal > lowerBounds) {
-        MDLeanEvent<3> event(signal, 0, coordinates);
+        MDLeanEvent<3> event(signal, errorSQ, coordinates);
         ws->addEvent(event);
       }
       if (i % frequency == 0)
@@ -281,9 +279,9 @@ void LoadVTK::execMDEvent(vtkDataSet *readDataset,
       double coordinates[3];
       readDataset->GetPoint(i, coordinates);
       float signal = signals->GetValue(i);
-      float errorSQ = errorsSQ->GetValue(i);
+
       if (signal > lowerBounds) {
-        MDLeanEvent<3> event(signal, errorSQ, coordinates);
+        MDLeanEvent<3> event(signal, 0, coordinates);
         ws->addEvent(event);
       }
       if (i % frequency == 0)
@@ -316,16 +314,16 @@ void LoadVTK::exec() {
   vtkSmartPointer<vtkStructuredPoints> readDataset;
   readDataset.TakeReference(reader->GetOutput());
 
-  vtkUnsignedShortArray *signals = vtkUnsignedShortArray::SafeDownCast(
+  vtkUnsignedShortArray *signals = vtkUnsignedShortArray::FastDownCast(
       readDataset->GetPointData()->GetArray(signalArrayName.c_str()));
-  if (signals == NULL) {
+  if (!signals) {
     throw std::invalid_argument("Signal array: " + signalArrayName +
                                 " does not exist");
   }
 
-  vtkUnsignedShortArray *errorsSQ = vtkUnsignedShortArray::SafeDownCast(
+  vtkUnsignedShortArray *errorsSQ = vtkUnsignedShortArray::FastDownCast(
       readDataset->GetPointData()->GetArray(errorSQArrayName.c_str()));
-  if (!errorSQArrayName.empty() && errorsSQ == NULL) {
+  if (!errorSQArrayName.empty() && !errorsSQ) {
     throw std::invalid_argument("Error squared array: " + errorSQArrayName +
                                 " does not exist");
   }
diff --git a/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp b/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp
index e6140965d176d2b46e4698576b925a0965c35a15..81cc8b7afd0a2764e51dec715f01108be679c5ea 100644
--- a/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/MDEWEventNexusLoadingPresenter.cpp
@@ -1,4 +1,5 @@
 #include "MantidVatesAPI/MDEWEventNexusLoadingPresenter.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidVatesAPI/MDLoadingView.h"
 #include "MantidVatesAPI/ProgressAction.h"
@@ -23,13 +24,13 @@ Constructor
 @throw logic_error if cannot use the reader-presenter for this filetype.
 */
 MDEWEventNexusLoadingPresenter::MDEWEventNexusLoadingPresenter(
-    std::unique_ptr<MDLoadingView> view, const std::string filename)
+    std::unique_ptr<MDLoadingView> view, const std::string &filename)
     : MDEWLoadingPresenter(std::move(view)), m_filename(filename),
-      m_wsTypeName("") {
+      m_wsTypeName() {
   if (this->m_filename.empty()) {
     throw std::invalid_argument("File name is an empty string.");
   }
-  if (nullptr == this->m_view) {
+  if (!this->m_view) {
     throw std::invalid_argument("View is NULL.");
   }
 }
@@ -45,17 +46,13 @@ bool MDEWEventNexusLoadingPresenter::canReadFile() const {
     return 0;
   }
 
-  ::NeXus::File *file = NULL;
-
-  file = new ::NeXus::File(this->m_filename);
+  auto file = Kernel::make_unique<::NeXus::File>(this->m_filename);
   // MDEventWorkspace file has a different name for the entry
   try {
     file->openGroup("MDEventWorkspace", "NXentry");
-    file->close();
     return 1;
   } catch (::NeXus::Exception &) {
     // If the entry name does not match, then it can't read the file.
-    file->close();
     return 0;
   }
   return 0;
diff --git a/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp b/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp
index 33b1f390a9659dd4416b84f22628a1348fb44185..05fac0698d89118be5a473bfca25098af6289d91 100644
--- a/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/MDEWLoadingPresenter.cpp
@@ -2,6 +2,7 @@
 #include "MantidVatesAPI/MDLoadingView.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 
 #include "MantidGeometry/MDGeometry/NullImplicitFunction.h"
 #include "MantidVatesAPI/VatesKnowledgeSerializer.h"
diff --git a/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
index baad4f41b9ebf32198e3e266d72031ba7a73a676..a4d9346b5f548ad0bd6c76d693b4bdcdf9af41b0 100644
--- a/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
@@ -2,7 +2,6 @@
 #include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidGeometry/MDGeometry/MDGeometryXMLBuilder.h"
-#include "MantidKernel/MultiThreaded.h"
 #include "MantidVatesAPI/FactoryChains.h"
 #include "MantidVatesAPI/MDLoadingView.h"
 #include "MantidVatesAPI/MetaDataExtractorUtils.h"
@@ -11,6 +10,7 @@
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include <qwt_double_interval.h>
 
+#include "tbb/tbb.h"
 #include "vtkStructuredGrid.h"
 #include "vtkUnsignedCharArray.h"
 #include "vtkUnstructuredGrid.h"
@@ -35,10 +35,10 @@ MDHWInMemoryLoadingPresenter::MDHWInMemoryLoadingPresenter(
   if (m_wsName.empty()) {
     throw std::invalid_argument("The workspace name is empty.");
   }
-  if (NULL == repository) {
+  if (!repository) {
     throw std::invalid_argument("The repository is NULL");
   }
-  if (nullptr == m_view) {
+  if (!m_view) {
     throw std::invalid_argument("View is NULL.");
   }
 }
@@ -53,14 +53,13 @@ bool MDHWInMemoryLoadingPresenter::canReadFile() const {
   if (!m_repository->canProvideWorkspace(m_wsName)) {
     // The workspace does not exist.
     bCanReadIt = false;
-  } else if (NULL ==
-             boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(
-                 m_repository->fetchWorkspace(m_wsName)).get()) {
+  } else if (boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(
+                 m_repository->fetchWorkspace(m_wsName))) {
     // The workspace can be found, but is not an IMDHistoWorkspace.
-    bCanReadIt = false;
+    bCanReadIt = true;
   } else {
     // The workspace is present, and is of the correct type.
-    bCanReadIt = true;
+    bCanReadIt = false;
   }
   return bCanReadIt;
 }
@@ -84,27 +83,44 @@ private:
   const unsigned char *InputCellGhostArray;
 };
 
+struct MinAndMax {
+  double m_minimum = VTK_DOUBLE_MAX;
+  double m_maximum = VTK_DOUBLE_MIN;
+  vtkDataArray *m_cellScalars;
+  CellVisibility m_isCellVisible;
+  MinAndMax(vtkDataArray *cellScalars, const unsigned char *cellGhostArray)
+      : m_cellScalars(cellScalars), m_isCellVisible(cellGhostArray) {}
+  MinAndMax(MinAndMax &rhs, tbb::split)
+      : m_cellScalars(rhs.m_cellScalars), m_isCellVisible(rhs.m_isCellVisible) {
+  }
+  void operator()(const tbb::blocked_range<int> &r) {
+    for (int id = r.begin(); id != r.end(); ++id) {
+      if (m_isCellVisible(id)) {
+        double s = m_cellScalars->GetComponent(id, 0);
+        m_minimum = std::min(m_minimum, s);
+        m_maximum = std::max(m_maximum, s);
+      }
+    }
+  }
+  void join(MinAndMax &rhs) {
+    m_minimum = std::min(m_minimum, rhs.m_minimum);
+    m_maximum = std::max(m_maximum, rhs.m_maximum);
+  }
+};
+
 void ComputeScalarRange(vtkStructuredGrid *grid, double *cellRange) {
-  auto cga = grid->GetCellGhostArray();
-  CellVisibility isCellVisible(cga ? cga->GetPointer(0) : nullptr);
   vtkDataArray *cellScalars = grid->GetCellData()->GetScalars();
-  double minvalue = VTK_DOUBLE_MAX;
-  double maxvalue = VTK_DOUBLE_MIN;
+  auto cga = grid->GetCellGhostArray();
+  MinAndMax minandmax(cellScalars, cga ? cga->GetPointer(0) : nullptr);
+
   int num = boost::numeric_cast<int>(grid->GetNumberOfCells());
-#if defined(_OPENMP) && _OPENMP >= 200805
-  PRAGMA_OMP(parallel for reduction(min : minvalue) reduction(max : maxvalue))
-#endif
-  for (int id = 0; id < num; id++) {
-    if (isCellVisible(id)) {
-      double s = cellScalars->GetComponent(id, 0);
-      minvalue = std::min(minvalue, s);
-      maxvalue = std::max(maxvalue, s);
-    }
-  }
-  cellRange[0] = minvalue;
-  cellRange[1] = maxvalue;
+  tbb::parallel_reduce(tbb::blocked_range<int>(0, num), minandmax);
+
+  cellRange[0] = minandmax.m_minimum;
+  cellRange[1] = minandmax.m_maximum;
 }
 }
+
 /*
 Executes the underlying algorithm to create the MVP model.
 @param factory : visualisation factory to use.
@@ -139,9 +155,9 @@ MDHWInMemoryLoadingPresenter::execute(vtkDataSetFactory *factory,
   // Until this is addressed in VTK, we are better of doing the calculation
   // ourselves.
   // 600x600x600 vtkStructuredGrid, every other cell blank
-  // structuredGrid->GetScalarRange(range) : 2.36625s
-  // structuredGrid->GetCellData()->GetScalars()->GetRange(range) : 1.01453s
-  // ComputeScalarRange(structuredGrid,range): 0.086104s
+  // structuredGrid->GetScalarRange(range) : 2.267s
+  // structuredGrid->GetCellData()->GetScalars()->GetRange(range) : 1.023s
+  // ComputeScalarRange(structuredGrid,range): 0.075s
   double range[2];
   if (auto structuredGrid = vtkStructuredGrid::SafeDownCast(visualDataSet)) {
     ComputeScalarRange(structuredGrid, range);
diff --git a/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp b/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp
index 0439d1c6c0641478762ae3852f4d4c5d7ce0f437..2498623bdf4cce842f9149e6a6f171b1e437dde0 100644
--- a/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/MDHWLoadingPresenter.cpp
@@ -5,6 +5,7 @@
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidGeometry/MDGeometry/NullImplicitFunction.h"
 #include "MantidVatesAPI/VatesKnowledgeSerializer.h"
@@ -18,6 +19,8 @@
 #include "MantidVatesAPI/Common.h"
 
 #include <boost/scoped_ptr.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
+#include <boost/algorithm/string/trim.hpp>
 
 #include <vtkPVChangeOfBasisHelper.h>
 #include <vtkFieldData.h>
diff --git a/Vates/VatesAPI/src/MDHWNexusLoadingPresenter.cpp b/Vates/VatesAPI/src/MDHWNexusLoadingPresenter.cpp
index 9bb01b22c40a5c77a9bc1cc280ee6e57630d13a4..58459754a807b6e458e0b3bc3dd1bba1c57f9482 100644
--- a/Vates/VatesAPI/src/MDHWNexusLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/MDHWNexusLoadingPresenter.cpp
@@ -1,4 +1,5 @@
 #include "MantidVatesAPI/MDHWNexusLoadingPresenter.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidVatesAPI/MDLoadingView.h"
 #include "MantidVatesAPI/ProgressAction.h"
@@ -44,17 +45,13 @@ bool MDHWNexusLoadingPresenter::canReadFile() const {
   if (!canLoadFileBasedOnExtension(m_filename, ".nxs")) {
     return 0;
   }
-  ::NeXus::File *file = NULL;
-
-  file = new ::NeXus::File(this->m_filename);
+  auto file = Kernel::make_unique<::NeXus::File>(this->m_filename);
   // MDHistoWorkspace file has a different name for the entry
   try {
     file->openGroup("MDHistoWorkspace", "NXentry");
-    file->close();
     return 1;
   } catch (::NeXus::Exception &) {
     // If the entry name does not match, then it can't read the file.
-    file->close();
     return 0;
   }
   return 0;
diff --git a/Vates/VatesAPI/src/MedianAndBelowThresholdRange.cpp b/Vates/VatesAPI/src/MedianAndBelowThresholdRange.cpp
deleted file mode 100644
index acfb839a48c7cef41fee732db4a4326b75ac091a..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/src/MedianAndBelowThresholdRange.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "MantidVatesAPI/MedianAndBelowThresholdRange.h"
-#include "MantidAPI/IMDIterator.h"
-#include <cmath>
-
-namespace Mantid {
-namespace VATES {
-
-/**
-Constructor
-*/
-MedianAndBelowThresholdRange::MedianAndBelowThresholdRange()
-    : m_min(0.00), m_max(0), m_isCalculated(false) {}
-
-/**
-Constructor
-*/
-MedianAndBelowThresholdRange::MedianAndBelowThresholdRange(
-    signal_t min, signal_t max, bool isCalculated,
-    Mantid::API::IMDWorkspace_sptr workspace)
-    : m_min(min), m_max(max), m_isCalculated(isCalculated),
-      m_workspace(workspace) {}
-
-/// Destructor
-MedianAndBelowThresholdRange::~MedianAndBelowThresholdRange() {}
-
-/**
-Overriden calculate method.
-*/
-void MedianAndBelowThresholdRange::calculate() {
-  if (NULL == m_workspace.get()) {
-    throw std::logic_error("The workspace has not been set.");
-  }
-
-  signal_t signal = 0;
-  signal_t accumulated_signal = 0;
-
-  Mantid::API::IMDIterator *it = m_workspace->createIterator();
-  do {
-    signal = it->getNormalizedSignal();
-    accumulated_signal += signal;
-    m_min = signal < m_min ? signal : m_min;
-  } while (it->next());
-
-  m_max = accumulated_signal / static_cast<signal_t>(it->getDataSize());
-  m_isCalculated = true;
-}
-
-/**
-Indicates wheter execution has occured or not.
-@return : true if calculate has been called previously, otherwise false.
-*/
-bool MedianAndBelowThresholdRange::hasCalculated() const {
-  return m_isCalculated;
-}
-
-/**
-Getter for the calculated minimum value.
-*/
-signal_t MedianAndBelowThresholdRange::getMinimum() const {
-  if (!m_isCalculated) {
-    throw std::runtime_error(
-        "Cannot call ::getMinimum() without first calling ::calculate()");
-  }
-  return m_min;
-}
-
-/**
-Getter for the calculated maximum value.
-*/
-signal_t MedianAndBelowThresholdRange::getMaximum() const {
-  if (!m_isCalculated) {
-    throw std::runtime_error(
-        "Cannot call ::getMaximum() without first calling ::calculate()");
-  }
-  return m_max;
-}
-
-/**
-Virtual constructor clone method.
-@return clone as MedianAndBelowThresholdRange*.
-*/
-MedianAndBelowThresholdRange *MedianAndBelowThresholdRange::clone() const {
-  return new MedianAndBelowThresholdRange(m_min, m_max, m_isCalculated,
-                                          this->m_workspace);
-}
-
-/**
-Setter for IMDWorkspace.
-@param workspace : The workspace to extract ranges from.
-*/
-void MedianAndBelowThresholdRange::setWorkspace(
-    Mantid::API::Workspace_sptr workspace) {
-  m_isCalculated = false;
-  m_workspace =
-      boost::dynamic_pointer_cast<Mantid::API::IMDWorkspace>(workspace);
-  if (!workspace) {
-    throw std::logic_error(
-        "MedianAndBelowThresholdRange only works for IMDWorkspaces");
-  }
-}
-
-/**
-Determine whether the signal is withing range.
-@param signal value
-@return true if the signal is in the range defined by this object.
-*/
-bool MedianAndBelowThresholdRange::inRange(const signal_t &signal) {
-  return signal != 0 && signal < m_max;
-}
-}
-}
diff --git a/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp b/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp
index 5d520a305637464ca464502c7f0ed4e533f00b64..662b3f84d185cc2a746adaa659ee1bb5f382a891 100644
--- a/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp
+++ b/Vates/VatesAPI/src/MetaDataExtractorUtils.cpp
@@ -7,6 +7,7 @@
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidGeometry/Instrument.h"
 #include "MantidKernel/Logger.h"
+#include "MantidKernel/MultiThreaded.h"
 #include "boost/pointer_cast.hpp"
 #include <cfloat>
 
@@ -78,7 +79,8 @@ MetaDataExtractorUtils::getMinAndMax(Mantid::API::IMDWorkspace_sptr workspace) {
   if (!workspace)
     throw std::invalid_argument("The workspace is empty.");
 
-  auto iterators = workspace->createIterators(PARALLEL_GET_MAX_THREADS, 0);
+  auto iterators =
+      workspace->createIterators(PARALLEL_GET_MAX_THREADS, nullptr);
 
   std::vector<QwtDoubleInterval> intervals(iterators.size());
   // cppcheck-suppress syntaxError
diff --git a/Vates/VatesAPI/src/MetadataToFieldData.cpp b/Vates/VatesAPI/src/MetadataToFieldData.cpp
index 4cafe5c4ace83099a20782df52adad4530adc874..35544546b7b10307e43f0b7785a4ed11d429b29e 100644
--- a/Vates/VatesAPI/src/MetadataToFieldData.cpp
+++ b/Vates/VatesAPI/src/MetadataToFieldData.cpp
@@ -7,26 +7,26 @@ namespace Mantid {
 namespace VATES {
 
 void MetadataToFieldData::operator()(vtkFieldData *fieldData,
-                                     std::string metaData,
-                                     std::string id) const {
+                                     const std::string &metaData,
+                                     const std::string &id) const {
   execute(fieldData, metaData, id);
 }
 
-void MetadataToFieldData::execute(vtkFieldData *fieldData, std::string metaData,
-                                  std::string id) const {
+void MetadataToFieldData::execute(vtkFieldData *fieldData,
+                                  const std::string &metaData,
+                                  const std::string &id) const {
   // clean out existing.
-  vtkDataArray *arry = fieldData->GetArray(id.c_str());
-  if (NULL != arry) {
+  vtkDataArray *array = fieldData->GetArray(id.c_str());
+  if (array) {
     fieldData->RemoveArray(id.c_str());
   }
   // create new.
-  vtkNew<vtkCharArray> newArry;
-  newArry->Allocate(metaData.size());
-  newArry->SetName(id.c_str());
-  fieldData->AddArray(newArry.GetPointer());
-
-  for (unsigned int i = 0; i < metaData.size(); i++) {
-    newArry->InsertNextValue(metaData.at(i));
+  vtkNew<vtkCharArray> newArray;
+  newArray->SetNumberOfTuples(metaData.size());
+  newArray->SetName(id.c_str());
+  fieldData->AddArray(newArray.GetPointer());
+  for (size_t i = 0; i < metaData.size(); i++) {
+    newArray->SetValue(i, metaData[i]);
   }
 }
 }
diff --git a/Vates/VatesAPI/src/NoThresholdRange.cpp b/Vates/VatesAPI/src/NoThresholdRange.cpp
deleted file mode 100644
index 6f605e03f8ddfcefde7a97cef6a4c1f717d073a5..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/src/NoThresholdRange.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "MantidVatesAPI/NoThresholdRange.h"
-#include <stdexcept>
-
-namespace Mantid {
-namespace VATES {
-
-/**
-Constructor.
-*/
-NoThresholdRange::NoThresholdRange() : m_min(0), m_max(0) {}
-
-/**
-Constructor.
-*/
-NoThresholdRange::NoThresholdRange(signal_t min, signal_t max)
-    : m_min(min), m_max(max) {}
-
-/**
-Indicates wheter execution has occured or not.
-return : true always.
-*/
-bool NoThresholdRange::hasCalculated() const { return true; }
-
-/**
-Destructor.
-*/
-NoThresholdRange::~NoThresholdRange() {}
-
-/**
-Do nothing calculate method.
-*/
-void NoThresholdRange::calculate() {}
-
-/**
-Minimum value getter.
-@return The minimum value.
-*/
-double NoThresholdRange::getMinimum() const { return m_min; }
-
-/**
-Maximum value getter.
-@return The maximum value.
-*/
-double NoThresholdRange::getMaximum() const { return m_max; }
-
-/**
-Virtual constructor clone method.
-@return clone of original.
-*/
-NoThresholdRange *NoThresholdRange::clone() const {
-  return new NoThresholdRange(this->m_min, this->m_max);
-}
-
-/**
-Determine whether the signal is withing range.
-@param signal value
-@return true if the signal is in the range defined by this object.
-*/
-bool NoThresholdRange::inRange(const signal_t &signal) {
-  m_max = signal > m_max ? signal : m_max; // cache min and max values.
-  m_min = signal < m_min ? signal : m_min;
-  return true;
-}
-}
-}
diff --git a/Vates/VatesAPI/src/PresenterUtilities.cpp b/Vates/VatesAPI/src/PresenterUtilities.cpp
index 6e6761abea534753acd52f31459d5654cb580a0a..8577c9a5186cefbce8ba0795645875f9dd8d4726 100644
--- a/Vates/VatesAPI/src/PresenterUtilities.cpp
+++ b/Vates/VatesAPI/src/PresenterUtilities.cpp
@@ -2,7 +2,6 @@
 #include "MantidVatesAPI/FactoryChains.h"
 
 #include "MantidVatesAPI/MDLoadingPresenter.h"
-#include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHistoLineFactory.h"
 #include "MantidVatesAPI/vtkMDHistoQuadFactory.h"
 #include "MantidVatesAPI/vtkMDHistoHexFactory.h"
@@ -77,21 +76,18 @@ void applyCOBMatrixSettingsToVtkDataSet(
 
 /**
  * Creates a factory chain for MDEvent workspaces
- * @param threshold: the threshold range
  * @param normalization: the normalization option
  * @param time: the time slice time
  * @returns a factory chain
  */
 std::unique_ptr<vtkMDHexFactory>
-createFactoryChainForEventWorkspace(ThresholdRange_scptr threshold,
-                                    VisualNormalization normalization,
+createFactoryChainForEventWorkspace(VisualNormalization normalization,
                                     double time) {
-  auto factory =
-      Mantid::Kernel::make_unique<vtkMDHexFactory>(threshold, normalization);
-  factory->setSuccessor(Mantid::Kernel::make_unique<vtkMDQuadFactory>(
-                            threshold, normalization))
-      .setSuccessor(Mantid::Kernel::make_unique<vtkMDLineFactory>(
-          threshold, normalization))
+  auto factory = Mantid::Kernel::make_unique<vtkMDHexFactory>(normalization);
+  factory->setSuccessor(
+               Mantid::Kernel::make_unique<vtkMDQuadFactory>(normalization))
+      .setSuccessor(
+           Mantid::Kernel::make_unique<vtkMDLineFactory>(normalization))
       .setSuccessor(Mantid::Kernel::make_unique<vtkMD0DFactory>());
   factory->setTime(time);
   return factory;
@@ -99,24 +95,22 @@ createFactoryChainForEventWorkspace(ThresholdRange_scptr threshold,
 
 /**
 * Creates a factory chain for MDHisto workspaces
-* @param threshold: the threshold range
 * @param normalization: the normalization option
 * @param time: the time slice time
 * @returns a factory chain
 */
 std::unique_ptr<vtkMDHistoHex4DFactory<TimeToTimeStep>>
-createFactoryChainForHistoWorkspace(ThresholdRange_scptr threshold,
-                                    VisualNormalization normalization,
+createFactoryChainForHistoWorkspace(VisualNormalization normalization,
                                     double time) {
   auto factory =
       Mantid::Kernel::make_unique<vtkMDHistoHex4DFactory<TimeToTimeStep>>(
-          threshold, normalization, time);
-  factory->setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(
-                            threshold, normalization))
-      .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoQuadFactory>(
-          threshold, normalization))
-      .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoLineFactory>(
-          threshold, normalization))
+          normalization, time);
+  factory->setSuccessor(
+               Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(normalization))
+      .setSuccessor(
+           Mantid::Kernel::make_unique<vtkMDHistoQuadFactory>(normalization))
+      .setSuccessor(
+           Mantid::Kernel::make_unique<vtkMDHistoLineFactory>(normalization))
       .setSuccessor(Mantid::Kernel::make_unique<vtkMD0DFactory>());
   return factory;
 }
diff --git a/Vates/VatesAPI/src/SQWLoadingPresenter.cpp b/Vates/VatesAPI/src/SQWLoadingPresenter.cpp
index b7026167a68f2cc2094ceac4467c5ede9a5347fd..d8109833b6003a25f8cb7cc0bb921e8df09dd669 100644
--- a/Vates/VatesAPI/src/SQWLoadingPresenter.cpp
+++ b/Vates/VatesAPI/src/SQWLoadingPresenter.cpp
@@ -1,4 +1,5 @@
 #include "MantidVatesAPI/SQWLoadingPresenter.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidVatesAPI/Common.h"
 #include "MantidVatesAPI/MDLoadingView.h"
@@ -6,6 +7,7 @@
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include <boost/regex.hpp>
 
 namespace Mantid {
diff --git a/Vates/VatesAPI/src/SaveMDWorkspaceToVTK.cpp b/Vates/VatesAPI/src/SaveMDWorkspaceToVTK.cpp
index e7b77406bbe7a8aaf374806215c5010f57cbbee7..d57f061b27a5145e68ba9d8ed24c5b94c9d71366 100644
--- a/Vates/VatesAPI/src/SaveMDWorkspaceToVTK.cpp
+++ b/Vates/VatesAPI/src/SaveMDWorkspaceToVTK.cpp
@@ -18,7 +18,7 @@ namespace VATES {
 DECLARE_ALGORITHM(SaveMDWorkspaceToVTK)
 
 SaveMDWorkspaceToVTK::SaveMDWorkspaceToVTK()
-    : saver(Mantid::Kernel::make_unique<SaveMDWorkspaceToVTKImpl>()) {}
+    : saver(Mantid::Kernel::make_unique<SaveMDWorkspaceToVTKImpl>(this)) {}
 
 SaveMDWorkspaceToVTK::~SaveMDWorkspaceToVTK() {}
 
@@ -60,13 +60,6 @@ void SaveMDWorkspaceToVTK::init() {
       "The visual normalization option. The automatic default will choose a "
       "normalization based on your data type and instrument.");
 
-  auto thresholds = saver->getAllowedThresholdsInStringRepresentation();
-  declareProperty(
-      "ThresholdRange", "IgnoreZerosThresholdRange",
-      boost::make_shared<Mantid::Kernel::StringListValidator>(thresholds),
-      "The threshold range. Currently either no threshold or an ignore-zeros "
-      "policy can be applied.");
-
   boost::shared_ptr<Mantid::Kernel::BoundedValidator<int>> mustBePositive(
       new Mantid::Kernel::BoundedValidator<int>());
   mustBePositive->setLower(1);
@@ -90,18 +83,13 @@ void SaveMDWorkspaceToVTK::exec() {
   auto normalization = saver->translateStringToVisualNormalization(
       normalizationInStringRepresentation);
 
-  std::string thresholdRangeInStringRepresentation =
-      this->getProperty("ThresholdRange");
-  auto thresholdRange = saver->translateStringToThresholdRange(
-      thresholdRangeInStringRepresentation);
-
   int recursionDepth = this->getProperty("RecursionDepth");
 
   std::string compressorType = this->getProperty("CompressorType");
 
   // Save workspace into file
-  saver->saveMDWorkspace(inputWS, filename, normalization, thresholdRange,
-                         recursionDepth, compressorType);
+  saver->saveMDWorkspace(inputWS, filename, normalization, recursionDepth,
+                         compressorType);
 }
 
 std::map<std::string, std::string> SaveMDWorkspaceToVTK::validateInputs() {
diff --git a/Vates/VatesAPI/src/SaveMDWorkspaceToVTKImpl.cpp b/Vates/VatesAPI/src/SaveMDWorkspaceToVTKImpl.cpp
index 1d7440130c49f53cd459f63e419a020fca5c623e..0552e1b5577f9353429fe0e0b4211697b18a8134 100644
--- a/Vates/VatesAPI/src/SaveMDWorkspaceToVTKImpl.cpp
+++ b/Vates/VatesAPI/src/SaveMDWorkspaceToVTKImpl.cpp
@@ -1,9 +1,6 @@
 #include "MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h"
 #include "MantidVatesAPI/Normalization.h"
 
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
-
 #include "MantidVatesAPI/FactoryChains.h"
 #include "MantidVatesAPI/MDEWInMemoryLoadingPresenter.h"
 #include "MantidVatesAPI/MDHWInMemoryLoadingPresenter.h"
@@ -18,6 +15,7 @@
 #include "MantidKernel/Logger.h"
 #include "MantidKernel/make_unique.h"
 
+#include "vtkCallbackCommand.h"
 #include "vtkFloatArray.h"
 #include "vtkNew.h"
 #include "vtkSmartPointer.h"
@@ -26,6 +24,7 @@
 #include "vtkXMLUnstructuredGridWriter.h"
 
 #include <boost/make_shared.hpp>
+#include <boost/math/special_functions/round.hpp>
 #include <memory>
 
 namespace {
@@ -60,22 +59,24 @@ namespace VATES {
 const std::string SaveMDWorkspaceToVTKImpl::structuredGridExtension = "vts";
 const std::string SaveMDWorkspaceToVTKImpl::unstructuredGridExtension = "vtu";
 
-SaveMDWorkspaceToVTKImpl::SaveMDWorkspaceToVTKImpl() { setupMembers(); }
+SaveMDWorkspaceToVTKImpl::SaveMDWorkspaceToVTKImpl(SaveMDWorkspaceToVTK *parent)
+    : m_progress(parent, 0.0, 1.0, 101) {
+  setupMembers();
+}
 
 /**
  * Save an MD workspace to a vts/vtu file.
  * @param workspace: the workspace which is to be saved.
  * @param filename: the name of the file to which the workspace is to be saved.
  * @param normalization: the visual normalization option
- * @param thresholdRange: a plolicy for the threshold range
  * @param recursionDepth: the recursion depth for MDEvent Workspaces determines
  * @param compressorType: the compression type used by VTK
  * from which level data should be displayed
  */
 void SaveMDWorkspaceToVTKImpl::saveMDWorkspace(
     Mantid::API::IMDWorkspace_sptr workspace, const std::string &filename,
-    VisualNormalization normalization, ThresholdRange_scptr thresholdRange,
-    int recursionDepth, const std::string &compressorType) const {
+    VisualNormalization normalization, int recursionDepth,
+    const std::string &compressorType) const {
   auto isHistoWorkspace =
       boost::dynamic_pointer_cast<Mantid::API::IMDHistoWorkspace>(workspace) !=
       nullptr;
@@ -98,8 +99,8 @@ void SaveMDWorkspaceToVTKImpl::saveMDWorkspace(
   auto time = selectTimeSliceValue(workspace);
 
   // Get presenter and data set factory set up
-  auto factoryChain = getDataSetFactoryChain(isHistoWorkspace, thresholdRange,
-                                             normalization, time);
+  auto factoryChain =
+      getDataSetFactoryChain(isHistoWorkspace, normalization, time);
 
   auto presenter = getPresenter(isHistoWorkspace, workspace, recursionDepth);
 
@@ -145,22 +146,19 @@ void SaveMDWorkspaceToVTKImpl::saveMDWorkspace(
 /**
  * Creates the correct factory chain based
  * @param isHistoWorkspace: flag if workspace is MDHisto
- * @param thresholdRange: the threshold range
  * @param normalization: the normalization option
  * @param time: the time slice info
  * @returns a data set factory
  */
 std::unique_ptr<vtkDataSetFactory>
 SaveMDWorkspaceToVTKImpl::getDataSetFactoryChain(
-    bool isHistoWorkspace, ThresholdRange_scptr thresholdRange,
-    VisualNormalization normalization, double time) const {
+    bool isHistoWorkspace, VisualNormalization normalization,
+    double time) const {
   std::unique_ptr<vtkDataSetFactory> factory;
   if (isHistoWorkspace) {
-    factory = createFactoryChainForHistoWorkspace(thresholdRange, normalization,
-                                                  time);
+    factory = createFactoryChainForHistoWorkspace(normalization, time);
   } else {
-    factory = createFactoryChainForEventWorkspace(thresholdRange, normalization,
-                                                  time);
+    factory = createFactoryChainForEventWorkspace(normalization, time);
   }
   return factory;
 }
@@ -195,6 +193,22 @@ SaveMDWorkspaceToVTKImpl::getPresenter(bool isHistoWorkspace,
   return presenter;
 }
 
+void ProgressFunction(vtkObject *caller, long unsigned int vtkNotUsed(eventId),
+                      void *clientData, void *vtkNotUsed(callData)) {
+  vtkXMLWriter *testFilter = dynamic_cast<vtkXMLWriter *>(caller);
+  if (!testFilter)
+    return;
+  const char *progressText = testFilter->GetProgressText();
+  if (progressText) {
+    reinterpret_cast<Kernel::ProgressBase *>(clientData)
+        ->report(boost::math::iround(testFilter->GetProgress() * 100.0),
+                 progressText);
+  } else {
+    reinterpret_cast<Kernel::ProgressBase *>(clientData)
+        ->report(boost::math::iround(testFilter->GetProgress() * 100.0));
+  }
+}
+
 /**
  * Write an unstructured grid or structured grid to a vtk file.
  * @param writer: a vtk xml writer
@@ -206,6 +220,10 @@ SaveMDWorkspaceToVTKImpl::getPresenter(bool isHistoWorkspace,
 int SaveMDWorkspaceToVTKImpl::writeDataSetToVTKFile(
     vtkXMLWriter *writer, vtkDataSet *dataSet, const std::string &filename,
     vtkXMLWriter::CompressorType compressor) const {
+  vtkNew<vtkCallbackCommand> progressCallback;
+  progressCallback->SetCallback(ProgressFunction);
+  writer->AddObserver(vtkCommand::ProgressEvent, progressCallback.GetPointer());
+  progressCallback->SetClientData(&m_progress);
   writer->SetFileName(filename.c_str());
   writer->SetInputData(dataSet);
   writer->SetCompressorType(compressor);
@@ -243,26 +261,6 @@ void SaveMDWorkspaceToVTKImpl::setupMembers() {
                            VisualNormalization::NumEventsNormalization);
   m_normalizations.emplace("VolumeNormalization",
                            VisualNormalization::VolumeNormalization);
-
-  m_thresholds.emplace_back("IgnoreZerosThresholdRange");
-  m_thresholds.emplace_back("NoThresholdRange");
-}
-
-std::vector<std::string>
-SaveMDWorkspaceToVTKImpl::getAllowedThresholdsInStringRepresentation() const {
-  return m_thresholds;
-}
-
-ThresholdRange_scptr SaveMDWorkspaceToVTKImpl::translateStringToThresholdRange(
-    const std::string thresholdRange) const {
-  if (thresholdRange == m_thresholds[0]) {
-    return boost::make_shared<IgnoreZerosThresholdRange>();
-  } else if (thresholdRange == m_thresholds[1]) {
-    return boost::make_shared<NoThresholdRange>();
-  } else {
-    throw std::runtime_error("SaveMDWorkspaceToVTK: The selected threshold "
-                             "range seems to be incorrect.");
-  }
 }
 
 /**
diff --git a/Vates/VatesAPI/src/UserDefinedThresholdRange.cpp b/Vates/VatesAPI/src/UserDefinedThresholdRange.cpp
deleted file mode 100644
index a47a679ef1114cf69f03a2e3746ffd72f70623b9..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/src/UserDefinedThresholdRange.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
-#include <stdexcept>
-
-namespace Mantid {
-namespace VATES {
-
-/**
-Constructor.
-@param min : range min.
-@param max : range max.
-*/
-UserDefinedThresholdRange::UserDefinedThresholdRange(signal_t min, signal_t max)
-    : m_min(min), m_max(max) {
-  if (max < min) {
-    throw std::invalid_argument(
-        "Cannot have max < min in a UserDefinedThresholdRange.");
-  }
-}
-
-/**
-Indicates wheter execution has occured or not.
-return : true always.
-*/
-bool UserDefinedThresholdRange::hasCalculated() const { return true; }
-
-/**
-Destructor.
-*/
-UserDefinedThresholdRange::~UserDefinedThresholdRange() {}
-
-/**
-Do nothing calculate method.
-*/
-void UserDefinedThresholdRange::calculate() {}
-
-/**
-Minimum value getter.
-@return The minimum value.
-*/
-double UserDefinedThresholdRange::getMinimum() const { return m_min; }
-
-/**
-Maximum value getter.
-@return The maximum value.
-*/
-double UserDefinedThresholdRange::getMaximum() const { return m_max; }
-
-/**
-Virtual constructor clone method.
-@return clone of original.
-*/
-UserDefinedThresholdRange *UserDefinedThresholdRange::clone() const {
-  return new UserDefinedThresholdRange(this->m_min, this->m_max);
-}
-
-/**
-Determine whether the signal is withing range.
-@param signal value
-@return true if the signal is in the range defined by this object.
-*/
-bool UserDefinedThresholdRange::inRange(const signal_t &signal) {
-  return signal >= m_min && signal <= m_max;
-}
-}
-}
diff --git a/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp b/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp
index 1a88636a27aa7e4b1118aa23c7cc57f3f5945e88..f729a37f300106149a513cb86a9cfbd5383f4171 100644
--- a/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp
+++ b/Vates/VatesAPI/src/VatesKnowledgeSerializer.cpp
@@ -56,7 +56,7 @@ std::string VatesKnowledgeSerializer::createXMLString() const {
     throw std::runtime_error("No workspace name provided on workspace.");
   }
   // Check to see if a function has been provided.
-  if (m_spFunction != NULL) {
+  if (m_spFunction) {
     return std::string(
         MDGeometryXMLDefinitions::workspaceInstructionXMLTagStart() +
         m_wsNameXML + m_wsLocationXML + m_geomXML +
@@ -81,7 +81,7 @@ const std::string &VatesKnowledgeSerializer::getWorkspaceGeometry() const {
 }
 
 bool VatesKnowledgeSerializer::hasFunctionInfo() const {
-  return NULL != m_spFunction.get();
+  return static_cast<bool>(m_spFunction);
 }
 
 bool VatesKnowledgeSerializer::hasGeometryInfo() const {
diff --git a/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp b/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp
index 829079bec7953d933752f5273f5d47554e510352..415eda9a6e4a4e8ab46b868084d0b3ddc1783e7e 100644
--- a/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp
+++ b/Vates/VatesAPI/src/vtkDataSetToImplicitFunction.cpp
@@ -26,7 +26,7 @@ Constructor
 */
 vtkDataSetToImplicitFunction::vtkDataSetToImplicitFunction(vtkDataSet *dataSet)
     : m_dataset(dataSet) {
-  if (m_dataset == NULL) {
+  if (!m_dataset) {
     throw std::runtime_error(
         "Tried to construct vtkDataSetToImplicitFunction with NULL vtkDataSet");
   }
@@ -51,7 +51,7 @@ Mantid::Geometry::MDImplicitFunction *vtkDataSetToImplicitFunction::execute() {
     Poco::XML::Element *pRootElem = pDoc->documentElement();
     Poco::XML::Element *functionElem = pRootElem->getChildElement(
         MDGeometryXMLDefinitions::functionElementName());
-    if (NULL != functionElem) {
+    if (functionElem) {
       auto existingFunction =
           std::unique_ptr<Mantid::Geometry::MDImplicitFunction>(
               Mantid::API::ImplicitFunctionFactory::Instance().createUnwrapped(
diff --git a/Vates/VatesAPI/src/vtkDataSetToNonOrthogonalDataSet.cpp b/Vates/VatesAPI/src/vtkDataSetToNonOrthogonalDataSet.cpp
index 4c3dde0b03115e0da8b39779a42bee15b9408386..c75bdcc12546121250a9afbe8de4597937aeeae5 100644
--- a/Vates/VatesAPI/src/vtkDataSetToNonOrthogonalDataSet.cpp
+++ b/Vates/VatesAPI/src/vtkDataSetToNonOrthogonalDataSet.cpp
@@ -87,7 +87,7 @@ vtkDataSetToNonOrthogonalDataSet::vtkDataSetToNonOrthogonalDataSet(
       m_basisNorm(), m_basisX(1, 0, 0), m_basisY(0, 1, 0), m_basisZ(0, 0, 1),
       m_coordType(Kernel::HKL),
       m_workspaceProvider(std::move(workspaceProvider)) {
-  if (NULL == m_dataSet) {
+  if (!m_dataSet) {
     throw std::runtime_error("Cannot construct "
                              "vtkDataSetToNonOrthogonalDataSet with null VTK "
                              "dataset");
@@ -107,7 +107,7 @@ vtkDataSetToNonOrthogonalDataSet::~vtkDataSetToNonOrthogonalDataSet() {}
 void vtkDataSetToNonOrthogonalDataSet::execute(ProgressAction *progress) {
   // Downcast to a vtkPointSet
   vtkPointSet *data = vtkPointSet::SafeDownCast(m_dataSet);
-  if (NULL == data) {
+  if (!data) {
     throw std::runtime_error("VTK dataset does not inherit from vtkPointSet");
   }
 
@@ -214,8 +214,8 @@ void vtkDataSetToNonOrthogonalDataSet::execute(ProgressAction *progress) {
 
   // Get the original points
   vtkFloatArray *points =
-      vtkFloatArray::SafeDownCast(data->GetPoints()->GetData());
-  if (points == NULL) {
+      vtkFloatArray::FastDownCast(data->GetPoints()->GetData());
+  if (!points) {
     throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray.");
   } else if (points->GetNumberOfComponents() != 3) {
     throw std::runtime_error("points array must have 3 components.");
diff --git a/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp b/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp
index bb5ec8cfc4db24af64147f84f23456b083edc7c0..b6631234d7f6fc2ffa2c49ee08d0e1afc35d5a3c 100644
--- a/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp
+++ b/Vates/VatesAPI/src/vtkDataSetToScaledDataSet.cpp
@@ -71,12 +71,12 @@ vtkPointSet *vtkDataSetToScaledDataSet::execute(double xScale, double yScale,
                                                 vtkPointSet *inputData,
                                                 vtkPointSet *outputData) {
 
-  if (NULL == inputData) {
+  if (!inputData) {
     throw std::runtime_error("Cannot construct vtkDataSetToScaledDataSet with "
                              "NULL input vtkPointSet");
   }
 
-  if (outputData == NULL) {
+  if (!outputData) {
     outputData = inputData->NewInstance();
   }
 
@@ -85,11 +85,11 @@ vtkPointSet *vtkDataSetToScaledDataSet::execute(double xScale, double yScale,
   vtkNew<vtkPoints> newPoints;
 
   vtkFloatArray *oldPointsArray =
-      vtkFloatArray::SafeDownCast(points->GetData());
+      vtkFloatArray::FastDownCast(points->GetData());
   vtkFloatArray *newPointsArray =
-      vtkFloatArray::SafeDownCast(newPoints->GetData());
+      vtkFloatArray::FastDownCast(newPoints->GetData());
 
-  if (oldPointsArray == NULL || newPointsArray == NULL) {
+  if (!oldPointsArray || !newPointsArray) {
     throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray.");
   } else if (oldPointsArray->GetNumberOfComponents() != 3 ||
              newPointsArray->GetNumberOfComponents() != 3) {
diff --git a/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp b/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp
index 6a7d17d65c06372421b13fad48d0e8e754146c13..8d55fdd3157b76919e9eaff5d73eea1ce1859ede 100644
--- a/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp
+++ b/Vates/VatesAPI/src/vtkDataSetToWsLocation.cpp
@@ -26,7 +26,7 @@ Constructor
 */
 vtkDataSetToWsLocation::vtkDataSetToWsLocation(vtkDataSet *dataSet)
     : m_dataset(dataSet) {
-  if (m_dataset == NULL) {
+  if (!m_dataset) {
     throw std::runtime_error(
         "Tried to construct vtkDataSetToWsLocation with NULL vtkDataSet");
   }
@@ -47,7 +47,7 @@ std::string vtkDataSetToWsLocation::execute() {
   Poco::XML::Element *pRootElem = pDoc->documentElement();
   Poco::XML::Element *wsLocationElem = pRootElem->getChildElement(
       MDGeometryXMLDefinitions::workspaceLocationElementName());
-  if (wsLocationElem == NULL) {
+  if (!wsLocationElem) {
     throw std::runtime_error(
         "The element containing the workspace location must be present.");
   }
diff --git a/Vates/VatesAPI/src/vtkDataSetToWsName.cpp b/Vates/VatesAPI/src/vtkDataSetToWsName.cpp
index 2393a03db255807abb4251b17bff54568efdedd5..f4a88bc8efa387a9f01027a6f4516bec78bc2717 100644
--- a/Vates/VatesAPI/src/vtkDataSetToWsName.cpp
+++ b/Vates/VatesAPI/src/vtkDataSetToWsName.cpp
@@ -26,7 +26,7 @@ Constructor
 */
 vtkDataSetToWsName::vtkDataSetToWsName(vtkDataSet *dataSet)
     : m_dataset(dataSet) {
-  if (m_dataset == NULL) {
+  if (!m_dataset) {
     throw std::runtime_error(
         "Tried to construct vtkDataSetToWsName with NULL vtkDataSet");
   }
@@ -47,7 +47,7 @@ std::string vtkDataSetToWsName::execute() {
   Poco::XML::Element *pRootElem = pDoc->documentElement();
   Poco::XML::Element *wsNameElem = pRootElem->getChildElement(
       MDGeometryXMLDefinitions::workspaceNameElementName());
-  if (wsNameElem == NULL) {
+  if (!wsNameElem) {
     throw std::runtime_error(
         "The element containing the workspace name must be present.");
   }
diff --git a/Vates/VatesAPI/src/vtkMDHexFactory.cpp b/Vates/VatesAPI/src/vtkMDHexFactory.cpp
index 282e1c3d912c4c6427af3b2d15f80ab6befe105f..acbf4e96e72d5d0dfe367d8f8e9d2ee38751eb79 100644
--- a/Vates/VatesAPI/src/vtkMDHexFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDHexFactory.cpp
@@ -31,16 +31,13 @@ namespace Mantid {
 namespace VATES {
 
 /*Constructor
-  @param thresholdRange : Threshold range strategy
   @param normalizationOption : Info object setting how normalization should be
   done.
   @param maxDepth : Maximum depth to search to
   */
-vtkMDHexFactory::vtkMDHexFactory(ThresholdRange_scptr thresholdRange,
-                                 const VisualNormalization normalizationOption,
+vtkMDHexFactory::vtkMDHexFactory(const VisualNormalization normalizationOption,
                                  const size_t maxDepth)
-    : m_thresholdRange(thresholdRange),
-      m_normalizationOption(normalizationOption), m_maxDepth(maxDepth),
+    : m_normalizationOption(normalizationOption), m_maxDepth(maxDepth),
       slice(false), m_time(0) {}
 
 /// Destructor
@@ -81,7 +78,7 @@ void vtkMDHexFactory::doCreate(
 
   // Create 8 points per box.
   vtkNew<vtkPoints> points;
-  vtkFloatArray *pointsArray = vtkFloatArray::SafeDownCast(points->GetData());
+  vtkFloatArray *pointsArray = vtkFloatArray::FastDownCast(points->GetData());
   float *pointsPtr = pointsArray->WritePointer(0, numBoxes * 8 * 3);
 
   // One scalar per box
@@ -120,8 +117,7 @@ void vtkMDHexFactory::doCreate(
       API::IMDNode *box = boxes[i];
       Mantid::signal_t signal_normalized = (box->*normFunction)();
 
-      if (std::isfinite(signal_normalized) &&
-          m_thresholdRange->inRange(signal_normalized)) {
+      if (std::isfinite(signal_normalized)) {
         // Cache the signal and using of it
         signalCache[i] = static_cast<float>(signal_normalized);
         useBox[i] = true;
@@ -205,7 +201,7 @@ vtkSmartPointer<vtkDataSet>
 vtkMDHexFactory::create(ProgressAction &progressUpdating) const {
   this->dataSet = tryDelegatingCreation<IMDEventWorkspace, 3>(
       m_workspace, progressUpdating, false);
-  if (this->dataSet != NULL) {
+  if (this->dataSet) {
     return this->dataSet;
   } else {
     IMDEventWorkspace_sptr imdws =
@@ -302,10 +298,6 @@ IMDEventWorkspace, attempts to use any run-time successor set.
 void vtkMDHexFactory::initialize(Mantid::API::Workspace_sptr ws) {
   IMDEventWorkspace_sptr imdws = doInitialize<IMDEventWorkspace, 3>(ws, false);
   m_workspace = imdws;
-
-  // Setup range values according to whatever strategy object has been injected.
-  m_thresholdRange->setWorkspace(ws);
-  m_thresholdRange->calculate();
 }
 
 /// Validate the current object.
diff --git a/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp
index 5851197f8bad4117365f35c50e1508c377f93eb8..64254cae6b80e3965da345bf0acf832d21066eed 100644
--- a/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDHistoHex4DFactory.cpp
@@ -15,10 +15,8 @@ namespace VATES {
 
 template <typename TimeMapper>
 vtkMDHistoHex4DFactory<TimeMapper>::vtkMDHistoHex4DFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normalization, const double timestep)
-    : vtkMDHistoHexFactory(thresholdRange, normalization),
-      m_timestep(timestep) {}
+    : vtkMDHistoHexFactory(normalization), m_timestep(timestep) {}
 
 /**
 Assigment operator
@@ -30,7 +28,6 @@ vtkMDHistoHex4DFactory<TimeMapper> &vtkMDHistoHex4DFactory<TimeMapper>::
 operator=(const vtkMDHistoHex4DFactory<TimeMapper> &other) {
   if (this != &other) {
     this->m_normalizationOption = other.m_normalizationOption;
-    this->m_thresholdRange = other.m_thresholdRange;
     this->m_workspace = other.m_workspace;
     this->m_timestep = other.m_timestep;
     this->m_timeMapper = other.m_timeMapper;
@@ -52,17 +49,12 @@ template <typename TimeMapper>
 void vtkMDHistoHex4DFactory<TimeMapper>::initialize(
     Mantid::API::Workspace_sptr workspace) {
   m_workspace = doInitialize<MDHistoWorkspace, 4>(workspace);
-  if (m_workspace != NULL) {
+  if (m_workspace) {
     double tMax = m_workspace->getTDimension()->getMaximum();
     double tMin = m_workspace->getTDimension()->getMinimum();
     size_t nbins = m_workspace->getTDimension()->getNBins();
 
     m_timeMapper = TimeMapper::construct(tMin, tMax, nbins);
-
-    // Setup range values according to whatever strategy object has been
-    // injected.
-    m_thresholdRange->setWorkspace(workspace);
-    m_thresholdRange->calculate();
   }
 }
 
diff --git a/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp
index 88851df40e06173060f5b35afc00b389d1e758fd..6aa96e138ab77718063a72049419e5e1487f4729 100644
--- a/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDHistoHexFactory.cpp
@@ -1,8 +1,6 @@
 #include "MantidAPI/IMDWorkspace.h"
 #include "MantidKernel/CPUTimer.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
-#include "MantidDataObjects/MDHistoWorkspaceIterator.h"
-
 #include "MantidVatesAPI/vtkMDHWSignalArray.h"
 #include "MantidVatesAPI/Common.h"
 #include "MantidVatesAPI/Normalization.h"
@@ -29,10 +27,8 @@ namespace Mantid {
 namespace VATES {
 
 vtkMDHistoHexFactory::vtkMDHistoHexFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normalizationOption)
-    : m_normalizationOption(normalizationOption),
-      m_thresholdRange(thresholdRange) {}
+    : m_normalizationOption(normalizationOption) {}
 
 /**
 Assigment operator
@@ -43,7 +39,6 @@ vtkMDHistoHexFactory &vtkMDHistoHexFactory::
 operator=(const vtkMDHistoHexFactory &other) {
   if (this != &other) {
     this->m_normalizationOption = other.m_normalizationOption;
-    this->m_thresholdRange = other.m_thresholdRange;
     this->m_workspace = other.m_workspace;
   }
   return *this;
@@ -55,21 +50,15 @@ Copy Constructor
 */
 vtkMDHistoHexFactory::vtkMDHistoHexFactory(const vtkMDHistoHexFactory &other) {
   this->m_normalizationOption = other.m_normalizationOption;
-  this->m_thresholdRange = other.m_thresholdRange;
   this->m_workspace = other.m_workspace;
 }
 
 void vtkMDHistoHexFactory::initialize(Mantid::API::Workspace_sptr workspace) {
   m_workspace = doInitialize<MDHistoWorkspace, 3>(workspace);
-
-  // Setup range values according to whatever strategy object has been injected.
-  m_thresholdRange->setWorkspace(workspace);
-  m_thresholdRange->calculate();
 }
 
 void vtkMDHistoHexFactory::validateWsNotNull() const {
-
-  if (NULL == m_workspace.get()) {
+  if (!m_workspace) {
     throw std::runtime_error("IMDWorkspace is null");
   }
 }
@@ -121,14 +110,10 @@ vtkMDHistoHexFactory::create3Dor4D(size_t timestep,
     offset = timestep * indexMultiplier[2];
   }
 
-  std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-      dynamic_cast<MDHistoWorkspaceIterator *>(createIteratorWithNormalization(
-          m_normalizationOption, m_workspace.get())));
-
   vtkNew<vtkMDHWSignalArray<double>> signal;
 
   signal->SetName(vtkDataSetFactory::ScalarName.c_str());
-  signal->InitializeArray(std::move(iterator), offset, imageSize);
+  signal->InitializeArray(m_workspace.get(), m_normalizationOption, offset);
   visualDataSet->GetCellData()->SetScalars(signal.GetPointer());
 
   // update progress after a 1% change
@@ -137,9 +122,7 @@ vtkMDHistoHexFactory::create3Dor4D(size_t timestep,
     if (index % progressIncrement == 0)
       progressUpdate.eventRaised(static_cast<double>(index) * progressFactor);
     double signalScalar = signal->GetValue(index);
-    bool maskValue = (!std::isfinite(signalScalar) ||
-                      !m_thresholdRange->inRange(signalScalar));
-    if (maskValue) {
+    if (!std::isfinite(signalScalar)) {
       visualDataSet->BlankCell(index);
     }
   }
@@ -163,8 +146,8 @@ vtkMDHistoHexFactory::create3Dor4D(size_t timestep,
   const vtkIdType nPointsY = nBinsY + 1;
   const vtkIdType nPointsZ = nBinsZ + 1;
 
-  vtkFloatArray *pointsarray = vtkFloatArray::SafeDownCast(points->GetData());
-  if (pointsarray == NULL) {
+  vtkFloatArray *pointsarray = vtkFloatArray::FastDownCast(points->GetData());
+  if (!pointsarray) {
     throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray.");
   } else if (pointsarray->GetNumberOfComponents() != 3) {
     throw std::runtime_error("points array must have 3 components.");
@@ -192,7 +175,7 @@ vtkMDHistoHexFactory::create3Dor4D(size_t timestep,
   }
 
   visualDataSet->SetPoints(points.GetPointer());
-  visualDataSet->Register(NULL);
+  visualDataSet->Register(nullptr);
   visualDataSet->Squeeze();
 
   // Hedge against empty data sets
@@ -215,7 +198,7 @@ vtkSmartPointer<vtkDataSet>
 vtkMDHistoHexFactory::create(ProgressAction &progressUpdating) const {
   auto product =
       tryDelegatingCreation<MDHistoWorkspace, 3>(m_workspace, progressUpdating);
-  if (product != NULL) {
+  if (product) {
     return product;
   } else {
     // Create in 3D mode
diff --git a/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp
index c8bf0e8aa14dd693613fb0b545de3156bb5d8b07..1673b55e92d6a18e382c786bb067bed066d226fc 100644
--- a/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDHistoLineFactory.cpp
@@ -26,10 +26,8 @@ namespace Mantid {
 namespace VATES {
 
 vtkMDHistoLineFactory::vtkMDHistoLineFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normaliztionOption)
-    : m_normalizationOption(normaliztionOption),
-      m_thresholdRange(thresholdRange) {}
+    : m_normalizationOption(normaliztionOption) {}
 
 /**
 Assigment operator
@@ -40,7 +38,6 @@ vtkMDHistoLineFactory &vtkMDHistoLineFactory::
 operator=(const vtkMDHistoLineFactory &other) {
   if (this != &other) {
     this->m_normalizationOption = other.m_normalizationOption;
-    this->m_thresholdRange = other.m_thresholdRange;
     this->m_workspace = other.m_workspace;
   }
   return *this;
@@ -53,7 +50,6 @@ Copy Constructor
 vtkMDHistoLineFactory::vtkMDHistoLineFactory(
     const vtkMDHistoLineFactory &other) {
   this->m_normalizationOption = other.m_normalizationOption;
-  this->m_thresholdRange = other.m_thresholdRange;
   this->m_workspace = other.m_workspace;
 }
 
@@ -114,8 +110,7 @@ vtkMDHistoLineFactory::create(ProgressAction &progressUpdating) const {
       float signalScalar =
           static_cast<float>(m_workspace->getSignalNormalizedAt(i));
 
-      if (!std::isfinite(signalScalar) ||
-          !m_thresholdRange->inRange(signalScalar)) {
+      if (!std::isfinite(signalScalar)) {
         // Flagged so that topological and scalar data is not applied.
         unstructPoint.isSparse = true;
       } else {
@@ -167,14 +162,10 @@ vtkMDHistoLineFactory::create(ProgressAction &progressUpdating) const {
 void vtkMDHistoLineFactory::initialize(
     Mantid::API::Workspace_sptr wspace_sptr) {
   m_workspace = this->doInitialize<MDHistoWorkspace, 1>(wspace_sptr);
-
-  // Setup range values according to whatever strategy object has been injected.
-  m_thresholdRange->setWorkspace(wspace_sptr);
-  m_thresholdRange->calculate();
 }
 
 void vtkMDHistoLineFactory::validate() const {
-  if (NULL == m_workspace.get()) {
+  if (!m_workspace) {
     throw std::runtime_error("IMDWorkspace is null");
   }
 }
diff --git a/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp b/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp
index b460e1183a3bbaa7c5699ad84bbbe65ec660e750..868e67d77e3dc0e4e5b1de3dd278eaf3eb88e1af 100644
--- a/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDHistoQuadFactory.cpp
@@ -30,10 +30,8 @@ namespace Mantid {
 
 namespace VATES {
 vtkMDHistoQuadFactory::vtkMDHistoQuadFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normalizationOption)
-    : m_normalizationOption(normalizationOption),
-      m_thresholdRange(thresholdRange) {}
+    : m_normalizationOption(normalizationOption) {}
 
 /**
 Assigment operator
@@ -44,7 +42,6 @@ vtkMDHistoQuadFactory &vtkMDHistoQuadFactory::
 operator=(const vtkMDHistoQuadFactory &other) {
   if (this != &other) {
     this->m_normalizationOption = other.m_normalizationOption;
-    this->m_thresholdRange = other.m_thresholdRange;
     this->m_workspace = other.m_workspace;
   }
   return *this;
@@ -57,7 +54,6 @@ Copy Constructor
 vtkMDHistoQuadFactory::vtkMDHistoQuadFactory(
     const vtkMDHistoQuadFactory &other) {
   this->m_normalizationOption = other.m_normalizationOption;
-  this->m_thresholdRange = other.m_thresholdRange;
   this->m_workspace = other.m_workspace;
 }
 
@@ -141,8 +137,7 @@ vtkMDHistoQuadFactory::create(ProgressAction &progressUpdating) const {
             iterator->getNormalizedSignal()); // Get signal normalized as per
                                               // m_normalizationOption
 
-        if (!std::isfinite(signalScalar) ||
-            !m_thresholdRange->inRange(signalScalar)) {
+        if (!std::isfinite(signalScalar)) {
           // out of range
           voxelShown[index] = false;
         } else {
@@ -166,7 +161,7 @@ vtkMDHistoQuadFactory::create(ProgressAction &progressUpdating) const {
 
     // Get the transformation that takes the points in the TRANSFORMED space
     // back into the ORIGINAL (not-rotated) space.
-    Mantid::API::CoordTransform const *transform = NULL;
+    Mantid::API::CoordTransform const *transform = nullptr;
     if (m_useTransform)
       transform = m_workspace->getTransformToOriginal();
 
@@ -241,14 +236,10 @@ vtkMDHistoQuadFactory::create(ProgressAction &progressUpdating) const {
 void vtkMDHistoQuadFactory::initialize(
     Mantid::API::Workspace_sptr wspace_sptr) {
   m_workspace = doInitialize<MDHistoWorkspace, 2>(wspace_sptr);
-
-  // Setup range values according to whatever strategy object has been injected.
-  m_thresholdRange->setWorkspace(wspace_sptr);
-  m_thresholdRange->calculate();
 }
 
 void vtkMDHistoQuadFactory::validate() const {
-  if (NULL == m_workspace.get()) {
+  if (!m_workspace) {
     throw std::runtime_error("IMDWorkspace is null");
   }
 }
diff --git a/Vates/VatesAPI/src/vtkMDLineFactory.cpp b/Vates/VatesAPI/src/vtkMDLineFactory.cpp
index 33a028441dcf775e5e952e0808e9bbfd0ebd2ce5..bff1b97490f7b670253ecec16a335e133e4210d4 100644
--- a/Vates/VatesAPI/src/vtkMDLineFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDLineFactory.cpp
@@ -29,14 +29,11 @@ namespace Mantid {
 namespace VATES {
 /**
 Constructor
-@param thresholdRange : Thresholding range functor
 @param normalizationOption : Normalization option to use
 */
 vtkMDLineFactory::vtkMDLineFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normalizationOption)
-    : m_thresholdRange(thresholdRange),
-      m_normalizationOption(normalizationOption) {}
+    : m_normalizationOption(normalizationOption) {}
 
 /// Destructor
 vtkMDLineFactory::~vtkMDLineFactory() {}
@@ -99,7 +96,7 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const {
     vtkNew<vtkIdList> linePointList;
     linePointList->SetNumberOfIds(2);
 
-    Mantid::API::CoordTransform const *transform = NULL;
+    Mantid::API::CoordTransform const *transform = nullptr;
     if (m_useTransform) {
       transform = imdws->getTransformToOriginal();
     }
@@ -115,8 +112,7 @@ vtkMDLineFactory::create(ProgressAction &progressUpdating) const {
       progressUpdating.eventRaised(double(iBox) * progressFactor);
 
       Mantid::signal_t signal_normalized = it->getNormalizedSignal();
-      if (std::isfinite(signal_normalized) &&
-          m_thresholdRange->inRange(signal_normalized)) {
+      if (std::isfinite(signal_normalized)) {
         useBox[iBox] = true;
         signals->InsertNextValue(static_cast<float>(signal_normalized));
 
@@ -184,7 +180,7 @@ std::string vtkMDLineFactory::getFactoryTypeName() const {
 
 /// Template Method pattern to validate the factory before use.
 void vtkMDLineFactory::validate() const {
-  if (NULL == m_workspace.get()) {
+  if (!m_workspace) {
     throw std::runtime_error(
         "vtkMDLineFactory has no workspace to run against");
   }
diff --git a/Vates/VatesAPI/src/vtkMDQuadFactory.cpp b/Vates/VatesAPI/src/vtkMDQuadFactory.cpp
index f8ed9f183d44e17bedd326a40526ffe5c3bf6c92..544ffcbf235d70a9333f6c13e7fc5653aa0a609e 100644
--- a/Vates/VatesAPI/src/vtkMDQuadFactory.cpp
+++ b/Vates/VatesAPI/src/vtkMDQuadFactory.cpp
@@ -27,10 +27,8 @@ namespace Mantid {
 namespace VATES {
 /// Constructor
 vtkMDQuadFactory::vtkMDQuadFactory(
-    ThresholdRange_scptr thresholdRange,
     const VisualNormalization normalizationOption)
-    : m_thresholdRange(thresholdRange),
-      m_normalizationOption(normalizationOption) {}
+    : m_normalizationOption(normalizationOption) {}
 
 /// Destructor
 vtkMDQuadFactory::~vtkMDQuadFactory() {}
@@ -94,7 +92,7 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const {
     vtkNew<vtkIdList> quadPointList;
     quadPointList->SetNumberOfIds(4);
 
-    Mantid::API::CoordTransform const *transform = NULL;
+    Mantid::API::CoordTransform const *transform = nullptr;
     if (m_useTransform) {
       transform = imdws->getTransformToOriginal();
     }
@@ -110,7 +108,7 @@ vtkMDQuadFactory::create(ProgressAction &progressUpdating) const {
       progressUpdating.eventRaised(progressFactor * double(iBox));
 
       Mantid::signal_t signal = it->getNormalizedSignal();
-      if (std::isfinite(signal) && m_thresholdRange->inRange(signal)) {
+      if (std::isfinite(signal)) {
         useBox[iBox] = true;
         signals->InsertNextValue(static_cast<float>(signal));
 
@@ -180,7 +178,7 @@ std::string vtkMDQuadFactory::getFactoryTypeName() const {
 
 /// Template Method pattern to validate the factory before use.
 void vtkMDQuadFactory::validate() const {
-  if (NULL == m_workspace.get()) {
+  if (!m_workspace) {
     throw std::runtime_error(
         "vtkMDQuadFactory has no workspace to run against");
   }
diff --git a/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
index 8a92822e55fdbafc5cf17b28dc38aa5c2902a19d..b3434c11d029e9d9fdb2df7f8bce00eeae8579b3 100644
--- a/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
+++ b/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
@@ -43,17 +43,15 @@ namespace Mantid {
 namespace VATES {
 /**
  * Constructor
- * @param thresholdRange : Threshold range strategy
  * @param scalarName : Name for scalar signal array.
  * @param numPoints : Total number of points to create.
  * @param percentToUse : Cutoff for the densest boxes.
  */
-vtkSplatterPlotFactory::vtkSplatterPlotFactory(
-    ThresholdRange_scptr thresholdRange, const std::string &scalarName,
-    const size_t numPoints, const double percentToUse)
-    : m_thresholdRange(thresholdRange), m_scalarName(scalarName),
-      m_numPoints(numPoints), m_buildSortedList(true), m_wsName(""),
-      slice(false), m_time(0.0), m_minValue(0.1), m_maxValue(0.1),
+vtkSplatterPlotFactory::vtkSplatterPlotFactory(const std::string &scalarName,
+                                               const size_t numPoints,
+                                               const double percentToUse)
+    : m_scalarName(scalarName), m_numPoints(numPoints), m_buildSortedList(true),
+      m_wsName(""), slice(false), m_time(0.0), m_minValue(0.1), m_maxValue(0.1),
       m_metaDataExtractor(new MetaDataExtractorUtils()),
       m_metadataJsonManager(new MetadataJsonManager()),
       m_vatesConfigurations(new VatesConfigurations()) {
@@ -158,7 +156,7 @@ void vtkSplatterPlotFactory::doCreate(
 
   // Create the point list, one position for each point actually used
   vtkNew<vtkPoints> points;
-  vtkFloatArray *pointsArray = vtkFloatArray::SafeDownCast(points->GetData());
+  vtkFloatArray *pointsArray = vtkFloatArray::FastDownCast(points->GetData());
   if (!pointsArray) {
     throw std::runtime_error("Failed to cast vtkDataArray to vtkFloatArray.");
   }
@@ -291,7 +289,7 @@ void vtkSplatterPlotFactory::doCreateMDHisto(
 
   // Get the transformation that takes the points in the TRANSFORMED space back
   // into the ORIGINAL (not-rotated) space.
-  Mantid::API::CoordTransform const *transform = NULL;
+  Mantid::API::CoordTransform const *transform = nullptr;
   if (m_useTransform) {
     transform = workspace->getTransformToOriginal();
   }
@@ -314,7 +312,6 @@ void vtkSplatterPlotFactory::doCreateMDHisto(
         // Make sure that the signal is not bad and is in the range and larger
         // than 0
         if (std::isfinite(signalScalar) &&
-            m_thresholdRange->inRange(signalScalar) &&
             (signalScalar > static_cast<signal_t>(0.0))) {
           in[0] = (minX + (static_cast<coord_t>(x) + 0.5f) * incrementX);
           // Create the transformed value if required
diff --git a/Vates/VatesAPI/test/IgnoreZerosThresholdRangeTest.h b/Vates/VatesAPI/test/IgnoreZerosThresholdRangeTest.h
deleted file mode 100644
index 117b637b7d93311ce98722409c4fb8510e1d3795..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/test/IgnoreZerosThresholdRangeTest.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef IGNORE_ZEROS_THRESHOLD_RANGE_TEST_H_
-#define IGNORE_ZEROS_THRESHOLD_RANGE_TEST_H_
-
-#include <cxxtest/TestSuite.h>
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
-
-using namespace Mantid;
-using namespace Mantid::VATES;
-
-//=====================================================================================
-// Functional tests
-//=====================================================================================
-class IgnoreZerosThresholdRangeTest : public CxxTest::TestSuite {
-
-public:
-  void testIgnoreEmptyCells() {
-    IgnoreZerosThresholdRange range;
-
-    TS_ASSERT_EQUALS(true, range.inRange(0.001));
-    TS_ASSERT_EQUALS(true, range.inRange(-0.001));
-    TS_ASSERT_EQUALS(false, range.inRange(0));
-  }
-
-  void testGetMinMax() {
-    IgnoreZerosThresholdRange range;
-
-    range.inRange(1);
-    range.inRange(3);
-    range.inRange(-2);
-    range.inRange(5);
-    TSM_ASSERT_EQUALS("Wrong max found", 5, range.getMaximum());
-    TSM_ASSERT_EQUALS("Wrong min found", -2, range.getMinimum());
-  }
-
-  void testMinIsNeverZero() {
-    IgnoreZerosThresholdRange range;
-
-    range.inRange(0);
-    range.inRange(0.5);
-    range.inRange(2);
-    TSM_ASSERT_EQUALS("Wrong min found", 0.5, range.getMinimum());
-  }
-};
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/test/LoadVTKTest.h b/Vates/VatesAPI/test/LoadVTKTest.h
index 68bd8de7275911aa4abcbccb7b78ab374662edfd..7d8897cbf98aaa01d12371b97534351c6f047eae 100644
--- a/Vates/VatesAPI/test/LoadVTKTest.h
+++ b/Vates/VatesAPI/test/LoadVTKTest.h
@@ -3,6 +3,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidVatesAPI/LoadVTK.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidGeometry/MDGeometry/UnknownFrame.h"
diff --git a/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h b/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h
index ebfa2c4438a86458288dd618ae4586b0b25a6c0e..50cae98a708d14b36cfc8d2e210f9533b2c1acac 100644
--- a/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h
+++ b/Vates/VatesAPI/test/MDHWNexusLoadingPresenterTest.h
@@ -14,7 +14,6 @@
 #include "MantidVatesAPI/vtkMDHistoHexFactory.h"
 #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h"
 #include "MantidVatesAPI/TimeToTimeStep.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -155,22 +154,19 @@ public:
         .WillRepeatedly(testing::Return(true));
     EXPECT_CALL(*view, updateAlgorithmProgress(_, _)).Times(AnyNumber());
 
-    ThresholdRange_scptr thresholdRange =
-        boost::make_shared<IgnoreZerosThresholdRange>();
-
     // Create the presenter as in the vtkMDHWSource
     auto normalizationOption = Mantid::VATES::VisualNormalization::AutoSelect;
     MDHWNexusLoadingPresenter presenter(std::move(view), filename);
     const double time = 0.0;
     auto factory = boost::make_shared<vtkMDHistoHex4DFactory<TimeToTimeStep>>(
-        thresholdRange, normalizationOption, time);
+        normalizationOption, time);
 
     factory->setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoHexFactory>(
-                              thresholdRange, normalizationOption))
+                              normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoQuadFactory>(
-            thresholdRange, normalizationOption))
+            normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMDHistoLineFactory>(
-            thresholdRange, normalizationOption))
+            normalizationOption))
         .setSuccessor(Mantid::Kernel::make_unique<vtkMD0DFactory>());
 
     presenter.executeLoadMetadata();
diff --git a/Vates/VatesAPI/test/MDLoadingPresenterTest.h b/Vates/VatesAPI/test/MDLoadingPresenterTest.h
index 76cbef910491790f390453b01c1fa64132084d41..c0a11b8b2fbe75a4c523f03da465f547222527b6 100644
--- a/Vates/VatesAPI/test/MDLoadingPresenterTest.h
+++ b/Vates/VatesAPI/test/MDLoadingPresenterTest.h
@@ -3,7 +3,6 @@
 
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidVatesAPI/MDLoadingPresenter.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/ProgressAction.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 #include "MantidVatesAPI/vtkMDHexFactory.h"
@@ -55,8 +54,7 @@ private:
     FakeProgressAction progressUpdate;
     MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(8, -10.0, 10.0, 1);
-    Mantid::VATES::vtkMDHexFactory factory(
-        ThresholdRange_scptr(new NoThresholdRange), VolumeNormalization);
+    Mantid::VATES::vtkMDHexFactory factory(VolumeNormalization);
     factory.initialize(ws);
     auto dataset = factory.create(progressUpdate);
     auto grid = vtkUnstructuredGrid::SafeDownCast(dataset.Get());
diff --git a/Vates/VatesAPI/test/MedianAndBelowThresholdRangeTest.h b/Vates/VatesAPI/test/MedianAndBelowThresholdRangeTest.h
deleted file mode 100644
index c7e651c04cf77352d86c3a2a0210b64f354b2ff4..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/test/MedianAndBelowThresholdRangeTest.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#ifndef MEDIAN_AND_BELOW_THRESHOLD_RANGE_TEST_H_
-#define MEDIAN_AND_BELOW_THRESHOLD_RANGE_TEST_H_
-
-#include <cxxtest/TestSuite.h>
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include "MantidVatesAPI/MedianAndBelowThresholdRange.h"
-#include "MantidAPI/IMDIterator.h"
-#include "MantidTestHelpers/MDEventsTestHelper.h"
-#include "MantidDataObjects/MDHistoWorkspace.h"
-
-using namespace Mantid;
-using namespace Mantid::DataObjects;
-using namespace testing;
-
-//=====================================================================================
-// Functional tests
-//=====================================================================================
-
-class MedianAndBelowThresholdRangeTest : public CxxTest::TestSuite {
-private:
-  // Fake workspace
-  MDHistoWorkspace_sptr sptrWs;
-
-public:
-  void setUp() override {
-    // Fake workspace with 8 cells
-    sptrWs = MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1, 8, 8.0);
-    // Set up a standard set of values for subsequent tests. Note that the
-    // following set gives a standard deviation of +/-2
-    sptrWs->setSignalAt(0, -1.0);
-    sptrWs->setSignalAt(1, 2);
-    sptrWs->setSignalAt(2, 2);
-    sptrWs->setSignalAt(3, 3);
-    sptrWs->setSignalAt(4, 4);
-    sptrWs->setSignalAt(5, 5);
-    sptrWs->setSignalAt(6, 6);
-    sptrWs->setSignalAt(7, 7);
-  }
-
-  void testMedianCalculation() {
-    Mantid::VATES::MedianAndBelowThresholdRange medianCalculator;
-    medianCalculator.setWorkspace(sptrWs);
-    medianCalculator.calculate();
-    //-1 + 2 + 2 + 3 + 4 + 5 + 6 + 7 / 8 = 3.5
-
-    TSM_ASSERT_EQUALS("Wrong maximum value.", 3.5,
-                      medianCalculator.getMaximum());
-    TSM_ASSERT_EQUALS("Wrong minimum value.", -1,
-                      medianCalculator.getMinimum());
-  }
-
-  void testInRange() {
-    Mantid::VATES::MedianAndBelowThresholdRange medianCalculator;
-    medianCalculator.setWorkspace(sptrWs);
-    medianCalculator.calculate();
-    //-1 + 2 + 2 + 3 + 4 + 5 + 6 + 7 / 8 = 3.5
-
-    TS_ASSERT_EQUALS(true, medianCalculator.inRange(3.499));
-    TS_ASSERT_EQUALS(false, medianCalculator.inRange(3.501));
-  }
-};
-
-#endif
diff --git a/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h b/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h
index 75873feba4d1cb9ad138e374097894db68866eb1..d2a620d23b6e4620c18cfe20d3116fbcf5f0a349 100644
--- a/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h
+++ b/Vates/VatesAPI/test/MetaDataExtractorUtilsTest.h
@@ -16,6 +16,7 @@
 
 #include <qwt_double_interval.h>
 #include "MantidTestHelpers/MDEventsTestHelper.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FileFinder.h"
 #include "MantidAPI/ITableWorkspace.h"
 #include "MantidAPI/WorkspaceFactory.h"
diff --git a/Vates/VatesAPI/test/NoThresholdRangeTest.h b/Vates/VatesAPI/test/NoThresholdRangeTest.h
deleted file mode 100644
index 57b2a404b6b0303afd5d16879ab9bc88d35a2fbe..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/test/NoThresholdRangeTest.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef NO_THRESHOLD_RANGE_TEST_H_
-#define NO_THRESHOLD_RANGE_TEST_H_
-
-#include <cxxtest/TestSuite.h>
-
-#include "MantidVatesAPI/NoThresholdRange.h"
-
-using namespace Mantid;
-using namespace Mantid::VATES;
-
-//=====================================================================================
-// Functional tests
-//=====================================================================================
-class NoThresholdRangeTest : public CxxTest::TestSuite {
-public:
-  void testEverythingWithinRange() {
-    NoThresholdRange range;
-
-    TS_ASSERT_EQUALS(true, range.inRange(-1e9));
-    TS_ASSERT_EQUALS(true, range.inRange(0));
-    TS_ASSERT_EQUALS(true, range.inRange(1e9));
-  }
-
-  void testGetMinMax() {
-    NoThresholdRange range;
-
-    range.inRange(1);
-    range.inRange(3);
-    range.inRange(-2);
-    range.inRange(5);
-    TSM_ASSERT_EQUALS("Wrong max found", 5, range.getMaximum());
-    TSM_ASSERT_EQUALS("Wrong min found", -2, range.getMinimum());
-  }
-};
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/test/SaveMDWorkspaceToVTKImplTest.h b/Vates/VatesAPI/test/SaveMDWorkspaceToVTKImplTest.h
index 3a06c37bdcac214ca4d278462587f52c2c419c55..66ced7db7af6082f2cf888e93a6393c688e90723 100644
--- a/Vates/VatesAPI/test/SaveMDWorkspaceToVTKImplTest.h
+++ b/Vates/VatesAPI/test/SaveMDWorkspaceToVTKImplTest.h
@@ -4,7 +4,6 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidVatesAPI/SaveMDWorkspaceToVTKImpl.h"
 #include "MantidVatesAPI/Normalization.h"
-#include "MantidVatesAPI/IgnoreZerosThresholdRange.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidKernel/ConfigService.h"
 
@@ -63,43 +62,6 @@ public:
                       volumeNormalization, Mantid::VATES::VolumeNormalization);
   }
 
-  void test_that_vector_of_threshold_strings_has_all_values() {
-    // Arrange
-    Mantid::VATES::SaveMDWorkspaceToVTKImpl saveMDToVTK;
-
-    // Act
-    const auto thresholds =
-        saveMDToVTK.getAllowedThresholdsInStringRepresentation();
-
-    // Assert
-    TSM_ASSERT_EQUALS("There should be 2 normalization options",
-                      thresholds.size(), 2);
-    TSM_ASSERT_EQUALS(
-        "First normalization should be IgnoreZerosThresholdRange.",
-        thresholds[0], "IgnoreZerosThresholdRange");
-    TSM_ASSERT_EQUALS("Second normalization should be NoThresholdRange.",
-                      thresholds[1], "NoThresholdRange");
-  }
-
-  void test_string_representation_converts_to_TresholdRange() {
-    // Arrange
-    Mantid::VATES::SaveMDWorkspaceToVTKImpl saveMDToVTK;
-    auto thresholds = saveMDToVTK.getAllowedThresholdsInStringRepresentation();
-    // Act
-    auto ignoreZerosThresholdRange =
-        saveMDToVTK.translateStringToThresholdRange(thresholds[0]);
-    auto noThresholdRange =
-        saveMDToVTK.translateStringToThresholdRange(thresholds[1]);
-    // Assert
-    TSM_ASSERT(
-        "Should be a IgnoreZerosTresholdRange",
-        boost::dynamic_pointer_cast<Mantid::VATES::IgnoreZerosThresholdRange>(
-            ignoreZerosThresholdRange));
-    TSM_ASSERT("Should be a NoTresholdRange",
-               boost::dynamic_pointer_cast<Mantid::VATES::ThresholdRange>(
-                   noThresholdRange));
-  }
-
   void test_detects_when_not_3D_workspace() {
     // Arrange
     Mantid::VATES::SaveMDWorkspaceToVTKImpl saveMDToVTK;
@@ -208,13 +170,7 @@ private:
         saveMDToVTK.getAllowedNormalizationsInStringRepresentation();
     const auto normalization =
         saveMDToVTK.translateStringToVisualNormalization(normalizations[0]);
-
-    const auto thresholds =
-        saveMDToVTK.getAllowedThresholdsInStringRepresentation();
-    const auto threshold =
-        saveMDToVTK.translateStringToThresholdRange(thresholds[0]);
-
-    saveMDToVTK.saveMDWorkspace(workspace, filename, normalization, threshold,
+    saveMDToVTK.saveMDWorkspace(workspace, filename, normalization,
                                 recursionDepth, "NONE");
   }
 
diff --git a/Vates/VatesAPI/test/SaveMDWorkspaceToVTKTest.h b/Vates/VatesAPI/test/SaveMDWorkspaceToVTKTest.h
index 46027ce611af122974485747c97a51fd71abd045..c5264d10281945caca1740df1683a823d2818761 100644
--- a/Vates/VatesAPI/test/SaveMDWorkspaceToVTKTest.h
+++ b/Vates/VatesAPI/test/SaveMDWorkspaceToVTKTest.h
@@ -11,7 +11,7 @@ class SaveMDWorkspaceToVTKTest : public CxxTest::TestSuite {
 public:
   void test_that_wrong_workspace_type_throws() {
     // Arrange
-    auto workspace = WorkspaceCreationHelper::Create2DWorkspace(1, 10);
+    auto workspace = WorkspaceCreationHelper::create2DWorkspace(1, 10);
 
     Mantid::VATES::SaveMDWorkspaceToVTK alg;
     alg.setChild(true);
@@ -20,7 +20,6 @@ public:
     alg.setProperty("InputWorkspace", workspace);
     alg.setProperty("Filename", "test_file_name");
     alg.setProperty("Normalization", "AutoSelect");
-    alg.setProperty("ThresholdRange", "IgnoreZerosThresholdRange");
     alg.setProperty("RecursionDepth", 5);
     alg.setProperty("CompressorType", "NONE");
 
@@ -45,7 +44,6 @@ public:
     alg.setProperty("InputWorkspace", workspace);
     alg.setProperty("Filename", "test_file_name");
     alg.setProperty("Normalization", "AutoSelect");
-    alg.setProperty("ThresholdRange", "IgnoreZerosThresholdRange");
     alg.setProperty("RecursionDepth", 5);
     alg.setProperty("CompressorType", "NONE");
 
@@ -75,7 +73,6 @@ public:
     alg.setProperty("InputWorkspace", workspace);
     alg.setProperty("Filename", fullFilename);
     alg.setProperty("Normalization", "AutoSelect");
-    alg.setProperty("ThresholdRange", "IgnoreZerosThresholdRange");
     alg.setProperty("RecursionDepth", 5);
     alg.setProperty("CompressorType", "NONE");
 
diff --git a/Vates/VatesAPI/test/UserDefinedThresholdRangeTest.h b/Vates/VatesAPI/test/UserDefinedThresholdRangeTest.h
deleted file mode 100644
index b34062277c106157607c26668d74b6081e5d6c0b..0000000000000000000000000000000000000000
--- a/Vates/VatesAPI/test/UserDefinedThresholdRangeTest.h
+++ /dev/null
@@ -1,66 +0,0 @@
-#ifndef USER_DEFINED_THRESHOLD_RANGE_TEST_H_
-#define USER_DEFINED_THRESHOLD_RANGE_TEST_H_
-
-#include <cxxtest/TestSuite.h>
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
-
-using namespace Mantid::VATES;
-using namespace Mantid;
-
-class UserDefinedThresholdRangeTest : public CxxTest::TestSuite {
-public:
-  void testConstructMaxLessThanMinThrows() {
-    TSM_ASSERT_THROWS("Should not be able to construct with max less than min.",
-                      UserDefinedThresholdRange(2, 1), std::invalid_argument);
-  }
-
-  void testGetMaximum() {
-    Mantid::VATES::UserDefinedThresholdRange userRangeCalculator(1, 2);
-    TSM_ASSERT_EQUALS("::getMaximum not wired-up correctly.", 2,
-                      userRangeCalculator.getMaximum());
-  }
-
-  void testGetMinimum() {
-    Mantid::VATES::UserDefinedThresholdRange userRangeCalculator(1, 2);
-    TSM_ASSERT_EQUALS("::getMinimum not wired-up correctly.", 1,
-                      userRangeCalculator.getMinimum());
-  }
-
-  void testHasCalculated() {
-    Mantid::VATES::UserDefinedThresholdRange userRangeCalculator(1, 2);
-    TS_ASSERT(userRangeCalculator
-                  .hasCalculated()); // Should return true no matter what!
-  }
-
-  void testClone() {
-    Mantid::VATES::UserDefinedThresholdRange original(1, 2);
-    auto cloned = std::unique_ptr<Mantid::VATES::UserDefinedThresholdRange>(
-        original.clone());
-
-    TS_ASSERT_EQUALS(original.getMaximum(), cloned->getMaximum());
-    TS_ASSERT_EQUALS(original.getMinimum(), cloned->getMinimum());
-  }
-
-  void testInRange() {
-    Mantid::VATES::UserDefinedThresholdRange userRangeCalculator(1, 2);
-    // Boundary Value Analysis
-    signal_t just_above_upper_boundary = 2.001;
-    signal_t just_below_lower_boundary = 0.999;
-    signal_t on_lower_boundary = 1;
-    signal_t on_upper_boundary = 2;
-    signal_t just_below_upper_boundary = 1.999;
-    signal_t just_above_lower_boundary = 1.001;
-    TS_ASSERT_EQUALS(false,
-                     userRangeCalculator.inRange(just_above_upper_boundary));
-    TS_ASSERT_EQUALS(false,
-                     userRangeCalculator.inRange(just_below_lower_boundary));
-    TS_ASSERT_EQUALS(true, userRangeCalculator.inRange(on_lower_boundary));
-    TS_ASSERT_EQUALS(true, userRangeCalculator.inRange(on_upper_boundary));
-    TS_ASSERT_EQUALS(true,
-                     userRangeCalculator.inRange(just_below_upper_boundary));
-    TS_ASSERT_EQUALS(true,
-                     userRangeCalculator.inRange(just_above_lower_boundary));
-  }
-};
-
-#endif
\ No newline at end of file
diff --git a/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h b/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h
index c159e19f181fa1452c9475d7cf0e440b7aae5bed..142e573da02ae58cbd6c22345a830f5bf42d787c 100644
--- a/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h
+++ b/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h
@@ -13,8 +13,6 @@
 #include "MantidVatesAPI/FieldDataToMetadata.h"
 #include "MantidVatesAPI/MetadataJsonManager.h"
 #include "MantidVatesAPI/MetadataToFieldData.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
 #include "MantidVatesAPI/VatesConfigurations.h"
 #include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h"
 #include "MantidVatesAPI/vtkSplatterPlotFactory.h"
@@ -65,8 +63,7 @@ private:
     FakeProgressAction progressUpdate;
     MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(10, -10.0, 10.0, 1);
-    vtkSplatterPlotFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 1), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
     TS_ASSERT_THROWS_NOTHING(product = factory.create(progressUpdate));
diff --git a/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h b/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h
index 391434f9587672c5707e5080b7c7d1e201177d99..7325a44b26cd03d0ea92cef524708553b366d0ef 100644
--- a/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h
+++ b/Vates/VatesAPI/test/vtkDataSetToScaledDataSetTest.h
@@ -7,7 +7,6 @@
 #include "MantidVatesAPI/MetadataJsonManager.h"
 #include "MantidVatesAPI/MetadataToFieldData.h"
 #include "MantidVatesAPI/VatesConfigurations.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetToScaledDataSet.h"
 #include "MantidVatesAPI/vtkMDHexFactory.h"
 #include "MockObjects.h"
@@ -35,8 +34,7 @@ private:
     FakeProgressAction progressUpdate;
     MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(8, -10.0, 10.0, 1);
-    vtkMDHexFactory factory(ThresholdRange_scptr(new NoThresholdRange),
-                            VolumeNormalization);
+    vtkMDHexFactory factory(VolumeNormalization);
     factory.initialize(ws);
     auto product = factory.create(progressUpdate);
     auto data = vtkUnstructuredGrid::SafeDownCast(product.Get());
diff --git a/Vates/VatesAPI/test/vtkMDHWSignalArrayTest.h b/Vates/VatesAPI/test/vtkMDHWSignalArrayTest.h
index 014ec76ddf29ecd5903aca1ac28414da1fb455d0..ae6d338ddd9a60e3a0b7fa32a499cb392e9f46fb 100644
--- a/Vates/VatesAPI/test/vtkMDHWSignalArrayTest.h
+++ b/Vates/VatesAPI/test/vtkMDHWSignalArrayTest.h
@@ -34,12 +34,8 @@ public:
     const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
-
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(Mantid::VATES::NoNormalization,
-                                            ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(), Mantid::VATES::NoNormalization,
+                            offset);
 
     for (auto index = 0; index < imageSize; ++index) {
       double output1[1];
@@ -82,7 +78,8 @@ public:
         dynamic_cast<MDHistoWorkspaceIterator *>(
             createIteratorWithNormalization(
                 Mantid::VATES::NumEventsNormalization, ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(),
+                            Mantid::VATES::NumEventsNormalization, offset);
 
     vtkNew<vtkIdList> ptIds;
 
@@ -108,20 +105,13 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3, 4);
     vtkNew<vtkMDHWSignalArray<double>> signal;
     std::size_t offset = 0;
-    const int nBinsX = static_cast<int>(ws_sptr->getXDimension()->getNBins());
-    const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
-    const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
-    const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
 
     ws_sptr->setMDMaskAt(0, true);
     ws_sptr->setMDMaskAt(7, true);
     ws_sptr->setMDMaskAt(42, true);
 
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(Mantid::VATES::NoNormalization,
-                                            ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(), Mantid::VATES::NoNormalization,
+                            offset);
 
     vtkNew<vtkIdList> idList1, idList2;
 
@@ -135,16 +125,8 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3);
     vtkNew<vtkMDHWSignalArray<double>> signal;
     std::size_t offset = 0;
-    const int nBinsX = static_cast<int>(ws_sptr->getXDimension()->getNBins());
-    const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
-    const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
-    const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
-
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(Mantid::VATES::VolumeNormalization,
-                                            ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(), Mantid::VATES::VolumeNormalization,
+                            offset);
 
     vtkNew<vtkDoubleArray> doubleArray;
     doubleArray->SetNumberOfComponents(1);
@@ -164,16 +146,9 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(8.0, 3, 10, 5.0);
     vtkNew<vtkMDHWSignalArray<double>> signal;
     std::size_t offset = 0;
-    const int nBinsX = static_cast<int>(ws_sptr->getXDimension()->getNBins());
-    const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
-    const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
-    const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
 
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(Mantid::VATES::NoNormalization,
-                                            ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(), Mantid::VATES::NoNormalization,
+                            offset);
     TS_ASSERT(signal->LookupValue(1.0) == 0);
     TS_ASSERT(signal->LookupTypedValue(1.0) == 0);
   }
@@ -183,16 +158,8 @@ public:
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3);
     vtkNew<vtkMDHWSignalArray<double>> signal;
     std::size_t offset = 0;
-    const int nBinsX = static_cast<int>(ws_sptr->getXDimension()->getNBins());
-    const int nBinsY = static_cast<int>(ws_sptr->getYDimension()->getNBins());
-    const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
-    const int imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
-
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(Mantid::VATES::NoNormalization,
-                                            ws_sptr.get())));
-    signal->InitializeArray(std::move(iterator), offset, imageSize);
+    signal->InitializeArray(ws_sptr.get(), Mantid::VATES::NoNormalization,
+                            offset);
 
     vtkNew<vtkIdList> idList1, idList2;
     signal->LookupValue(0.0, idList1.GetPointer());
@@ -222,11 +189,8 @@ public:
     const int nBinsZ = static_cast<int>(ws_sptr->getZDimension()->getNBins());
     imageSize = (nBinsX) * (nBinsY) * (nBinsZ);
 
-    std::unique_ptr<MDHistoWorkspaceIterator> iterator(
-        dynamic_cast<MDHistoWorkspaceIterator *>(
-            createIteratorWithNormalization(
-                Mantid::VATES::NumEventsNormalization, ws_sptr.get())));
-    m_signal->InitializeArray(std::move(iterator), offset, imageSize);
+    m_signal->InitializeArray(ws_sptr.get(),
+                              Mantid::VATES::NumEventsNormalization, offset);
   }
 
   void tearDown() override {}
diff --git a/Vates/VatesAPI/test/vtkMDHexFactoryTest.h b/Vates/VatesAPI/test/vtkMDHexFactoryTest.h
index 9fdf7d8cc30500dd225583f58b7390238aa011e8..6c5509cc93259173ad761cba6166f5ea829f5715 100644
--- a/Vates/VatesAPI/test/vtkMDHexFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDHexFactoryTest.h
@@ -1,6 +1,7 @@
 #ifndef VTK_MD_HEX_FACTORY_TEST
 #define VTK_MD_HEX_FACTORY_TEST
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidDataObjects/MDEventFactory.h"
@@ -8,9 +9,7 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHexFactory.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
@@ -50,8 +49,7 @@ private:
         AnalysisDataService::Instance().retrieve("binned");
     FakeProgressAction progressUpdater;
 
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.setCheckDimensionality(doCheckDimensionality);
     if (doCheckDimensionality) {
       TS_ASSERT_THROWS(factory.initialize(binned_ws), std::runtime_error);
@@ -67,15 +65,13 @@ public:
 
   void testCreateWithoutInitalizeThrows() {
     FakeProgressAction progressUpdater;
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     TSM_ASSERT_THROWS("Have NOT initalized object. Should throw.",
                       factory.create(progressUpdater), std::runtime_error);
   }
 
   void testInitalizeWithNullWorkspaceThrows() {
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
 
     IMDEventWorkspace *ws = NULL;
     TSM_ASSERT_THROWS("This is a NULL workspace. Should throw.",
@@ -84,8 +80,7 @@ public:
   }
 
   void testGetFactoryTypeName() {
-    vtkMDHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDHexFactory", factory.getFactoryTypeName());
   }
 
@@ -96,8 +91,7 @@ public:
     EXPECT_CALL(*mockSuccessor, initialize(_)).Times(1);
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     auto ws = boost::make_shared<Mantid::DataObjects::TableWorkspace>();
@@ -120,8 +114,7 @@ public:
         .WillOnce(Return(vtkSmartPointer<vtkStructuredGrid>::New()));
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     auto ws = boost::make_shared<Mantid::DataObjects::TableWorkspace>();
@@ -134,8 +127,7 @@ public:
 
   void testOnInitaliseCannotDelegateToSuccessor() {
     FakeProgressAction progressUpdater;
-    vtkMDHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     // factory.SetSuccessor(mockSuccessor); No Successor set.
 
     auto ws = boost::make_shared<Mantid::DataObjects::TableWorkspace>();
@@ -144,8 +136,7 @@ public:
 
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdater;
-    vtkMDHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     // initialize not called!
     TS_ASSERT_THROWS(factory.create(progressUpdater), std::runtime_error);
   }
@@ -186,8 +177,7 @@ public:
 
     Mantid::DataObjects::MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1);
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -226,8 +216,7 @@ public:
 
     Mantid::DataObjects::MDEventWorkspace4Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<4>(5, -10.0, 10.0, 1);
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -274,8 +263,7 @@ public:
 
     Mantid::DataObjects::MDEventWorkspace4Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<4>(4, -10.0, 10.0, 1);
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -319,8 +307,7 @@ public:
   void test_CreateDataSet_from3D() {
     FakeProgressAction progressUpdate;
 
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.initialize(m_ws3);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -359,8 +346,7 @@ public:
   void test_CreateDataSet_from4D() {
     FakeProgressAction progressUpdate;
 
-    vtkMDHexFactory factory(boost::make_shared<UserDefinedThresholdRange>(0, 1),
-                            VATES::VolumeNormalization);
+    vtkMDHexFactory factory(VATES::VolumeNormalization);
     factory.initialize(m_ws4);
     vtkSmartPointer<vtkDataSet> product;
 
diff --git a/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h b/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h
index 08c6f50a62a8e488a2fdf2157e24da78a9e2c780..a8696e1f93e7b7334d5c6c2a7131b1e34b8b454a 100644
--- a/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDHistoHex4DFactoryTest.h
@@ -5,9 +5,7 @@
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidVatesAPI/TimeStepToTimeStep.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHistoHex4DFactory.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
 #include "MantidVatesAPI/vtkStructuredGrid_Silent.h"
@@ -27,55 +25,6 @@ using namespace testing;
 class vtkMDHistoHex4DFactoryTest : public CxxTest::TestSuite {
 
 public:
-  void testThresholds() {
-    FakeProgressAction progressAction;
-
-    // Workspace with value 1.0 everywhere
-    MDHistoWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 4);
-    ws_sptr->setTransformFromOriginal(new NullCoordTransform);
-
-    // Set up so that only cells with signal values == 1 should not be filtered
-    // out by thresholding.
-
-    vtkMDHistoHex4DFactory<TimeStepToTimeStep> inside(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 2)),
-        Mantid::VATES::VolumeNormalization, 0);
-    inside.initialize(ws_sptr);
-    auto insideData = inside.create(progressAction);
-    auto insideProduct = vtkStructuredGrid::SafeDownCast(insideData.Get());
-
-    vtkMDHistoHex4DFactory<TimeStepToTimeStep> below(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 0.5)),
-        Mantid::VATES::VolumeNormalization, 0);
-    below.initialize(ws_sptr);
-    auto belowData = below.create(progressAction);
-    auto belowProduct = vtkStructuredGrid::SafeDownCast(belowData.Get());
-
-    vtkMDHistoHex4DFactory<TimeStepToTimeStep> above(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(2, 3)),
-        Mantid::VATES::VolumeNormalization, 0);
-    above.initialize(ws_sptr);
-    auto aboveData = above.create(progressAction);
-    auto aboveProduct = vtkStructuredGrid::SafeDownCast(aboveData.Get());
-
-    TS_ASSERT_EQUALS((10 * 10 * 10), insideProduct->GetNumberOfCells());
-    for (auto i = 0; i < insideProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(insideProduct->IsCellVisible(i) != 0);
-    }
-
-    // This has changed. Cells are still present but not visible.
-    TS_ASSERT_EQUALS((10 * 10 * 10), belowProduct->GetNumberOfCells());
-    for (auto i = 0; i < belowProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(belowProduct->IsCellVisible(i) == 0);
-    }
-
-    TS_ASSERT_EQUALS((10 * 10 * 10), aboveProduct->GetNumberOfCells());
-    for (auto i = 0; i < aboveProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(aboveProduct->IsCellVisible(i) == 0);
-    }
-  }
-
   void testProgressUpdating() {
     MockProgressAction mockProgressAction;
     // Expectation checks that progress should be >= 0 and <= 100 and called at
@@ -86,7 +35,6 @@ public:
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 4);
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory(
-        ThresholdRange_scptr(new NoThresholdRange),
         Mantid::VATES::VolumeNormalization, 0);
 
     factory.initialize(ws_sptr);
@@ -103,14 +51,11 @@ public:
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 4);
     ws_sptr->setTransformFromOriginal(new NullCoordTransform);
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory =
         vtkMDHistoHex4DFactory<TimeStepToTimeStep>(
-            ThresholdRange_scptr(pRange.release()),
             Mantid::VATES::VolumeNormalization, 0);
     factory.initialize(ws_sptr);
 
@@ -132,9 +77,8 @@ public:
 
     IMDWorkspace *nullWorkspace = NULL;
     Mantid::API::IMDWorkspace_sptr ws_sptr(nullWorkspace);
-    UserDefinedThresholdRange *pRange = new UserDefinedThresholdRange(0, 100);
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory(
-        ThresholdRange_scptr(pRange), Mantid::VATES::VolumeNormalization, 1);
+        Mantid::VATES::VolumeNormalization, 1);
 
     TSM_ASSERT_THROWS(
         "No workspace, so should not be possible to complete initialization.",
@@ -144,10 +88,7 @@ public:
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressAction;
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory(
-        ThresholdRange_scptr(pRange.release()),
         Mantid::VATES::VolumeNormalization, 1);
     TS_ASSERT_THROWS(factory.create(progressAction), std::runtime_error);
   }
@@ -167,14 +108,10 @@ public:
     EXPECT_CALL(*pMockFactorySuccessor, getFactoryTypeName())
         .WillOnce(testing::Return("TypeA"));
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
-
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory =
         vtkMDHistoHex4DFactory<TimeStepToTimeStep>(
-            ThresholdRange_scptr(pRange.release()),
             Mantid::VATES::VolumeNormalization, (double)0);
 
     // Successor is provided.
@@ -196,14 +133,10 @@ public:
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2);
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
-
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory =
         vtkMDHistoHex4DFactory<TimeStepToTimeStep>(
-            ThresholdRange_scptr(pRange.release()),
             Mantid::VATES::VolumeNormalization, (double)0);
 
     TSM_ASSERT_THROWS("Should have thrown an execption given that no successor "
@@ -235,14 +168,10 @@ public:
     EXPECT_CALL(*pMockFactorySuccessor, getFactoryTypeName())
         .WillOnce(testing::Return("TypeA"));
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
-
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory =
         vtkMDHistoHex4DFactory<TimeStepToTimeStep>(
-            ThresholdRange_scptr(pRange.release()),
             Mantid::VATES::VolumeNormalization, (double)0);
 
     // Successor is provided.
@@ -260,12 +189,8 @@ public:
   void testTypeName() {
     using namespace Mantid::VATES;
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100);
-
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory =
         vtkMDHistoHex4DFactory<TimeStepToTimeStep>(
-            ThresholdRange_scptr(pRange.release()),
             Mantid::VATES::VolumeNormalization, (double)0);
     TS_ASSERT_EQUALS("vtkMDHistoHex4DFactory", factory.getFactoryTypeName());
   }
@@ -288,10 +213,7 @@ public:
   void testGenerateVTKDataSet() {
     FakeProgressAction progressUpdate;
 
-    auto pRange =
-        Mantid::Kernel::make_unique<UserDefinedThresholdRange>(0, 100000);
     vtkMDHistoHex4DFactory<TimeStepToTimeStep> factory(
-        ThresholdRange_scptr(pRange.release()),
         Mantid::VATES::VolumeNormalization, 0);
     factory.initialize(m_ws_sptr);
     TS_ASSERT_THROWS_NOTHING(factory.create(progressUpdate));
diff --git a/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h b/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h
index 3cdb9c9515afec087463f1415b81ee773a60b967..7cfe65be4494882bb4a95a04ad163fef1b51b9ef 100644
--- a/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDHistoHexFactoryTest.h
@@ -4,8 +4,6 @@
 #include "MantidKernel/make_unique.h"
 #include "MantidDataObjects/MDHistoWorkspace.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHistoHexFactory.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
@@ -29,52 +27,6 @@ using namespace testing;
 class vtkMDHistoHexFactoryTest : public CxxTest::TestSuite {
 
 public:
-  void testThresholds() {
-    FakeProgressAction progressUpdate;
-
-    // Workspace with value 1.0 everywhere
-    MDHistoWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3);
-    ws_sptr->setTransformFromOriginal(new NullCoordTransform);
-
-    vtkMDHistoHexFactory inside(
-        boost::make_shared<UserDefinedThresholdRange>(0, 2),
-        Mantid::VATES::VolumeNormalization);
-    inside.initialize(ws_sptr);
-    auto insideData = inside.create(progressUpdate);
-    auto insideProduct = vtkStructuredGrid::SafeDownCast(insideData.Get());
-
-    vtkMDHistoHexFactory below(
-        boost::make_shared<UserDefinedThresholdRange>(0, 0.5),
-        Mantid::VATES::VolumeNormalization);
-    below.initialize(ws_sptr);
-    auto belowData = below.create(progressUpdate);
-    auto belowProduct = vtkStructuredGrid::SafeDownCast(belowData.Get());
-
-    vtkMDHistoHexFactory above(
-        boost::make_shared<UserDefinedThresholdRange>(2, 3),
-        Mantid::VATES::VolumeNormalization);
-    above.initialize(ws_sptr);
-    auto aboveData = above.create(progressUpdate);
-    auto aboveProduct = vtkStructuredGrid::SafeDownCast(aboveData.Get());
-
-    TS_ASSERT_EQUALS((10 * 10 * 10), insideProduct->GetNumberOfCells());
-    for (auto i = 0; i < insideProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(insideProduct->IsCellVisible(i) != 0);
-    }
-
-    // This has changed. Cells are still present but not visible.
-    TS_ASSERT_EQUALS((10 * 10 * 10), belowProduct->GetNumberOfCells());
-    for (auto i = 0; i < belowProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(belowProduct->IsCellVisible(i) == 0);
-    }
-
-    TS_ASSERT_EQUALS((10 * 10 * 10), aboveProduct->GetNumberOfCells());
-    for (auto i = 0; i < aboveProduct->GetNumberOfCells(); ++i) {
-      TS_ASSERT(aboveProduct->IsCellVisible(i) == 0);
-    }
-  }
-
   void testSignalAspects() {
     FakeProgressAction progressUpdate;
 
@@ -85,9 +37,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(ws_sptr);
 
     auto product = factory.create(progressUpdate);
@@ -112,8 +62,7 @@ public:
 
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3);
-    vtkMDHistoHexFactory factory(boost::make_shared<NoThresholdRange>(),
-                                 Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
 
     factory.initialize(ws_sptr);
     auto product = factory.create(mockProgressAction);
@@ -126,9 +75,7 @@ public:
     IMDWorkspace *nullWorkspace = NULL;
     Mantid::API::IMDWorkspace_sptr ws_sptr(nullWorkspace);
 
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS(
         "No workspace, so should not be possible to complete initialization.",
@@ -137,9 +84,7 @@ public:
 
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdate;
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_THROWS(factory.create(progressUpdate), std::runtime_error);
   }
 
@@ -159,9 +104,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -183,9 +126,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS("Should have thrown an execption given that no successor "
                       "was available.",
@@ -217,9 +158,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -235,9 +174,7 @@ public:
 
   void testTypeName() {
     using namespace Mantid::VATES;
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDHistoHexFactory", factory.getFactoryTypeName());
   }
 };
@@ -260,9 +197,7 @@ public:
     FakeProgressAction progressUpdate;
 
     // Create the factory.
-    vtkMDHistoHexFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoHexFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(m_ws_sptr);
 
     TS_ASSERT_THROWS_NOTHING(factory.create(progressUpdate));
diff --git a/Vates/VatesAPI/test/vtkMDHistoLineFactoryTest.h b/Vates/VatesAPI/test/vtkMDHistoLineFactoryTest.h
index af30d6e400a5b8260ff0fa8bffe31f94861ae9d2..15871c051c81ea2bcf4709ec919a51d9be5a5efb 100644
--- a/Vates/VatesAPI/test/vtkMDHistoLineFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDHistoLineFactoryTest.h
@@ -3,8 +3,6 @@
 
 #include "MantidAPI/IMDIterator.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHistoLineFactory.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
@@ -31,9 +29,7 @@ public:
     IMDWorkspace *nullWorkspace = NULL;
     Mantid::API::IMDWorkspace_sptr ws_sptr(nullWorkspace);
 
-    vtkMDHistoLineFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 10000)),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS(
         "No workspace, so should not be possible to complete initialization.",
@@ -42,72 +38,10 @@ public:
 
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdate;
-    vtkMDHistoLineFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 10000)),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_THROWS(factory.create(progressUpdate), std::runtime_error);
   }
 
-  void testInsideThresholds() {
-    FakeProgressAction progressUpdate;
-
-    Mantid::API::IMDWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1);
-
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall between the minimum 0 and maximum 2.
-    vtkMDHistoLineFactory inside(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 2)),
-        Mantid::VATES::VolumeNormalization);
-    inside.initialize(ws_sptr);
-    auto insideData = inside.create(progressUpdate);
-    auto insideProduct = vtkUnstructuredGrid::SafeDownCast(insideData.Get());
-
-    TS_ASSERT_EQUALS(9, insideProduct->GetNumberOfCells());
-    TS_ASSERT_EQUALS(10, insideProduct->GetNumberOfPoints());
-  }
-
-  void testAboveThreshold() {
-    using namespace Mantid::Geometry;
-    using namespace testing;
-
-    FakeProgressAction progressUpdate;
-
-    Mantid::API::IMDWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1);
-
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall above and outside the minimum 0 and maximum 0.5.
-    vtkMDHistoLineFactory above(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 0.5)),
-        Mantid::VATES::VolumeNormalization);
-    above.initialize(ws_sptr);
-    auto aboveData = above.create(progressUpdate);
-    auto aboveProduct = vtkUnstructuredGrid::SafeDownCast(aboveData.Get());
-
-    TS_ASSERT_EQUALS(0, aboveProduct->GetNumberOfCells());
-    TS_ASSERT_EQUALS(10, aboveProduct->GetNumberOfPoints());
-  }
-
-  void testBelowThreshold() {
-    FakeProgressAction progressUpdate;
-
-    Mantid::API::IMDWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1);
-
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall below and outside the minimum 1.5 and maximum 2.
-    vtkMDHistoLineFactory below(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(1.5, 2)),
-        Mantid::VATES::VolumeNormalization);
-    below.initialize(ws_sptr);
-    auto belowData = below.create(progressUpdate);
-    auto belowProduct = vtkUnstructuredGrid::SafeDownCast(belowData.Get());
-
-    TS_ASSERT_EQUALS(0, belowProduct->GetNumberOfCells());
-    TS_ASSERT_EQUALS(10, belowProduct->GetNumberOfPoints());
-  }
-
   void testProgressUpdates() {
     MockProgressAction mockProgressAction;
     // Expectation checks that progress should be >= 0 and <= 100 and called at
@@ -117,8 +51,7 @@ public:
 
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 1);
-    vtkMDHistoLineFactory factory(ThresholdRange_scptr(new NoThresholdRange),
-                                  Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
 
     factory.initialize(ws_sptr);
     auto product = factory.create(mockProgressAction);
@@ -144,9 +77,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoLineFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 10000)),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -168,9 +99,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoLineFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 10000)),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS("Should have thrown an execption given that no successor "
                       "was available.",
@@ -202,9 +131,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    vtkMDHistoLineFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -219,9 +146,7 @@ public:
   }
 
   void testTypeName() {
-    vtkMDHistoLineFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 10000),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDHistoLineFactory", factory.getFactoryTypeName());
   }
 };
@@ -242,11 +167,7 @@ public:
 
   void testGenerateVTKDataSet() {
     FakeProgressAction progressUpdate;
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall between the minimum 0 and maximum 2.
-    vtkMDHistoLineFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 2),
-        Mantid::VATES::VolumeNormalization);
+    vtkMDHistoLineFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(m_ws_sptr);
     TS_ASSERT_THROWS_NOTHING(factory.create(progressUpdate));
   }
diff --git a/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h b/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h
index b03dba696237abf56a195cc898d6d5692b911f64..28424d037c3f2e92b9883090593cecaa93d9133d 100644
--- a/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDHistoQuadFactoryTest.h
@@ -4,8 +4,6 @@
 #include "MantidAPI/IMDIterator.h"
 #include "MantidKernel/make_unique.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MantidVatesAPI/vtkMDHistoQuadFactory.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
@@ -35,8 +33,7 @@ public:
     IMDWorkspace *nullWorkspace = NULL;
     Mantid::API::IMDWorkspace_sptr ws_sptr(nullWorkspace);
 
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 100);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS(
         "No workspace, so should not be possible to complete initialization.",
@@ -46,8 +43,7 @@ public:
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdate;
 
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 100);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_THROWS(factory.create(progressUpdate), std::runtime_error);
   }
 
@@ -58,10 +54,7 @@ public:
     Mantid::API::IMDWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2);
 
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall between the minimum 0 and maximum 2.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 2);
-    vtkMDHistoQuadFactory inside(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory inside(Mantid::VATES::VolumeNormalization);
     inside.initialize(ws_sptr);
     auto product = inside.create(progressUpdate);
     auto data = vtkDataSet::SafeDownCast(product.Get());
@@ -71,53 +64,6 @@ public:
     TS_ASSERT_EQUALS((11 * 11), insideProduct->GetNumberOfPoints());
   }
 
-  void testAboveThreshold() {
-    FakeProgressAction progressUpdate;
-    // WS with 2 dimensions
-    Mantid::API::IMDWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2);
-
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall above and outside the minimum 0 and maximum 0.5.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 0.5);
-    vtkMDHistoQuadFactory above(pRange, Mantid::VATES::VolumeNormalization);
-    above.initialize(ws_sptr);
-    auto product = above.create(progressUpdate);
-    auto data = vtkDataSet::SafeDownCast(product.Get());
-    vtkSmartPointer<vtkDataSet> aboveProduct(data);
-
-    // This changed from previously, in order to ensure that we do not pass on
-    // empty
-    // workspaces. A single point is created in the center by the
-    // vtkNullUnstructuredGrid
-    TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfCells());
-    TS_ASSERT_EQUALS(1, aboveProduct->GetNumberOfPoints());
-  }
-
-  void testBelowThreshold() {
-    FakeProgressAction progressUpdate;
-    // WS with 2 dimensions
-    Mantid::API::IMDWorkspace_sptr ws_sptr =
-        MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2);
-
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall below and outside the minimum 1.5 and maximum 2.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(1.5, 2);
-    vtkMDHistoQuadFactory below(pRange, Mantid::VATES::VolumeNormalization);
-
-    below.initialize(ws_sptr);
-    auto product = below.create(progressUpdate);
-    auto data = vtkUnstructuredGrid::SafeDownCast(product.Get());
-    vtkSmartPointer<vtkDataSet> belowProduct(data);
-
-    // This changed from previously, in order to ensure that we do not pass on
-    // empty
-    // workspaces. A single point is created in the center by the
-    // vtkNullUnstructuredGrid
-    TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfCells());
-    TS_ASSERT_EQUALS(1, belowProduct->GetNumberOfPoints());
-  }
-
   void testInitializationDelegates() {
     // If the workspace provided is not a 4D imdworkspace, it should call the
     // successor's initalization
@@ -135,8 +81,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 1);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -159,9 +104,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    UserDefinedThresholdRange *pRange = new UserDefinedThresholdRange(0, 1);
-    vtkMDHistoQuadFactory factory(ThresholdRange_scptr(pRange),
-                                  Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
 
     TSM_ASSERT_THROWS("Should have thrown an execption given that no successor "
                       "was available.",
@@ -193,8 +136,7 @@ public:
 
     // Constructional method ensures that factory is only suitable for providing
     // mesh information.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 1);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
 
     // Successor is provided.
     factory.setSuccessor(std::move(uniqueSuccessor));
@@ -209,8 +151,7 @@ public:
   }
 
   void testTypeName() {
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 1);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDHistoQuadFactory", factory.getFactoryTypeName());
   }
 
@@ -223,8 +164,7 @@ public:
 
     MDHistoWorkspace_sptr ws_sptr =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 2);
-    vtkMDHistoQuadFactory factory(ThresholdRange_scptr(new NoThresholdRange),
-                                  Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
 
     factory.initialize(ws_sptr);
     auto product = factory.create(mockProgressAction);
@@ -250,10 +190,7 @@ public:
 
   void testGenerateVTKDataSet() {
     FakeProgressAction progressUpdate;
-    // Thresholds have been set such that the signal values (hard-coded to 1,
-    // see above) will fall between the minimum 0 and maximum 2.
-    auto pRange = boost::make_shared<UserDefinedThresholdRange>(0, 1);
-    vtkMDHistoQuadFactory factory(pRange, Mantid::VATES::VolumeNormalization);
+    vtkMDHistoQuadFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(m_ws_sptr);
     TS_ASSERT_THROWS_NOTHING(factory.create(progressUpdate));
   }
diff --git a/Vates/VatesAPI/test/vtkMDLineFactoryTest.h b/Vates/VatesAPI/test/vtkMDLineFactoryTest.h
index 2189e58b48b7097d45d8d3d9f4103c47b004c4e2..22707258d21bf5c360f3f7f8f69d53ec8599cacc 100644
--- a/Vates/VatesAPI/test/vtkMDLineFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDLineFactoryTest.h
@@ -3,9 +3,9 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/make_unique.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidVatesAPI/vtkMDLineFactory.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MockObjects.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "vtkCellType.h"
@@ -24,8 +24,7 @@ using namespace testing;
 class vtkMDLineFactoryTest : public CxxTest::TestSuite {
 public:
   void testGetFactoryTypeName() {
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDLineFactory", factory.getFactoryTypeName());
   }
 
@@ -36,8 +35,7 @@ public:
     EXPECT_CALL(*mockSuccessor, initialize(_)).Times(1);
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     ITableWorkspace_sptr ws =
@@ -60,8 +58,7 @@ public:
         .WillOnce(Return(vtkSmartPointer<vtkStructuredGrid>::New()));
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     auto ws = boost::make_shared<Mantid::DataObjects::TableWorkspace>();
@@ -73,10 +70,7 @@ public:
   }
 
   void testOnInitaliseCannotDelegateToSuccessor() {
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
-    // factory.SetSuccessor(mockSuccessor); No Successor set.
-
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     ITableWorkspace_sptr ws =
         boost::make_shared<Mantid::DataObjects::TableWorkspace>();
     TS_ASSERT_THROWS(factory.initialize(ws), std::runtime_error);
@@ -85,8 +79,7 @@ public:
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdate;
 
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     // initialize not called!
     TS_ASSERT_THROWS(factory.create(progressUpdate), std::runtime_error);
   }
@@ -115,8 +108,7 @@ public:
     Workspace_sptr binned =
         Mantid::API::AnalysisDataService::Instance().retrieve("binned");
 
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(binned);
 
     auto product = factory.create(mockProgressAction);
@@ -162,8 +154,7 @@ public:
     Workspace_sptr binned =
         Mantid::API::AnalysisDataService::Instance().retrieve("binned");
 
-    vtkMDLineFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDLineFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(binned);
 
     auto product = factory.create(progressAction);
diff --git a/Vates/VatesAPI/test/vtkMDQuadFactoryTest.h b/Vates/VatesAPI/test/vtkMDQuadFactoryTest.h
index cc4674639bf0a10e1e4ee82c919dc876f299e408..d29dfd93af33f454a6a302b4e3ac445f64f1a1a7 100644
--- a/Vates/VatesAPI/test/vtkMDQuadFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkMDQuadFactoryTest.h
@@ -3,9 +3,9 @@
 
 #include <cxxtest/TestSuite.h>
 #include "MantidKernel/make_unique.h"
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidDataObjects/TableWorkspace.h"
 #include "MantidVatesAPI/vtkMDQuadFactory.h"
-#include "MantidVatesAPI/NoThresholdRange.h"
 #include "MockObjects.h"
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "vtkCellType.h"
@@ -25,8 +25,7 @@ class vtkMDQuadFactoryTest : public CxxTest::TestSuite {
 
 public:
   void testGetFactoryTypeName() {
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     TS_ASSERT_EQUALS("vtkMDQuadFactory", factory.getFactoryTypeName());
   }
 
@@ -37,8 +36,7 @@ public:
     EXPECT_CALL(*mockSuccessor, initialize(_)).Times(1);
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     ITableWorkspace_sptr ws =
@@ -61,8 +59,7 @@ public:
         .WillOnce(Return(vtkSmartPointer<vtkStructuredGrid>::New()));
     EXPECT_CALL(*mockSuccessor, getFactoryTypeName()).Times(1);
 
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     factory.setSuccessor(std::move(uniqueSuccessor));
 
     ITableWorkspace_sptr ws =
@@ -75,10 +72,7 @@ public:
   }
 
   void testOnInitaliseCannotDelegateToSuccessor() {
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
-    // factory.SetSuccessor(mockSuccessor); No Successor set.
-
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     ITableWorkspace_sptr ws =
         boost::make_shared<Mantid::DataObjects::TableWorkspace>();
     TS_ASSERT_THROWS(factory.initialize(ws), std::runtime_error);
@@ -87,8 +81,7 @@ public:
   void testCreateWithoutInitaliseThrows() {
     FakeProgressAction progressUpdate;
 
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     // initialize not called!
     TS_ASSERT_THROWS(factory.create(progressUpdate), std::runtime_error);
   }
@@ -118,8 +111,7 @@ public:
     Workspace_sptr binned =
         Mantid::API::AnalysisDataService::Instance().retrieve("binned");
 
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(binned);
 
     auto product = factory.create(mockProgressAction);
@@ -165,8 +157,7 @@ public:
     Workspace_sptr binned =
         Mantid::API::AnalysisDataService::Instance().retrieve("binned");
 
-    vtkMDQuadFactory factory(boost::make_shared<NoThresholdRange>(),
-                             Mantid::VATES::VolumeNormalization);
+    vtkMDQuadFactory factory(Mantid::VATES::VolumeNormalization);
     factory.initialize(binned);
 
     auto product = factory.create(progressUpdate);
diff --git a/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h b/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
index 39df83afdf9000121f1b8bcdba9ee29a61c5e971..7826f9c0f50ec568a557dd9bebe1241273b81a58 100644
--- a/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
+++ b/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
@@ -9,7 +9,6 @@
 #include "MantidVatesAPI/FieldDataToMetadata.h"
 #include "MantidVatesAPI/MetadataJsonManager.h"
 #include "MantidVatesAPI/MetadataToFieldData.h"
-#include "MantidVatesAPI/UserDefinedThresholdRange.h"
 #include "MantidVatesAPI/VatesConfigurations.h"
 #include "MantidVatesAPI/vtkSplatterPlotFactory.h"
 #include "MockObjects.h"
@@ -37,15 +36,13 @@ public:
 
   void testCreateWithoutInitializeThrows() {
     FakeProgressAction progressUpdate;
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     TSM_ASSERT_THROWS("Have NOT initalized object. Should throw.",
                       factory.create(progressUpdate), std::runtime_error);
   }
 
   void testInitializeWithNullWorkspaceThrows() {
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     IMDEventWorkspace *ws = NULL;
     TSM_ASSERT_THROWS("This is a NULL workspace. Should throw.",
                       factory.initialize(Workspace_sptr(ws)),
@@ -60,8 +57,7 @@ public:
     size_t binning = 5;
     MDHistoWorkspace_sptr ws =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 3, binning);
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -98,8 +94,7 @@ public:
     size_t binning = 5;
     IMDHistoWorkspace_sptr ws =
         MDEventsTestHelper::makeFakeMDHistoWorkspace(1.0, 4, binning);
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -133,8 +128,7 @@ public:
 
     MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1);
-    vtkSplatterPlotFactory factory(
-        boost::make_shared<UserDefinedThresholdRange>(0, 1), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -168,8 +162,7 @@ public:
 
     MDEventWorkspace4Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<4>(5, -10.0, 10.0, 1);
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkSmartPointer<vtkDataSet> product;
 
@@ -202,8 +195,7 @@ public:
     FakeProgressAction progressUpdate;
     MDEventWorkspace3Lean::sptr ws =
         MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1);
-    vtkSplatterPlotFactory factory(
-        ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    vtkSplatterPlotFactory factory("signal");
     factory.initialize(ws);
     vtkDataSet *product = NULL;
 
diff --git a/Vates/VatesSimpleGui/StandAloneExec/src/main.cpp b/Vates/VatesSimpleGui/StandAloneExec/src/main.cpp
index bbd81c060ad56b8f141a278405e9e1008fb28872..52b4b76048795fc5d0258493687788585f24bf59 100644
--- a/Vates/VatesSimpleGui/StandAloneExec/src/main.cpp
+++ b/Vates/VatesSimpleGui/StandAloneExec/src/main.cpp
@@ -10,13 +10,13 @@ int main(int argc, char **argv) {
     window.show();
     return app.exec();
   } catch (std::exception &e) {
-    QMessageBox::critical(0, "VatesSimpleGui - Error",
+    QMessageBox::critical(nullptr, "VatesSimpleGui - Error",
                           QString("An unhandled exception has been caught. "
                                   "VatesSimpleGui will have to close. "
                                   "Details:\n\n") +
                               e.what());
   } catch (...) {
-    QMessageBox::critical(0, "VatesSimpleGui - Error",
+    QMessageBox::critical(nullptr, "VatesSimpleGui - Error",
                           "An unhandled exception has been caught. "
                           "VatesSimpleGui will have to close.");
   }
diff --git a/Vates/VatesSimpleGui/ViewWidgets/icons/ViewWidgetsIcons.qrc b/Vates/VatesSimpleGui/ViewWidgets/icons/ViewWidgetsIcons.qrc
index d6e22e59aefd6da2250d378879360e2659af31fc..42c9f3ff235499481befdd156a949bd49fc681d7 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/icons/ViewWidgetsIcons.qrc
+++ b/Vates/VatesSimpleGui/ViewWidgets/icons/ViewWidgetsIcons.qrc
@@ -6,5 +6,7 @@
         <file>pvIcon.png</file>
         <file>pqEditColor24.png</file>
         <file>resetViewToAll24.png</file>
+        <file>pqSlice24.png</file>
+        <file>pqThreshold24.png</file>
     </qresource>
 </RCC>
diff --git a/Vates/VatesSimpleGui/ViewWidgets/icons/pqSlice24.png b/Vates/VatesSimpleGui/ViewWidgets/icons/pqSlice24.png
new file mode 100644
index 0000000000000000000000000000000000000000..070ce3bda466eb48ec29e873917fe3699d4262b9
Binary files /dev/null and b/Vates/VatesSimpleGui/ViewWidgets/icons/pqSlice24.png differ
diff --git a/Vates/VatesSimpleGui/ViewWidgets/icons/pqThreshold24.png b/Vates/VatesSimpleGui/ViewWidgets/icons/pqThreshold24.png
new file mode 100644
index 0000000000000000000000000000000000000000..407467f848105219bb51123b92952c3b7f4204de
Binary files /dev/null and b/Vates/VatesSimpleGui/ViewWidgets/icons/pqThreshold24.png differ
diff --git a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
index 9deb82e95360f9dfe061775a8eb2a53b5c632b5d..0e05332882f2b3c796be6152a7d4a3e2309918b7 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
+++ b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
@@ -90,7 +90,7 @@ public:
   void renderWorkspace(QString workspaceName, int workspaceType,
                        std::string instrumentName) override;
   /// See MantidQt::API::VatesViewerInterface
-  void setupPluginMode() override;
+  void setupPluginMode(int WsType, const std::string &instrumentName) override;
   /// Load the state of the window from a Mantid project file
   void loadFromProject(const std::string &lines) override;
   /// Save the state of the window to a Mantid project file
@@ -214,7 +214,7 @@ private:
   /// Set the signals/slots for the ParaView components based on the view.
   void setParaViewComponentsForView();
   /// Run the necessary setup for the main view.
-  void setupMainView();
+  void setupMainView(ModeControlWidget::Views viewType);
   /// Creates the UI and mode switch connection.
   void setupUiAndConnections();
   /// Create the requested view.
diff --git a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
index 1c77e4caea592a150f856ce7e2013413fcb1fc01..076bc018369fa79097ce80d43f0aef84f417f366 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
+++ b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
@@ -89,6 +89,8 @@ public slots:
 protected slots:
   /// Add a slice to the current dataset.
   void onCutButtonClicked();
+  /// Apply the threshold filter to the current dataset.
+  void onThresholdButtonClicked();
   /// Perform operations when rendering is done.
   void onRenderDone();
   /// Invoke the ScaleWorkspace on the current dataset.
diff --git a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui
index c3c83e587838de402e3a8a2bd38ff66bb296c040..5121a033c35eaf658c0987b974291841e3083c88 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui
+++ b/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui
@@ -72,8 +72,41 @@
      </item>
      <item>
       <widget class="QPushButton" name="cutButton">
+       <property name="toolTip">
+        <string>apply cut filter</string>
+       </property>
+       <property name="text">
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../icons/ViewWidgetsIcons.qrc">
+         <normaloff>:/VatesSimpleGuiViewWidgets/icons/pqSlice24.png</normaloff>:/VatesSimpleGuiViewWidgets/icons/pqSlice24.png</iconset>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>24</width>
+         <height>24</height>
+        </size>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QPushButton" name="thresholdButton">
+       <property name="toolTip">
+        <string>apply threshold filter</string>
+       </property>
        <property name="text">
-        <string>Cut</string>
+        <string/>
+       </property>
+       <property name="icon">
+        <iconset resource="../../icons/ViewWidgetsIcons.qrc">
+         <normaloff>:/VatesSimpleGuiViewWidgets/icons/pqThreshold24.png</normaloff>:/VatesSimpleGuiViewWidgets/icons/pqThreshold24.png</iconset>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>24</width>
+         <height>24</height>
+        </size>
        </property>
       </widget>
      </item>
@@ -100,6 +133,9 @@
        <height>400</height>
       </size>
      </property>
+     <property name="toolTip">
+      <string>Apply cut filter</string>
+     </property>
      <property name="frameShape">
       <enum>QFrame::StyledPanel</enum>
      </property>
@@ -111,6 +147,8 @@
   </layout>
  </widget>
  <layoutdefault spacing="6" margin="11"/>
- <resources/>
+ <resources>
+  <include location="../../icons/ViewWidgetsIcons.qrc"/>
+ </resources>
  <connections/>
 </ui>
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp
index ead81038f0f1b800c936986831f59b4323e7d8ba..37a628bac26eb4d5e588f35d67482c6cda623fcf 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/BackgroundRgbProvider.cpp
@@ -145,4 +145,4 @@ void BackgroundRgbProvider::backgroundColorChangeCallbackFunction(
 }
 }
 }
-}
\ No newline at end of file
+}
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp
index f6efdf7366b967f6d96abda75cac15149a68e749..a215560a14d422c1ca0b738404daa7caa97d94ec 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp
@@ -33,7 +33,7 @@ Mantid::VATES::ViewFrustum_const_sptr CameraManager::getCurrentViewFrustum() {
 
   pqView *view = pqActiveObjects::instance().activeView();
 
-  vtkSMRenderViewProxy *proxy = NULL;
+  vtkSMRenderViewProxy *proxy = nullptr;
 
   if (view) {
     proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy());
@@ -98,7 +98,7 @@ Mantid::VATES::ViewFrustum_const_sptr CameraManager::getCurrentViewFrustum() {
 void CameraManager::setCameraToPeak(double xpos, double ypos, double zpos,
                                     double peakRadius) {
   pqView *view = pqActiveObjects::instance().activeView();
-  vtkSMRenderViewProxy *proxy = NULL;
+  vtkSMRenderViewProxy *proxy = nullptr;
 
   if (view) {
     proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy());
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp
index 047138ef80e6422fabb84fa2eedb49ded15e073c..639726cd1c1efe29230b6cee954a5ea020e535b1 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/ColorSelectionWidget.cpp
@@ -28,7 +28,7 @@ namespace SimpleGui {
 ColorSelectionWidget::ColorSelectionWidget(QWidget *parent)
     : QWidget(parent), m_minHistoric(0.01), m_maxHistoric(0.01),
       m_ignoreColorChangeCallbacks(false),
-      m_inProcessUserRequestedAutoScale(false), m_colorScaleLock(NULL) {
+      m_inProcessUserRequestedAutoScale(false), m_colorScaleLock(nullptr) {
   this->m_ui.setupUi(this);
   this->m_ui.autoColorScaleCheckBox->setChecked(true);
   this->setEditorStatus(false);
@@ -443,7 +443,7 @@ void ColorSelectionWidget::reset() {
  */
 void ColorSelectionWidget::setColorScaleLock(
     Mantid::VATES::ColorScaleLock *lock) {
-  if (m_colorScaleLock == NULL) {
+  if (!m_colorScaleLock) {
     m_colorScaleLock = lock;
   }
 }
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp
index 4923771f1ceab8783d9beaff37d1864bc8e5f60a..702ceaec9b29acf637fc9b1c5b4890cc9c906137 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/ColorUpdater.cpp
@@ -66,7 +66,7 @@ VsiColorScale ColorUpdater::autoScale() {
 void ColorUpdater::colorMapChange(pqPipelineRepresentation *repr,
                                   const Json::Value &model) {
   pqScalarsToColors *lut = repr->getLookupTable();
-  if (NULL == lut) {
+  if (!lut) {
     // Got a bad proxy, so just return
     return;
   }
@@ -120,7 +120,7 @@ void ColorUpdater::colorScaleChange(double min, double max) {
 void ColorUpdater::updateLookupTable(pqDataRepresentation *representation) {
   pqScalarsToColors *lookupTable = representation->getLookupTable();
 
-  if (NULL != lookupTable) {
+  if (lookupTable) {
     // Set the scalar range values
     lookupTable->setScalarRange(this->m_minScale, this->m_maxScale);
 
@@ -130,7 +130,7 @@ void ColorUpdater::updateLookupTable(pqDataRepresentation *representation) {
     vtkSMProxy *scalarOpacityFunctionProxy =
         lutProxy ? pqSMAdaptor::getProxyProperty(
                        lutProxy->GetProperty("ScalarOpacityFunction"))
-                 : NULL;
+                 : nullptr;
 
     if (scalarOpacityFunctionProxy) {
       vtkSMTransferFunctionProxy::RescaleTransferFunction(
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
index 8174343d80934e226a70887cfbe33e5f02958735..6b9fa7fb35d329a9f5cbc9b8d60c0d1589919f21 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
@@ -5,6 +5,7 @@
 #include <string>
 #include <vector>
 
+#include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDHistoWorkspace.h"
 #include "MantidAPI/IPeaksWorkspace.h"
@@ -156,13 +157,14 @@ MdViewerWidget::AllVSIViewsState::~AllVSIViewsState() {}
  * This constructor is used in the plugin mode operation of the VSI.
  */
 MdViewerWidget::MdViewerWidget()
-    : VatesViewerInterface(), currentView(NULL),
+    : VatesViewerInterface(), currentView(nullptr),
 
-      hiddenView(NULL), viewSwitched(false), dataLoader(NULL), lodAction(NULL),
-      screenShot(NULL), viewLayout(NULL), viewSettings(NULL),
-      useCurrentColorSettings(false), initialView(ModeControlWidget::STANDARD),
+      hiddenView(nullptr), viewSwitched(false), dataLoader(nullptr),
+      lodAction(nullptr), screenShot(nullptr), viewLayout(nullptr),
+      viewSettings(nullptr), useCurrentColorSettings(false),
+      initialView(ModeControlWidget::STANDARD),
       m_rebinAlgorithmDialogProvider(this),
-      m_rebinnedWorkspaceIdentifier("_tempvsi"), m_colorMapEditorPanel(NULL),
+      m_rebinnedWorkspaceIdentifier("_tempvsi"), m_colorMapEditorPanel(nullptr),
       m_gridAxesStartUpOn(true), m_allViews() {
   // this will initialize the ParaView application if needed.
   VatesParaViewApplication::instance();
@@ -194,7 +196,7 @@ MdViewerWidget::MdViewerWidget(QWidget *parent)
   // We're in the standalone application mode
   this->internalSetup(false);
   this->setupUiAndConnections();
-  this->setupMainView();
+  this->setupMainView(ModeControlWidget::STANDARD);
 }
 
 MdViewerWidget::~MdViewerWidget() {}
@@ -208,7 +210,7 @@ void MdViewerWidget::internalSetup(bool pMode) {
   static int widgetNumber = 0;
   this->m_widgetName = QString("MdViewerWidget%1").arg(widgetNumber++);
   this->pluginMode = pMode;
-  this->rotPointDialog = NULL;
+  this->rotPointDialog = nullptr;
   this->lodThreshold = 5.0;
   this->viewSwitched = false;
 }
@@ -241,14 +243,12 @@ void MdViewerWidget::setupUiAndConnections() {
     m_colorMapEditorPanel->setUpPanel();
   }
 
-  // this->connect(this->ui.proxiesPanel,SIGNAL(changeFinished(vtkSMProxy*)),SLOT(panelChanged()));
   QAction *temp = new QAction(this);
   pqDeleteReaction *deleteHandler = new pqDeleteReaction(temp);
   deleteHandler->connect(this->ui.propertiesPanel,
                          SIGNAL(deleteRequested(pqPipelineSource *)),
                          SLOT(deleteSource(pqPipelineSource *)));
 
-  // pqApplyBehavior* applyBehavior = new pqApplyBehavior(this);
   VsiApplyBehaviour *applyBehavior =
       new VsiApplyBehaviour(&m_colorScaleLock, this);
 
@@ -273,17 +273,17 @@ void MdViewerWidget::panelChanged() { this->currentView->renderAll(); }
  * event filter, tweaks the UI layout for the view and calls the routine that
  * sets up connections between ParaView and the main window widgets.
  */
-void MdViewerWidget::setupMainView() {
+void MdViewerWidget::setupMainView(ModeControlWidget::Views viewType) {
   // Commented this out to only use Mantid supplied readers
   // Initialize all readers available to ParaView. Now our application can load
   // all types of datasets supported by ParaView.
   // vtkSMProxyManager::GetProxyManager()->GetReaderFactory()->RegisterPrototypes("sources");
 
-  // Set the view at startup to STANDARD, the view will be changed, depending on
+  // Set the view at startup to view, the view will be changed, depending on
   // the workspace
-  this->currentView = this->createAndSetMainViewWidget(
-      this->ui.viewWidget, ModeControlWidget::STANDARD);
-  this->initialView = ModeControlWidget::STANDARD;
+  this->currentView =
+      this->createAndSetMainViewWidget(this->ui.viewWidget, viewType);
+  this->initialView = viewType;
   this->currentView->installEventFilter(this);
 
   // Create a layout to manage the view properly
@@ -475,7 +475,7 @@ void MdViewerWidget::onSwitchSources(std::string rebinnedWorkspaceName,
     // Set the splatterplot button explicitly
     this->currentView->setSplatterplot(true);
 
-    pqActiveObjects::instance().setActiveSource(NULL);
+    pqActiveObjects::instance().setActiveSource(nullptr);
     pqActiveObjects::instance().setActiveSource(rebinnedSource);
   } catch (const std::runtime_error &error) {
     g_log.warning() << error.what();
@@ -524,7 +524,7 @@ pqPipelineSource *MdViewerWidget::prepareRebinnedWorkspace(
 
   // It seems that the new source gets set as active before it is fully
   // constructed. We therefore reset it.
-  pqActiveObjects::instance().setActiveSource(NULL);
+  pqActiveObjects::instance().setActiveSource(nullptr);
   pqActiveObjects::instance().setActiveSource(newRebinnedSource);
 
   this->renderAndFinalSetup();
@@ -695,7 +695,10 @@ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType,
     this->setColorForBackground();
     this->setColorMap();
 
-    this->ui.modeControlWidget->setToStandardView();
+    if (VatesViewerInterface::PEAKS != workspaceType) {
+      resetCurrentView(workspaceType, instrumentName);
+    }
+
     this->currentView->hide();
     // Set the auto log scale state
     this->currentView->initializeColorScale();
@@ -724,20 +727,8 @@ void MdViewerWidget::renderWorkspace(QString workspaceName, int workspaceType,
   pqPipelineSource *source = this->currentView->setPluginSource(
       sourcePlugin, workspaceName, gridAxesOn);
   source->getProxy()->SetAnnotation(this->m_widgetName.toLatin1().data(), "1");
-
   this->renderAndFinalSetup();
-
-  // Reset the current view to the correct initial view
-  // Note that we can only reset if a source plugin exists.
-  // Also note that we can only reset the current view to the
-  // correct initial after calling renderAndFinalSetup. We first
-  // need to load in the current view and then switch to be inline
-  // with the current architecture.
-  if (VatesViewerInterface::PEAKS != workspaceType) {
-    resetCurrentView(workspaceType, instrumentName);
-  }
-
-  // save
+  this->currentView->show();
 }
 
 /**
@@ -870,14 +861,12 @@ MdViewerWidget::checkViewAgainstWorkspace(ModeControlWidget::Views view,
   if (VatesViewerInterface::MDHW == workspaceType) {
     // Histo workspaces cannot have a splatter plot,
     if (view == ModeControlWidget::SPLATTERPLOT) {
-      g_log.notice()
-          << "The preferred initial view favours the splatterplot as initial "
-             "view, "
-          << "but an MDHisto workspace is being loaded. An MDHisto workspace "
-          << "cannot be loaded into a splatterplot view. Defaulted to standard "
-             "view. \n";
-
-      selectedView = ModeControlWidget::STANDARD;
+      g_log.notice("The preferred initial view favours the splatterplot "
+                   "as initial view, but an MDHisto workspace is being "
+                   "loaded. A MDHisto workspace cannot be loaded into a "
+                   "splatterplot view. Defaulted to MultiSlice view.");
+
+      selectedView = ModeControlWidget::MULTISLICE;
     } else {
       selectedView = view;
     }
@@ -892,12 +881,15 @@ MdViewerWidget::checkViewAgainstWorkspace(ModeControlWidget::Views view,
  * This function performs setup for the plugin mode of the Vates Simple
  * Interface. It calls a number of defined functions to complete the process.
  */
-void MdViewerWidget::setupPluginMode() {
+void MdViewerWidget::setupPluginMode(int WsType,
+                                     const std::string &instrumentName) {
   // Don't use the current color map at start up.
   this->useCurrentColorSettings = false;
   this->setupUiAndConnections();
   this->createMenus();
-  this->setupMainView();
+  ModeControlWidget::Views initialView =
+      this->getInitialView(WsType, instrumentName);
+  this->setupMainView(initialView);
 }
 
 /**
@@ -1146,7 +1138,7 @@ void MdViewerWidget::setColorForBackground() {
 void MdViewerWidget::checkForUpdates() {
   Mantid::VATES::ColorScaleLockGuard colorScaleLockGuard(&m_colorScaleLock);
   pqPipelineSource *src = pqActiveObjects::instance().activeSource();
-  if (NULL == src) {
+  if (!src) {
     return;
   }
   vtkSMProxy *proxy = src->getProxy();
@@ -1242,10 +1234,7 @@ void MdViewerWidget::swapViews() {
   if (!this->hiddenView)
     g_log.error(
         "Inconsistency found when swapping views, the next view is NULL");
-
-  ViewBase *temp = this->currentView;
-  this->currentView = this->hiddenView;
-  this->hiddenView = temp;
+  std::swap(this->currentView, this->hiddenView);
 }
 
 /**
@@ -1390,7 +1379,7 @@ void MdViewerWidget::onLodToggled(bool state) {
  * setting the communication between it and the current view.
  */
 void MdViewerWidget::onRotationPoint() {
-  if (NULL == this->rotPointDialog) {
+  if (!this->rotPointDialog) {
     this->rotPointDialog = new RotationPointDialog(this);
     this->connectRotationPointDialog();
   }
@@ -1414,9 +1403,10 @@ void MdViewerWidget::onWikiHelp() {
  * switch view since the connection to the current view is destroyed.
  */
 void MdViewerWidget::disconnectDialogs() {
-  if (NULL != this->rotPointDialog) {
+  if (this->rotPointDialog) {
     this->rotPointDialog->close();
-    QObject::disconnect(this->rotPointDialog, 0, this->currentView, 0);
+    QObject::disconnect(this->rotPointDialog, nullptr, this->currentView,
+                        nullptr);
   }
 }
 
@@ -1455,7 +1445,7 @@ void MdViewerWidget::connectColorSelectionWidget() {
  * the current view.
  */
 void MdViewerWidget::connectRotationPointDialog() {
-  if (NULL != this->rotPointDialog) {
+  if (this->rotPointDialog) {
     QObject::connect(
         this->rotPointDialog, SIGNAL(sendCoordinates(double, double, double)),
         this->currentView, SLOT(onResetCenterToPoint(double, double, double)));
@@ -1496,7 +1486,7 @@ void MdViewerWidget::afterReplaceHandle(
     const boost::shared_ptr<Mantid::API::Workspace> ws) {
   UNUSED_ARG(ws);
   pqPipelineSource *src = this->currentView->hasWorkspace(wsName.c_str());
-  if (NULL != src) {
+  if (src) {
     // Have to mark the filter as modified to get it to update. Do this by
     // changing the requested workspace name to a dummy name and then change
     // back. However, push the change all the way down for it to work.
@@ -1526,7 +1516,7 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName,
   UNUSED_ARG(ws);
 
   pqPipelineSource *src = this->currentView->hasWorkspace(wsName.c_str());
-  if (NULL != src) {
+  if (src) {
     long long numSources = this->currentView->getNumSources();
     if (numSources > 1) {
       pqObjectBuilder *builder =
@@ -1680,22 +1670,22 @@ void MdViewerWidget::saveViewState(ViewBase *view) {
   switch (vtype) {
   case ModeControlWidget::Views::STANDARD: {
     m_allViews.stateStandard.TakeReference(
-        view->getView()->getRenderViewProxy()->SaveXMLState(NULL));
+        view->getView()->getRenderViewProxy()->SaveXMLState(nullptr));
   } break;
   case ModeControlWidget::Views::THREESLICE: {
     m_allViews.stateThreeSlice.TakeReference(
-        view->getView()->getRenderViewProxy()->SaveXMLState(NULL));
+        view->getView()->getRenderViewProxy()->SaveXMLState(nullptr));
   } break;
   case ModeControlWidget::Views::MULTISLICE: {
     m_allViews.stateMulti.TakeReference(
-        view->getView()->getRenderViewProxy()->SaveXMLState(NULL));
+        view->getView()->getRenderViewProxy()->SaveXMLState(nullptr));
   } break;
   case ModeControlWidget::Views::SPLATTERPLOT: {
     m_allViews.stateSplatter.TakeReference(
-        view->getView()->getRenderViewProxy()->SaveXMLState(NULL));
+        view->getView()->getRenderViewProxy()->SaveXMLState(nullptr));
   } break;
   default:
-    view = NULL;
+    view = nullptr;
     break;
   }
 }
@@ -1719,25 +1709,25 @@ void MdViewerWidget::restoreViewState(ViewBase *view,
   case ModeControlWidget::STANDARD: {
     if (m_allViews.stateStandard)
       loaded = view->getView()->getRenderViewProxy()->LoadXMLState(
-          m_allViews.stateStandard.GetPointer(), NULL);
+          m_allViews.stateStandard.GetPointer(), nullptr);
   } break;
   case ModeControlWidget::THREESLICE: {
     if (m_allViews.stateThreeSlice)
       loaded = view->getView()->getRenderViewProxy()->LoadXMLState(
-          m_allViews.stateThreeSlice.GetPointer(), NULL);
+          m_allViews.stateThreeSlice.GetPointer(), nullptr);
   } break;
   case ModeControlWidget::MULTISLICE: {
     if (m_allViews.stateMulti)
       loaded = view->getView()->getRenderViewProxy()->LoadXMLState(
-          m_allViews.stateMulti.GetPointer(), NULL);
+          m_allViews.stateMulti.GetPointer(), nullptr);
   } break;
   case ModeControlWidget::SPLATTERPLOT: {
     if (m_allViews.stateSplatter)
       loaded = view->getView()->getRenderViewProxy()->LoadXMLState(
-          m_allViews.stateSplatter.GetPointer(), NULL);
+          m_allViews.stateSplatter.GetPointer(), nullptr);
   } break;
   default:
-    view = NULL;
+    view = nullptr;
     break;
   }
 
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp
index 2fae62b53d082009d75e396bd2c6892e60dcef0d..01733d8a31924e820989cc5f08782eabf991919b 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/MultisliceView.cpp
@@ -100,6 +100,9 @@ void MultiSliceView::setupData() {
 
 void MultiSliceView::render() {
   this->origSrc = pqActiveObjects::instance().activeSource();
+  if (this->origSrc == nullptr) {
+    return;
+  }
   this->checkSliceViewCompat();
   this->setupData();
   this->resetDisplay();
@@ -152,7 +155,7 @@ void MultiSliceView::checkSliceClicked(int axisIndex, double sliceOffsetOnAxis,
 void MultiSliceView::checkSliceViewCompat() {
   QString wsName = this->getWorkspaceName();
   if (wsName.isEmpty()) {
-    QObject::disconnect(this->m_mainView, 0, this, 0);
+    QObject::disconnect(this->m_mainView, nullptr, this, nullptr);
   }
 }
 
@@ -180,8 +183,8 @@ void MultiSliceView::showCutInSliceViewer(int axisIndex,
   pqServerManagerModel *smModel =
       pqApplicationCore::instance()->getServerManagerModel();
   QList<pqPipelineSource *> srcs = smModel->findItems<pqPipelineSource *>();
-  pqPipelineSource *src1 = NULL;
-  pqPipelineSource *src2 = NULL;
+  pqPipelineSource *src1 = nullptr;
+  pqPipelineSource *src2 = nullptr;
   foreach (pqPipelineSource *src, srcs) {
     const QString name(src->getProxy()->GetXMLName());
 
@@ -204,7 +207,7 @@ void MultiSliceView::showCutInSliceViewer(int axisIndex,
     geomXML = std::string(inGeomXML);
   }
 
-  if (NULL != src2) {
+  if (src2) {
     // Need to see if scaling is applied to axis
     QString scalingProperty("Scaling Factor");
     switch (axisIndex) {
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp
index e6a938464d4a18ff5e24302bc3f405f6ed72f2d4..13d5fe01600c3e3844d95ae6d26c075ff2613720 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp
@@ -73,7 +73,7 @@ PeaksTableControllerVsi::PeaksTableControllerVsi(
     boost::shared_ptr<CameraManager> cameraManager, QWidget *parent)
     : QWidget(parent), m_cameraManager(cameraManager),
       m_presenter(new Mantid::VATES::CompositePeaksPresenterVsi()),
-      m_peaksTabWidget(NULL), m_peakMarker(NULL),
+      m_peaksTabWidget(nullptr), m_peakMarker(nullptr),
       m_coordinateSystem(Mantid::Kernel::SpecialCoordinateSystem::QLab) {
   m_peakTransformSelector.registerCandidate(
       boost::make_shared<Mantid::Geometry::PeakTransformHKLFactory>());
@@ -376,9 +376,9 @@ void PeaksTableControllerVsi::createTable() {
 */
 void PeaksTableControllerVsi::removeLayout(QWidget *widget) {
   QLayout *layout = widget->layout();
-  if (layout != 0) {
+  if (layout) {
     QLayoutItem *item;
-    while ((item = layout->takeAt(0)) != 0) {
+    while ((item = layout->takeAt(0))) {
       layout->removeItem(item);
       delete item->widget();
     }
@@ -397,7 +397,7 @@ void PeaksTableControllerVsi::removeTable() {
   if (m_peaksTabWidget) {
     m_peaksTabWidget->deleteLater();
   }
-  m_peaksTabWidget = NULL;
+  m_peaksTabWidget = nullptr;
 }
 
 /**
@@ -486,14 +486,16 @@ void PeaksTableControllerVsi::destroySinglePeakSource() {
         pqApplicationCore::instance()->getObjectBuilder();
     builder->destroy(m_peakMarker);
 
-    m_peakMarker = NULL;
+    m_peakMarker = nullptr;
   }
 }
 
 /**
  * On Single Peak Marker destroyed
  */
-void PeaksTableControllerVsi::onPeakMarkerDestroyed() { m_peakMarker = NULL; }
+void PeaksTableControllerVsi::onPeakMarkerDestroyed() {
+  m_peakMarker = nullptr;
+}
 
 /**
  * Reset the single peak source
@@ -646,4 +648,4 @@ void PeaksTableControllerVsi::setPeakSourceColorToDefault() {
 }
 }
 }
-}
\ No newline at end of file
+}
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
index 2b9772410455b7693c23bdb0df491f38c09fe1da..88896543cc26305f12fad85ea99372ec865b0340 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
@@ -5,6 +5,7 @@
 #include "MantidQtMantidWidgets/SlicingAlgorithmDialog.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidAPI/IMDWorkspace.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
 #include "MantidKernel/Logger.h"
 
 // Have to deal with ParaView warnings and Intel compiler the hard way.
@@ -131,7 +132,7 @@ MantidQt::API::AlgorithmDialog *RebinAlgorithmDialogProvider::createDialog(
   // This is an optional message displayed at the top of the GUI.
   QString optional_msg(algorithm->summary().c_str());
 
-  MantidQt::API::AlgorithmDialog *dialog = NULL;
+  MantidQt::API::AlgorithmDialog *dialog = nullptr;
 
   MantidQt::API::InterfaceManager interfaceManager;
   presets.insert(m_lblInputWorkspace, QString::fromStdString(inputWorkspace));
@@ -145,7 +146,7 @@ MantidQt::API::AlgorithmDialog *RebinAlgorithmDialogProvider::createDialog(
   dialog->setAttribute(Qt::WA_DeleteOnClose, true);
 
   // Set the QDialog window flags to ensure the dialog ends up on top
-  Qt::WindowFlags flags = 0;
+  Qt::WindowFlags flags = nullptr;
   flags |= Qt::Dialog;
   flags |= Qt::WindowContextHelpButtonHint;
   dialog->setWindowFlags(flags);
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
index 087483d000e55f74c841a8e6eb8fede2aac7e534..083c83c20cadcc780376d9c15c0931387d89300e 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
@@ -48,7 +48,7 @@ Mantid::Kernel::Logger g_log("RebinnedSourcesManager");
 
 RebinnedSourcesManager::RebinnedSourcesManager(QWidget *parent)
     : QWidget(parent), m_tempPostfix("_rebinned_vsi"), m_tempPrefix(""),
-      m_inputSource(NULL), m_rebinnedSource(NULL) {
+      m_inputSource(nullptr), m_rebinnedSource(nullptr) {
   observeAdd();
   observeAfterReplace();
   observePreDelete();
@@ -380,8 +380,8 @@ void RebinnedSourcesManager::processWorkspaceNames(std::string &inputWorkspace,
   // duration of the rebinning itself
   m_newWorkspacePairBuffer.clear();
   m_newRebinnedWorkspacePairBuffer.clear();
-  m_inputSource = NULL;
-  m_rebinnedSource = NULL;
+  m_inputSource = nullptr;
+  m_rebinnedSource = nullptr;
 
   // If the workspace is the original workspace or it is a freshly loaded, i.e.
   // it is not being tracked
@@ -445,10 +445,9 @@ void RebinnedSourcesManager::rebuildPipeline(pqPipelineSource *source1,
   pqPipelineSource *endOfSource2Pipeline = source2;
 
   while (filter1) {
-    vtkSMProxy *proxy1 = NULL;
-    proxy1 = filter1->getProxy();
-    pqPipelineSource *newPipelineElement = NULL;
-    pqPipelineFilter *newFilter = NULL;
+    vtkSMProxy *proxy1 = filter1->getProxy();
+    pqPipelineSource *newPipelineElement = nullptr;
+    pqPipelineFilter *newFilter = nullptr;
     // Move source2 to its end.
     while (endOfSource2Pipeline->getNumberOfConsumers() > 0) {
       endOfSource2Pipeline = endOfSource2Pipeline->getConsumer(0);
@@ -471,7 +470,7 @@ void RebinnedSourcesManager::rebuildPipeline(pqPipelineSource *source1,
     if (filter1->getNumberOfConsumers() > 0) {
       filter1 = qobject_cast<pqPipelineFilter *>(filter1->getConsumer(0));
     } else {
-      filter1 = NULL;
+      filter1 = nullptr;
     }
   }
   emit triggerAcceptForNewFilters();
@@ -538,11 +537,11 @@ void RebinnedSourcesManager::copySafe(vtkSMProxy *dest, vtkSMProxy *source) {
       }
 
       vtkSMProxy *srcValue = srcPP->GetProxy(0);
-      vtkSMProxy *destValue = NULL;
+      vtkSMProxy *destValue = nullptr;
 
       // find srcValue type in destPLD and that's the proxy to use as destValue.
       for (unsigned int cc = 0;
-           srcValue != NULL && cc < destPLD->GetNumberOfProxyTypes(); cc++) {
+           srcValue != nullptr && cc < destPLD->GetNumberOfProxyTypes(); cc++) {
         if (srcValue->GetXMLName() && destPLD->GetProxyName(cc) &&
             strcmp(srcValue->GetXMLName(), destPLD->GetProxyName(cc)) == 0 &&
             srcValue->GetXMLGroup() && destPLD->GetProxyGroup(cc) &&
@@ -756,7 +755,7 @@ RebinnedSourcesManager::createKeyPairForSource(pqPipelineSource *source) {
  * @param source A pointer to the source
  */
 void RebinnedSourcesManager::deleteSpecificSource(pqPipelineSource *source) {
-  if (NULL != source) {
+  if (source) {
     // Go to the end of the source and work your way back
     pqPipelineSource *tempSource = source;
 
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/SaveScreenshotReaction.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/SaveScreenshotReaction.cpp
index b857e53c80fa8820a9a91ddc5516937d5a83fdee..070e48766ed71f9d84568e82dd36e18b19ece5c1 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/SaveScreenshotReaction.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/SaveScreenshotReaction.cpp
@@ -81,7 +81,7 @@ void SaveScreenshotReaction::saveScreenshot() {
   filters += ";;PPM image (*.ppm)";
   filters += ";;JPG image (*.jpg)";
   filters += ";;PDF file (*.pdf)";
-  pqFileDialog file_dialog(NULL, pqCoreUtilities::mainWidget(),
+  pqFileDialog file_dialog(nullptr, pqCoreUtilities::mainWidget(),
                            tr("Save Screenshot:"), QString(), filters);
   file_dialog.setRecentlyUsedExtension(lastUsedExt);
   file_dialog.setObjectName("FileSaveScreenshotDialog");
@@ -141,7 +141,7 @@ void SaveScreenshotReaction::saveScreenshot(const QString &filename,
     img.TakeReference(view->captureImage(size));
   }
 
-  if (img.GetPointer() == NULL) {
+  if (!img.GetPointer()) {
     qCritical() << "Save Image failed.";
   } else {
     pqImageUtil::saveImage(img, filename, quality);
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
index 4367004587f984212afe44c9b7c5dadb33dab3f6..47a60d93ff021a383852d395b56680824370cfcd 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
@@ -59,7 +59,7 @@ SplatterPlotView::SplatterPlotView(
     bool createRenderProxy)
     : ViewBase(parent, rebinnedSourcesManager),
       m_cameraManager(boost::make_shared<CameraManager>()),
-      m_peaksTableController(NULL), m_peaksWorkspaceNameDelimiter(";") {
+      m_peaksTableController(nullptr), m_peaksWorkspaceNameDelimiter(";") {
   this->m_noOverlay = false;
   this->m_ui.setupUi(this);
 
@@ -131,14 +131,13 @@ void SplatterPlotView::destroyView() {
 pqRenderView *SplatterPlotView::getView() { return this->m_view.data(); }
 
 void SplatterPlotView::render() {
-  pqPipelineSource *src = NULL;
-  src = pqActiveObjects::instance().activeSource();
+  pqPipelineSource *src = pqActiveObjects::instance().activeSource();
   bool isPeaksWorkspace = this->isPeaksWorkspace(src);
   // Hedge for two things.
   // 1. If there is no active source
   // 2. If we are loading a peak workspace without haveing
   //    a splatterplot source in place
-  bool isBadInput = !src || (isPeaksWorkspace && this->m_splatSource == NULL);
+  bool isBadInput = !src || (isPeaksWorkspace && !this->m_splatSource);
   if (isBadInput) {
     g_log.warning() << "SplatterPlotView: Could not render source. You are "
                        "either loading an active source "
@@ -151,7 +150,7 @@ void SplatterPlotView::render() {
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
 
   // Do not allow overplotting of MDWorkspaces
-  if (!this->isPeaksWorkspace(src) && NULL != this->m_splatSource) {
+  if (!this->isPeaksWorkspace(src) && this->m_splatSource) {
     QMessageBox::warning(this, QApplication::tr("Overplotting Warning"),
                          QApplication::tr("SplatterPlot mode does not allow "
                                           "more that one MDEventWorkspace to "
@@ -303,8 +302,8 @@ void SplatterPlotView::checkView(ModeControlWidget::Views initialView) {
 void SplatterPlotView::onPickModeToggled(bool state) {
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
   if (state) {
-    pqPipelineSource *src = NULL;
-    if (NULL != this->m_threshSource) {
+    pqPipelineSource *src = nullptr;
+    if (this->m_threshSource) {
       src = this->m_threshSource;
     } else {
       src = this->m_splatSource;
@@ -351,7 +350,7 @@ void SplatterPlotView::readAndSendCoordinates() {
   vtkSMDoubleVectorProperty *coords =
       vtkSMDoubleVectorProperty::SafeDownCast(pList[0]->GetProperty("Center"));
 
-  if (NULL != coords) {
+  if (coords) {
     // Get coordinate type
     int peakViewCoords =
         vtkSMPropertyHelper(
@@ -622,7 +621,7 @@ void SplatterPlotView::updatePeaksFilter(pqPipelineSource *filter) {
  * We need to do this, since PV can destroy the filter in a general
  * destorySources command.
  */
-void SplatterPlotView::onPeaksFilterDestroyed() { m_peaksFilter = NULL; }
+void SplatterPlotView::onPeaksFilterDestroyed() { m_peaksFilter = nullptr; }
 
 /**
  * Destroy all sources in the splatterplot view. We need to delete the filters
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
index e2e0f9985cc7deb6a745679cb571c53bfec8dff1..c3978bab05aab7a48695efab05a5870df0bbd79e 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
@@ -93,8 +93,8 @@ QMap<QString, QString> StandardView::g_actionToAlgName;
 StandardView::StandardView(QWidget *parent,
                            RebinnedSourcesManager *rebinnedSourcesManager,
                            bool createRenderProxy)
-    : ViewBase(parent, rebinnedSourcesManager), m_binMDAction(NULL),
-      m_sliceMDAction(NULL), m_cutMDAction(NULL), m_unbinAction(NULL) {
+    : ViewBase(parent, rebinnedSourcesManager), m_binMDAction(nullptr),
+      m_sliceMDAction(nullptr), m_cutMDAction(nullptr), m_unbinAction(nullptr) {
   this->m_ui.setupUi(this);
   this->m_cameraReset = false;
 
@@ -112,6 +112,10 @@ StandardView::StandardView(QWidget *parent,
   QObject::connect(this->m_ui.cutButton, SIGNAL(clicked()), this,
                    SLOT(onCutButtonClicked()));
 
+  // Set the cut button to create a slice on the data
+  QObject::connect(this->m_ui.thresholdButton, SIGNAL(clicked()), this,
+                   SLOT(onThresholdButtonClicked()));
+
   // Listen to a change in the active source, to adapt our rebin buttons
   QObject::connect(&pqActiveObjects::instance(),
                    SIGNAL(sourceChanged(pqPipelineSource *)), this,
@@ -175,6 +179,7 @@ void StandardView::setupViewButtons() {
 void StandardView::destroyView() {
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
   this->destroyFilter(QString("Slice"));
+  this->destroyFilter(QString("Threshold"));
   builder->destroy(this->m_view);
 }
 
@@ -182,7 +187,7 @@ pqRenderView *StandardView::getView() { return this->m_view.data(); }
 
 void StandardView::render() {
   this->origSrc = pqActiveObjects::instance().activeSource();
-  if (NULL == this->origSrc) {
+  if (!this->origSrc) {
     return;
   }
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
@@ -227,6 +232,21 @@ void StandardView::onCutButtonClicked() {
   setVisibilityListener();
 }
 
+void StandardView::onThresholdButtonClicked() {
+  // check that has active source
+  if (!hasActiveSource()) {
+    return;
+  }
+
+  // Apply cut to currently viewed data
+  pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+  builder->createFilter("filters", "Threshold", this->getPvActiveSrc());
+
+  // We need to attach the visibility listener to the newly
+  // created filter, this is required for automatic updating the color scale
+  setVisibilityListener();
+}
+
 void StandardView::onScaleButtonClicked() {
   // check that has active source
   if (!hasActiveSource()) {
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/ThreesliceView.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/ThreesliceView.cpp
index 15d062155e4fa13ed01a06ff27993d0794ab77c1..1dffe55dc37c844f46dac95510faa3679c126dcb 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/ThreesliceView.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/ThreesliceView.cpp
@@ -66,9 +66,7 @@ void ThreeSliceView::render() {
 }
 
 void ThreeSliceView::makeThreeSlice() {
-  pqPipelineSource *src = NULL;
-  src = pqActiveObjects::instance().activeSource();
-
+  pqPipelineSource *src = pqActiveObjects::instance().activeSource();
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
 
   // Do not allow overplotting PeaksWorkspaces
@@ -85,6 +83,10 @@ void ThreeSliceView::makeThreeSlice() {
 
   this->origSrc = src;
 
+  if (this->origSrc == nullptr) {
+    return;
+  }
+
   pqDataRepresentation *drep = builder->createDataRepresentation(
       this->origSrc->getOutputPort(0), this->m_mainView);
   vtkSMPropertyHelper(drep->getProxy(), "Representation").Set("Slices");
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/VatesParaViewApplication.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/VatesParaViewApplication.cpp
index 5eb8c041d5852451ed38f5cbfe39423319210984..cfd41fc7c1d996a0477b60bd2cce743b5533dc85 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/VatesParaViewApplication.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/VatesParaViewApplication.cpp
@@ -114,7 +114,7 @@ VatesParaViewApplication::~VatesParaViewApplication() {}
 
 VatesParaViewApplication *VatesParaViewApplication::instance() {
   static QPointer<VatesParaViewApplication> arg;
-  if (arg == NULL) {
+  if (!arg) {
     arg = new VatesParaViewApplication();
   }
   return arg;
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
index 6e3d0b27f74f100d0bc73a86afcb8e21b2987657..2299bffce5e5f877cf7ac6450b91792f29b20a79 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
@@ -67,7 +67,7 @@ ViewBase::ViewBase(QWidget *parent,
                    RebinnedSourcesManager *rebinnedSourcesManager)
     : QWidget(parent), m_rebinnedSourcesManager(rebinnedSourcesManager),
       m_internallyRebinnedWorkspaceIdentifier("rebinned_vsi"),
-      m_colorScaleLock(NULL) {}
+      m_colorScaleLock(nullptr) {}
 
 /**
  * This function creates a single standard ParaView view instance.
@@ -155,7 +155,7 @@ void ViewBase::clearRenderLayout(QFrame *frame) {
   QLayout *layout = frame->layout();
   if (layout) {
     QLayoutItem *item;
-    while ((item = layout->takeAt(0)) != nullptr)
+    while ((item = layout->takeAt(0)))
       layout->removeItem(item);
     delete layout;
   }
@@ -167,7 +167,7 @@ void ViewBase::clearRenderLayout(QFrame *frame) {
  */
 void ViewBase::onColorMapChange(const Json::Value &model) {
   pqPipelineRepresentation *rep = this->getRep();
-  if (NULL == rep) {
+  if (!rep) {
     return;
   }
   // Work around a "bug" in pqScalarToColors::checkRange() where the lower
@@ -252,7 +252,7 @@ void ViewBase::setColorsForView(ColorSelectionWidget *colorScale) {
  * @return true if the pipeline source is derived from PeaksWorkspace
  */
 bool ViewBase::isPeaksWorkspace(pqPipelineSource *src) {
-  if (NULL == src) {
+  if (!src) {
     return false;
   }
   QString wsType(vtkSMPropertyHelper(src->getProxy(), "WorkspaceTypeName", true)
@@ -433,7 +433,7 @@ long long ViewBase::getNumSources() {
  * @param dvp the vector property containing the "time" information
  */
 void ViewBase::handleTimeInfo(vtkSMDoubleVectorProperty *dvp) {
-  if (NULL == dvp) {
+  if (!dvp) {
     // This is a normal filter and therefore has no timesteps.
     // qDebug() << "No timestep vector, returning.";
     return;
@@ -584,7 +584,7 @@ void ViewBase::closeSubWindows() {}
  */
 pqPipelineRepresentation *ViewBase::getRep() {
   pqPipelineRepresentation *rep = this->getPvActiveRep();
-  if (NULL == rep) {
+  if (!rep) {
     rep = this->origRep;
   }
   return rep;
@@ -595,7 +595,7 @@ pqPipelineRepresentation *ViewBase::getRep() {
  * @return true if the source is a MDHistoWorkspace
  */
 bool ViewBase::isMDHistoWorkspace(pqPipelineSource *src) {
-  if (NULL == src) {
+  if (!src) {
     return false;
   }
   QString wsType(vtkSMPropertyHelper(src->getProxy(), "WorkspaceTypeName", true)
@@ -613,7 +613,7 @@ bool ViewBase::isMDHistoWorkspace(pqPipelineSource *src) {
  * @return true if the source is an internally rebinned workspace;
  */
 bool ViewBase::isInternallyRebinnedWorkspace(pqPipelineSource *src) {
-  if (NULL == src) {
+  if (!src) {
     return false;
   }
 
@@ -691,7 +691,7 @@ pqPipelineSource *ViewBase::hasWorkspace(const QString &name) {
       }
     }
   }
-  return NULL;
+  return nullptr;
 }
 
 /**
@@ -887,7 +887,7 @@ void ViewBase::setAxesGrid(bool on) {
  * Check if there is an active source available
  * @returns true if there is an active source else false
  */
-bool ViewBase::hasActiveSource() { return this->getPvActiveSrc() != nullptr; }
+bool ViewBase::hasActiveSource() { return this->getPvActiveSrc(); }
 
 } // namespace SimpleGui
 } // namespace Vates
diff --git a/Vates/VatesSimpleGui/ViewWidgets/src/VsiApplyBehaviour.cpp b/Vates/VatesSimpleGui/ViewWidgets/src/VsiApplyBehaviour.cpp
index 85a885c4f2cc26465a52a23edddd99ef6dbc9ffa..6425e47246fe38b1395245ec021b2fa5514d3d09 100644
--- a/Vates/VatesSimpleGui/ViewWidgets/src/VsiApplyBehaviour.cpp
+++ b/Vates/VatesSimpleGui/ViewWidgets/src/VsiApplyBehaviour.cpp
@@ -6,11 +6,7 @@ namespace SimpleGui {
 
 VsiApplyBehaviour::VsiApplyBehaviour(Mantid::VATES::ColorScaleLock *lock,
                                      QObject *parent)
-    : pqApplyBehavior(parent), m_colorScaleLock(NULL) {
-  if (lock != NULL) {
-    m_colorScaleLock = lock;
-  }
-}
+    : pqApplyBehavior(parent), m_colorScaleLock(lock) {}
 
 /**
  * Forward the register request
@@ -30,14 +26,14 @@ void VsiApplyBehaviour::unregisterPanel(pqPropertiesPanel *panel) {
 /// React to the apply button press. We forward the request, but we add a lock
 void VsiApplyBehaviour::applied(pqPropertiesPanel *, pqProxy *pqproxy) {
   Mantid::VATES::ColorScaleLockGuard colorScaleLockGuard(m_colorScaleLock);
-  this->pqApplyBehavior::applied(NULL, pqproxy);
+  this->pqApplyBehavior::applied(nullptr, pqproxy);
 }
 
 /// React to the apply button press. We forward the request, but we add a lock
 void VsiApplyBehaviour::applied(pqPropertiesPanel *) {
   Mantid::VATES::ColorScaleLockGuard colorScaleLockGuard(m_colorScaleLock);
-  this->pqApplyBehavior::applied(NULL);
+  this->pqApplyBehavior::applied(nullptr);
+}
 }
 }
 }
-}
\ No newline at end of file
diff --git a/buildconfig/dev-packages/deb/mantid-developer/ns-control b/buildconfig/dev-packages/deb/mantid-developer/ns-control
index e23b3457d014603c4415c83ba03667a110d9d841..0746b425c920c2df033f04ed3fdda7fe6a917e06 100644
--- a/buildconfig/dev-packages/deb/mantid-developer/ns-control
+++ b/buildconfig/dev-packages/deb/mantid-developer/ns-control
@@ -3,12 +3,18 @@ Priority: optional
 Standards-Version: 3.9.2
 
 Package: mantid-developer
-Version: 1.2.8
-Maintainer: Mantid Project <mantid-help@mantidproject.org>
+Version: 1.2.9
+Maintainer: Mantid Project <mantid-tech@mantidproject.org>
 Priority: optional
 Architecture: all
-Depends: g++, git, clang, cmake-qt-gui(>=2.8.12), qt4-qmake, qt4-dev-tools, libqtwebkit-dev, libqt4-dbg, libpoco-dev(>=1.4.6), libboost-all-dev, libboost-dbg, libnexus0-dev, libgoogle-perftools-dev, libqwt5-qt4-dev, libqwtplot3d-qt4-dev, python-qt4-dev, libgsl0-dev, liboce-visualization-dev, libmuparser-dev, python-numpy, libssl-dev, libqscintilla2-dev, texlive,texlive-latex-extra, dvipng, libhdf4-dev, doxygen, python-sphinx, python-scipy, ipython-qtconsole (>=1.2.0), libhdf5-dev, libhdf4-dev, libpococrypto11-dbg, libpocodata11-dbg, libpocofoundation11-dbg, libpocomysql11-dbg, libpoconet11-dbg, libpoconetssl11-dbg, libpocoodbc11-dbg, libpocosqlite11-dbg, libpocoutil11-dbg, libpocoxml11-dbg, libpocozip11-dbg, python-qt4-dbg, qt4-default, ninja-build, libjsoncpp-dev(>=0.7.0), python-dateutil, python-sphinx-bootstrap-theme, graphviz, python-matplotlib, python-h5py, python-yaml
-Architecture: all
+Depends: git, g++, clang-format-3.6, cmake-qt-gui(>=3.5), ninja-build, libtbb-dev, libgoogle-perftools-dev, libboost-all-dev, libboost-dbg,
+  libpoco-dev(>=1.4.6), libpococrypto31-dbg, libpocodata31-dbg, libpocofoundation31-dbg, libpocomysql31-dbg, libpoconet31-dbg, libpoconetssl31-dbg,
+  libpocoodbc31-dbg, libpocosqlite31-dbg, libpocoutil31-dbg, libpocoxml31-dbg, libpocozip31-dbg, libnexus0-dev,
+  libhdf5-dev, libhdf4-dev, libgsl0-dev, liboce-visualization-dev, libmuparser-dev, libssl-dev, libjsoncpp-dev(>=0.7.0),
+  libpython-dev, python-numpy, python-scipy, python-qt4-dev, python-qt4-dbg, python-sphinx, python-dateutil,
+  python-sphinx-bootstrap-theme, python-matplotlib, python-h5py, python-yaml, ipython-qtconsole (>=1.2.0),
+  qt4-default, qt4-qmake, qt4-dev-tools, libqtwebkit-dev, libqwt5-qt4-dev, libqwtplot3d-qt4-dev, libqscintilla2-dev,
+  texlive, texlive-latex-extra, dvipng, graphviz, doxygen
 Description: Installs all packages required for a Mantid developer
  A metapackage which requires all the dependencies and tools that are
  required for Mantid development. It works for Ubuntu versions 14.04 and 16.04
diff --git a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
index 8f3a05d7d27ee3d617f330b55f951ce88d0f9d74..eb89bb31aec3a30e2a014477692817967ed9a0d7 100644
--- a/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
+++ b/docs/source/algorithms/CollectHB3AExperimentInfo-v1.rst
@@ -82,7 +82,7 @@ Output:
 
   Number of input files = 2
   Number of detectors in virtual instrument = 131072
-  Virtual detectors are from ID = 1 to ID = 131072
+  Virtual detectors are from ID = 0 to ID = 131070
 
 .. categories::
 
diff --git a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
index e3733cb4093c4169d19fd45d8bd4494479805a12..319715c4f232bc17fa8536e8c146b430311c2124 100644
--- a/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
+++ b/docs/source/algorithms/ConvertCWSDExpToMomentum-v1.rst
@@ -190,7 +190,7 @@ Output:
 
   Output MDEventWorkspace has 397 events.
   There are 1 peaks found in output MDWorkspace
-  In Q-sample frame, center of peak 0 is at (-6.93624, -0.08360, 8.16733) at detector with ID 35724
+  In Q-sample frame, center of peak 0 is at (-6.93624, -0.08360, 8.16733) at detector with ID 35723
 
 **Example - convert an HB3A experiment to MDEventWorkspace by copying instrument.:**
 
@@ -234,7 +234,7 @@ Output:
 
   Output MDEventWorkspace has 397 events.
   There are 1 peaks found in output MDWorkspace
-  In Q-sample frame, center of peak 0 is at (-3.58246, -4.40803, -3.06320) at detector with ID 29057
+  In Q-sample frame, center of peak 0 is at (-3.58246, -4.40802, -3.06320) at detector with ID 32881
 
 .. categories::
 
diff --git a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
index 219f648c8b5f9c388fa5ba5e4701471bcece86fc..68f44b314a3617cd0899c5a6a354270e5b45741d 100644
--- a/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
+++ b/docs/source/algorithms/ConvertCWSDMDtoHKL-v1.rst
@@ -9,7 +9,7 @@
 Description
 -----------
 
-This algorithms is to convert an MDEventWorkspace in Q-sample coordinate 
+This algorithms is to convert an MDEventWorkspace in Q-sample coordinate
 to HKL coordindate for a reactor-based four-circle single crystal diffractometer.
 Meanwhile, the algorithm is able to export the MDEvents to file.
 
@@ -26,20 +26,20 @@ Inputs
 
 **InputWorkspace** is an MDEventWorkspace ???.
 
-**PeakWorkspace** is an optional input as in many cases especially after calculating UB matrix, ... 
+**PeakWorkspace** is an optional input as in many cases especially after calculating UB matrix, ...
 
-**UBMatrix** is ???. 
+**UBMatrix** is ???.
 
 
 Outputs
 #######
 
-The output is an MDEventWorkspace that... .. 
+The output is an MDEventWorkspace that... ..
 
 MDEvent
 +++++++
 
-Each MDEvent in output MDEventWorkspace contain 
+Each MDEvent in output MDEventWorkspace contain
 * *H*
 * *K*
 * *L*
@@ -61,29 +61,31 @@ Usage
 .. testcode:: ExConvertHB3AToHKL
 
   # Create input table workspaces for experiment information and virtual instrument parameters
-  CollectHB3AExperimentInfo(ExperimentNumber='406', ScanList='298', PtLists='-1,22', 
+  CollectHB3AExperimentInfo(ExperimentNumber='406', ScanList='298', PtLists='-1,22',
       DataDirectory='',
       GenerateVirtualInstrument=False,
       OutputWorkspace='ExpInfoTable', DetectorTableWorkspace='VirtualInstrumentTable')
 
   # Convert to MDWorkspace
-  ConvertCWSDExpToMomentum(InputWorkspace='ExpInfoTable', CreateVirtualInstrument=False, 
+  ConvertCWSDExpToMomentum(InputWorkspace='ExpInfoTable', CreateVirtualInstrument=False,
       OutputWorkspace='QSampleMD',
       Directory='')
-      
-  ConvertCWSDMDtoHKL(InputWorkspace='QSampleMD', 
+
+  ConvertCWSDMDtoHKL(InputWorkspace='QSampleMD',
                 UBMatrix='0.13329061, 0.07152342, -0.04215966, 0.01084569, -0.1620849, 0.0007607, -0.14018499, -0.07841385, -0.04002737',
                 OutputWorkspace='HKLMD')
-              
-  
+
+
   # Examine
   mdws = mtd['QSampleMD']
-  print 'Output MDEventWorkspace has %d events.'%(mdws.getNEvents())
-  
   hklws = mtd['HKLMD']
-  print 'H: range from %.5f to %.5f.' % (hklws.getXDimension().getMinimum(), hklws.getXDimension().getMaximum())
-  print 'K: range from %.5f to %.5f.' % (hklws.getYDimension().getMinimum(), hklws.getYDimension().getMaximum())
-  print 'L: range from %.5f to %.5f.' % (hklws.getZDimension().getMinimum(), hklws.getZDimension().getMaximum())
+  print 'Output QSample and HKL workspaces have %d and %d events.'%(mdws.getNEvents(), hklws.getNEvents())
+
+  BinMD(InputWorkspace='HKLMD', AlignedDim0='H,-0.3,0.3,60', AlignedDim1='K,-0.4,0.5,90', AlignedDim2='L,4,8,10', OutputWorkspace='BinndHKL')
+  histws = mtd['BinndHKL']
+  events_array = histws.getNumEventsArray()
+  print 'events[22, 53, 5] = %.1f' % events_array[22, 53, 5]
+  print 'events[30, 40, 5] = %.1f' % events_array[30, 40, 5]
 
 .. testcleanup::  ExConvertHB3AToHKL
 
@@ -94,14 +96,14 @@ Usage
   DeleteWorkspace(Workspace='HB3A_exp0406_scan0298')
   DeleteWorkspace(Workspace='spicematrixws')
 
+
 Output:
 
 .. testoutput:: ExConvertHB3AToHKL
 
-  Output MDEventWorkspace has 1631 events.
-  H: range from -0.26128 to 0.24943.
-  K: range from -0.35012 to 0.44396.
-  L: range from 4.96512 to 7.18855.
+  Output QSample and HKL workspaces have 1631 and 1631 events.
+  events[22, 53, 5] = 19.0
+  events[30, 40, 5] = 38.0
 
 .. categories::
 
diff --git a/docs/source/algorithms/ConvolutionFitSequential-v1.rst b/docs/source/algorithms/ConvolutionFitSequential-v1.rst
index 615c0e177f848ee0e63ad5ee31ef4b5d55361c8a..d8d8018e11e9d97d8a09e5289f1cc9fd67bb9eca 100644
--- a/docs/source/algorithms/ConvolutionFitSequential-v1.rst
+++ b/docs/source/algorithms/ConvolutionFitSequential-v1.rst
@@ -71,7 +71,7 @@ Output:
   
   Result has 2 Spectra
   
-  Amplitude 0: 4.293
+  Amplitude 0: 4.314
   Amplitude 1: 4.179
   Amplitude 2: 3.979
 
@@ -79,7 +79,7 @@ Output:
   X axis at 1: 0.72917
   X axis at 2: 0.92340
 
-  Amplitude Err 0: 0.00465
+  Amplitude Err 0: 0.00460
   Amplitude Err 1: 0.00464
   Amplitude Err 2: 0.00504
 
diff --git a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
index afdebe3f470942d0d01e5705a31979a994609740..96c7607422e589c2c6e5e8a358fd8c38dd43a6e9 100644
--- a/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
+++ b/docs/source/algorithms/CreateGroupingWorkspace-v1.rst
@@ -29,6 +29,10 @@ the detectors for the given component will be grouped into the number
 of groups specified, detectors will be left ungrouped in the event that
 the number of detectors does not divide equally into the number of groups.
 
+GroupDetectorsBy has a new option, 2_4Grouping, to create one group of 4 
+columns of SNAP detectors and another with the remaining 2 columns. This 
+grouping is used frequently in their reduction.
+
 Usage
 -----
 
diff --git a/docs/source/algorithms/EstimateFitParameters-v1.rst b/docs/source/algorithms/EstimateFitParameters-v1.rst
index 6c922476a5d32838f626d2fa9328832da5a8fe83..87afb8e80a313494a21413613940bf2895f7bb46 100644
--- a/docs/source/algorithms/EstimateFitParameters-v1.rst
+++ b/docs/source/algorithms/EstimateFitParameters-v1.rst
@@ -34,6 +34,12 @@ In this strategy a number (defined by `NSamples` property) of paramter sets are
 gives the smallest cost function is considered the winner. These best parameters are set to `Function`
 property (it has the `InOut` direction).
 
+If `OutputWorkspace` property is set then more than 1 parameter set can be output. The output workspace is 
+a table workspace in which the first column contains the names of the parameters and the subsequent columns
+have the parameter sets with the smallest cost fnction values. Below is an example of such a workspace.
+
+.. figure:: /images/EstimateFitParameters_output.png
+
 
 Cross Entropy
 #############
@@ -103,9 +109,12 @@ Usage
     
 Output:
 
+(You may see different numbers for the parameters when you run this example on your machine.)
+
 .. testoutput:: ExMonteCarloBackToBackExponential
+   :options: +ELLIPSIS, +NORMALIZE_WHITESPACE
 
-    name=BackToBackExponential,I=130.029,A=124.254,B=1.93148,X0=-1.91278,S=1.67663,constraints=(50<I<200,0.1<A<300,0.01<B<10,-5<X0<0,0.001<S<4)
+    name=BackToBackExponential,I=...,A=...,B=...,X0=...,S=...,constraints=(50<I<200,0.1<A<300,0.01<B<10,-5<X0<0,0.001<S<4)
 
 **Example 2.**
 
@@ -157,9 +166,12 @@ Output:
 
 Output:
 
+(You may see different numbers for the parameters when you run this example on your machine.)
+
 .. testoutput:: Ex2
+    :options: +ELLIPSIS, +NORMALIZE_WHITESPACE
 
-    name=BackToBackExponential,I=3.89204,A=107.646,B=57.3761,X0=0.0452285,S=1.58316,constraints=(0.01<I<200,0.001<A<300,0.001<B<300,-5<X0<5,0.001<S<4),ties=(A=107.645731,B=57.376105)
+    name=BackToBackExponential,I=...,A=...,B=...,X0=...,S=...,constraints=(0.01<I<200,0.001<A<300,0.001<B<300,-5<X0<5,0.001<S<4),ties=(A=...,B=...)
     
 .. categories::
 
diff --git a/docs/source/algorithms/Fit-v1.rst b/docs/source/algorithms/Fit-v1.rst
index 9267c4e1abbb5a76826f75f11081c9c2203eba52..cf45eaafa023c9da55d31cbb1fbf4e945636f00d 100644
--- a/docs/source/algorithms/Fit-v1.rst
+++ b/docs/source/algorithms/Fit-v1.rst
@@ -209,6 +209,16 @@ Currently only the following functions can be used in a fit with "Histogram" eva
 If any other functions need to be included in the list please leave a request at the
 `Forum <http://forum.mantidproject.org/>`_.
 
+Peak Radius
+###########
+
+The effect of setting `PeakRadius` to a non-default value can be seen from next figure.
+
+.. figure:: /images/PeakRadius_Fit.png
+   :width: 700
+
+It can be used to speed up computations but there is a danger of introducing higher errors.
+
 
 Output
 ######
diff --git a/docs/source/algorithms/LoadNexusLogs-v1.rst b/docs/source/algorithms/LoadNexusLogs-v1.rst
index 85b036c6cb200864cb7171e7babbf9adc152f5f6..a598f17748066e6344e366a9613b1ccfd1f9c45a 100644
--- a/docs/source/algorithms/LoadNexusLogs-v1.rst
+++ b/docs/source/algorithms/LoadNexusLogs-v1.rst
@@ -60,6 +60,8 @@ Items missing from the Nexus file are simply not loaded.
 |                                  |                                                    | *Existing values are always           |
 |                                  |                                                    | overwritten.*                         |
 +----------------------------------+----------------------------------------------------+---------------------------------------+
+| Run title                        | Entry ``"title"``                                  | Title in run object if it exists      |
++----------------------------------+----------------------------------------------------+---------------------------------------+
 
 If the nexus file has a ``"proton_log"`` group, then this algorithm will do some event filtering to allow SANS2D files to load.
 
diff --git a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
index 1544bd488267decbd9031e17bcbd210ef34e0586..68f8a43df094ee532d8290deee27eedd4a2b3e7a 100644
--- a/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
+++ b/docs/source/algorithms/LoadSpiceXML2DDet-v1.rst
@@ -41,6 +41,14 @@ Counts of an :math:`n\times m` 2D detectors  are recorded in XML file as below::
 And the (1,1) position is the bottom left corner of the Anger camera as seen from the sample position.
 
 
+HB3A instrument facts
+#####################
+
+HB3A has 1 detector with :math:`256 \times 256` pixels.
+
+ - Pixel: width = :math:`2 \times 9.921875e-05` m, height = :math:`2 \times 9.921875e-05` m, depth = 0.0001 m.
+ - Detector: 
+
 
 Output Worskpaces
 #################
diff --git a/docs/source/algorithms/MonteCarloAbsorption-v1.rst b/docs/source/algorithms/MonteCarloAbsorption-v1.rst
index d1164a4fa69be627d2c29d3ba07a4564a47ae97f..5dc65a73bab5b624380e1725de7cf5434ef10d4e 100644
--- a/docs/source/algorithms/MonteCarloAbsorption-v1.rst
+++ b/docs/source/algorithms/MonteCarloAbsorption-v1.rst
@@ -54,17 +54,16 @@ The algorithm proceeds as follows. For each spectrum:
      - generate a random point on the beam face defined by the input height & width. If the point is outside of the
        area defined by the face of the sample then it is pulled to the boundary of this area
 
-     - assume the neutron travels in the direction defined by the `samplePos - srcPos` and define a `Track`
+     - generate a random point within the sample or container objects as the scatter point and create a `Track`
+       from the selected position on the beam face to the scatter point
 
-     - test for intersections of the track & sample + container objects, giving the number of subsections
+     - test for intersections of the track & sample/container objects, giving the number of subsections
        and corresponding distances within the object for each section, call them :math:`l_{1i}`
 
-     - choose a random section and depth for the scatter point
-
      - form a second `Track` with the scatter position as the starting point and the direction defined by
        `detPos - scatterPos`
 
-     - test for intersections of the track & sample + container objects, giving the number of subsections
+     - test for intersections of the track & sample/container objects, giving the number of subsections
        and corresponding distances within the object for each section, call them :math:`l_{2i}`
 
      - compute the self-attenuation factor for all intersections as
@@ -82,7 +81,8 @@ The algorithm proceeds as follows. For each spectrum:
 Interpolation
 #############
 
-The default linear interpolation method will produce an absorption curve that is not smooth. CSpline interpolation will produce a smoother result by using a 3rd-order polynomial to approximate the original points. 
+The default linear interpolation method will produce an absorption curve that is not smooth. CSpline interpolation
+will produce a smoother result by using a 3rd-order polynomial to approximate the original points. 
 
 Usage
 -----
diff --git a/docs/source/algorithms/SNAPReduce-v1.rst b/docs/source/algorithms/SNAPReduce-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..7d79a441b31246feba4be7aa23ab6d68e65f3a07
--- /dev/null
+++ b/docs/source/algorithms/SNAPReduce-v1.rst
@@ -0,0 +1,23 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+The purpose of this algorithm is to do a full reduction of SNAP
+data. This allows several runs, and with all the typical options that
+are usually used at the beamline, including calibrate from a cal file
+and from Convert Units, mask from file workspace and default masks,
+several groupings and save in GSAS or Fullprof format.
+
+Usage
+-----
+
+.. categories::
+
+.. sourcelink::
diff --git a/docs/source/algorithms/TOSCABankCorrection-v1.rst b/docs/source/algorithms/TOSCABankCorrection-v1.rst
index 22fee78069ae00a94287f9a423d0964dfdfe89dc..21a1da9a677f5faa15638beb7bb632d46cc22292 100644
--- a/docs/source/algorithms/TOSCABankCorrection-v1.rst
+++ b/docs/source/algorithms/TOSCABankCorrection-v1.rst
@@ -77,7 +77,7 @@ Output:
 
 .. testoutput:: ExTOSCABankCorrectionAutomatic
 
-    Target peak centre: 1077
+    Target peak centre: 1080
 
 **Example - Manual peak selection.**
 
@@ -95,6 +95,6 @@ Output:
 
 .. testoutput:: ExTOSCABankCorrectionManual
 
-    Target peak centre: 713
+    Target peak centre: 714
 
 .. categories::
diff --git a/docs/source/algorithms/VisionLoadDetectorTable-v1.rst b/docs/source/algorithms/VisionLoadDetectorTable-v1.rst
deleted file mode 100644
index fce9ae6bf565f7d4bca43c966ffcc6b754f11861..0000000000000000000000000000000000000000
--- a/docs/source/algorithms/VisionLoadDetectorTable-v1.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-.. algorithm::
-
-.. summary::
-
-.. alias::
-
-.. properties::
-
-Description
------------
-
-This algorithm is used to load the detector parameters for VISION
-from a CSV file into a TableWorkspace.
-
-.. Note::
-
-        Do not use this algortithm, it is just for VISION commissioning
-
-
-.. categories::
-
-.. sourcelink::
-
diff --git a/docs/source/api/python/mantid/kernel/LiveListenerInfo.rst b/docs/source/api/python/mantid/kernel/LiveListenerInfo.rst
new file mode 100644
index 0000000000000000000000000000000000000000..51572389cc864bfdaec97070be20646d537b3255
--- /dev/null
+++ b/docs/source/api/python/mantid/kernel/LiveListenerInfo.rst
@@ -0,0 +1,14 @@
+==================
+ LiveListenerInfo
+==================
+
+This a python binding to the C++ class Mantid::Kernel::LiveListenerInfo.
+
+
+.. module:`mantid.kernel`
+
+.. autoclass:: mantid.kernel.LiveListenerInfo 
+    :members:
+    :undoc-members:
+    :inherited-members:
+
diff --git a/docs/source/concepts/ErrorPropagation.rst b/docs/source/concepts/ErrorPropagation.rst
index c45bfd1fa1b9f4cbabf28c69c6998835f9494766..6a5f084056344e9b4d3a9a7be6f806fdb88a8faa 100644
--- a/docs/source/concepts/ErrorPropagation.rst
+++ b/docs/source/concepts/ErrorPropagation.rst
@@ -3,62 +3,66 @@
 Error Propagation
 =================
 
-The purpose of this document is to explain how Mantid deals with Error
-Propogation and how it is used in its algorithms.
+The purpose of this document is to explain how Mantid deals with error
+propagation and how it is used in its algorithms.
 
 Theory
 ------
 
-In order to deal with error propagation, Mantid treats errors as guassian 
-probabilities (also known as a bell curve or normal probabilities) and each 
-observation as independent. Meaning that if X = 100 +- 1 then it is still 
-possible for a value of 102 to occur, but less likely than 101 or 99, and a 
-value of 105 is far less likely still than any of these values.
+In order to deal with error propagation, Mantid treats errors as Gaussian
+probabilities (also known as a bell curve or normal probabilities) and each
+observation as independent. Meaning that if :math:`X = 100 \pm 1` then it is still
+possible for a value of :math:`102` to occur, but less likely than :math:`101`
+or :math:`99`, and a value of :math:`105` is far less likely still than any of
+these values.
 
 Plus and Minus Algorithm
 ------------------------
 
-The plus algorithm adds a selection of datasets together, including their 
-margin of errors. Mantid has to therefore adapt the margin of error so it 
-continues to work with just one margin of error. The way it does this is by 
-simply adding together the certain values. Consider the example where: 
-X\ :sub:`1` = 101 ± 2 and X\ :sub:`2` = 99 ± 2. Then for the Plus algorithm
+The :ref:`algm-Plus` algorithm adds two datasets together, propagating the
+uncertainties. Mantid calculates the result of :math:`X_1 + X_2` as
 
-X = 200 = (101 + 99).
+:math:`X = X_1 + X_2`
 
-The propagated error is calculated by taking the root of the sum of the 
-squares of the two error margins:
+with uncertainty
 
-(√2:sup:`2` + 2\ :sup:`2`) = √8
+:math:`\sigma_X = \sqrt{ \left( \sigma_{X_1} \right)^2 + \left( \sigma_{X_2} \right)^2 }`.
 
-Hence the result of the Plus algorithm can be summarised as:
+Consider the example where :math:`X_1 = 101 \pm 2` and :math:`X_2 = 99 \pm 2`.
+Then for this algorithm:
 
-X = 200 ± √8
+:math:`X = X_1 + X_2 = 101 + 99 = 200`
 
-Mantid deals with the Minus algorithm similarly.
+:math:`\sigma_X = \sqrt{ 2^2 + 2^2} = \sqrt{8} = 2.8284`
 
-Multiply and Divide Algorithm
------------------------------
+Hence the result of :ref:`algm-Plus` can be summarised as :math:`X = 200 \pm \sqrt{8}`.
+
+Mantid deals with the :ref:`algm-Minus` algorithm similarly: the result of :math:`X_1 - X_2` is
 
-The Multiply and Divide Algorithm work slightly different from the Plus
-and Minus Algorithms, in the sense that they have to be more complex, 
-see also `here <http://en.wikipedia.org/wiki/Propagation_of_uncertainty>`_.
+:math:`X = X_1 - X_2`
 
-To calculate error propagation, of say X\ :sub:`1` and X\ :sub:`2`.
-X\ :sub:`1` = 101 ± 2 and X\ :sub:`2` = 99 ± 2 ,Mantid would
-undertake the following calculation for divide:
+with error
 
-Q = X\ :sub:`1`/X:sub:`2` = 101/99
+:math:`\sigma_X = \sqrt{ \left( \sigma_{X_1} \right)^2 + \left( \sigma_{X_2} \right)^2 }`.
+
+Multiply and Divide Algorithm
+-----------------------------
 
-Error Propogation = (√ ± 2/99 + ±2/101) All multiplied by Q = 0.22425
+The :ref:`algm-Multiply` and :ref:`algm-Divide` algorithms propagate the uncertainties according
+to (see also `here <http://en.wikipedia.org/wiki/Propagation_of_uncertainty>`_):
 
-For the multiply algorithm, the only difference is in how Q is created,
-which in turn affects the Error Propogation,
+:math:`\sigma_X = \left|X\right| \sqrt{ \left( \frac{\sigma_{X_1}}{X_1} \right)^2 + \left( \frac{\sigma_{X_2}}{X_2} \right)^2 }`,
 
-Q = X\ :sub:`1`\ \*X\ :sub:`2` = 101\*99
+where :math:`X` is the result of the multiplication, :math:`X = X_1 \cdot X_2`, or the division, :math:`X = X_1 / X_2`.
 
-Error Propogation = (√ ± 2/99 + ±2/101) All multiplied by Q = 0.22425
+Considering the example above where :math:`X_1 = 101 \pm 2` and
+:math:`X_2 = 99 \pm 2`. Mantid would calculate the result of :math:`X_1 / X_2` as
+:math:`X = 101 / 99 = 1.0202`, with uncertainty
+:math:`\sigma_X = 1.0202 \sqrt{ \left(2/101\right)^2 + \left(2/99\right)^2} = 0.0288`.
 
+For :ref:`algm-Multiply`, the result of :math:`X_1 \times X_2` is
+:math:`X = 101 \times 99 = 9999`, with uncertainty
+:math:`\sigma_X = 9999 \sqrt{ \left(2/101\right)^2 + \left(2/99\right)^2} = 282.8568`.
 
 
-.. categories:: Concepts
\ No newline at end of file
+.. categories:: Concepts
diff --git a/docs/source/concepts/FittingMinimizers.rst b/docs/source/concepts/FittingMinimizers.rst
index 635e1022d27168b5cf8487167ed55a563b970b12..a66d7b16dd78564fb88e9071f29a77ded12c1687 100644
--- a/docs/source/concepts/FittingMinimizers.rst
+++ b/docs/source/concepts/FittingMinimizers.rst
@@ -34,14 +34,9 @@ options are available:
 - `Levenberg-MarquardtMD <../fitminimizers/LevenbergMarquardtMD.html>`__
 
   A `Levenberg-Marquardt <https://en.wikipedia.org/wiki/Levenberg-Marquardt_algorithm>`__ implementation generalised to allow different cost functions, and supporting chunking techniques for large datasets.
-- `Gauss-Newton <../fitminimizers/GaussNewton.html>`__ algorithm with damping.
+- `Gauss-Newton <../fitminimizers/DampedGaussNewton.html>`__ algorithm with damping.
 - :ref:`FABADA <FABADA>`
-- `Trust region
-  <https://ccpforge.cse.rl.ac.uk/gf/project/ral_nlls>`__: a `trust
-  region algorithm <https://en.wikipedia.org/wiki/Trust_region>`__ that,
-  at each iteration, calculates and returns the step that reduces the
-  model by an acceptable amount by solving (or approximating a
-  solution to) the trust-region subproblem
+- `Trust region <../fitminimizers/TrustRegion.html>`__
 
 All these algorithms are `iterative
 <https://en.wikipedia.org/wiki/Iterative_method>`__.  The *Simplex*
diff --git a/docs/source/fitfunctions/FunctionQDepends.rst b/docs/source/fitfunctions/FunctionQDepends.rst
new file mode 100644
index 0000000000000000000000000000000000000000..c94cf75a8f9218c18acad057bdcbca8f32f14284
--- /dev/null
+++ b/docs/source/fitfunctions/FunctionQDepends.rst
@@ -0,0 +1,30 @@
+.. _func-FunctionQDepends:
+
+================
+FunctionQDepends
+================
+
+.. index:: FunctionQDepends
+
+Description
+-----------
+
+This fitting function is the base class for all fitting functions that have:
+
+- A range of energy transfers as their one-dimensional domain from which to take values
+- The magnitude of the momemtum transfer, :math:`Q`, as one of their attributes.
+
+Fitting functions for QENS data depending on :math:`Q` should derive from this class.
+
+There are two ways to update attribute :math:`Q` in the fit funtion:
+
+- The user inputs a particular value.
+- The spectrum contains :math:`Q` in addition to the range of energy transfers.
+
+Conflict may arise when both options are available. In that case, priority is given to the :math:`Q`-value contained
+in the spectrum. Here are some user cases:
+
+- User cannot override the value of attribute :math:`Q` if the spectrum contains a :math:`Q`-value.
+- User can set or update the value of of attribute :math:`Q` is the spectrum does not contain a :math:`Q`-value.
+- The value of attribute :math:`Q` will be updated everytime we pass a new spectrum containing a :math:`Q`-value.
+- The value of attribute :math:`Q` will be erased if we pass a new spectrum not containing a :math:`Q`-value. In this case it is the responsability of the user to set the appropriate value.
diff --git a/docs/source/fitminimizers/GaussNewton.rst b/docs/source/fitminimizers/DampedGaussNewton.rst
similarity index 86%
rename from docs/source/fitminimizers/GaussNewton.rst
rename to docs/source/fitminimizers/DampedGaussNewton.rst
index 4e1e5db77f37e249d3423fa5bb2f382d94c6e175..86cfb1f193b94f55d965896ad83df298147f296b 100644
--- a/docs/source/fitminimizers/GaussNewton.rst
+++ b/docs/source/fitminimizers/DampedGaussNewton.rst
@@ -1,7 +1,7 @@
-.. _GaussNewton:
+.. _DampedGaussNewton:
 
-Damping Gauss-Newton minimizer
-==============================
+Damped Gauss-Newton minimizer
+=============================
 
 This minimizer is
 explained at `Wikipedia <https://en.wikipedia.org/wiki/Gauss–Newton_algorithm#Improved_versions>`__ 
diff --git a/docs/source/fitminimizers/TrustRegion.rst b/docs/source/fitminimizers/TrustRegion.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5e6d87879f7214b5160684813175ad04a7a2a327
--- /dev/null
+++ b/docs/source/fitminimizers/TrustRegion.rst
@@ -0,0 +1,15 @@
+.. _TrustRegion:
+
+Trust Region Minimizer
+======================
+
+This minimizer is a hybrid 
+`Gauss-Newton <https://en.wikipedia.org/wiki/Gauss%E2%80%93Newton_algorithm>`__/`Quasi-Newton <https://en.wikipedia.org/wiki/Quasi-Newton_method>`__ 
+method, that makes use of a `trust region <https://en.wikipedia.org/wiki/Trust_region>`__.
+
+It is a reimplementation of part of `RALFit_nonlinear least squares solver <https://github.com/ralna/RALFit>`__. 
+
+It is listed in `a comparison of fitting minimizers <../concepts/FittingMinimizers.html>`__.
+
+.. categories:: FitMinimizers
+
diff --git a/docs/source/images/EstimateFitParameters_output.png b/docs/source/images/EstimateFitParameters_output.png
new file mode 100644
index 0000000000000000000000000000000000000000..6427f0a5549f00f87fc95899973e8f77403a8f21
Binary files /dev/null and b/docs/source/images/EstimateFitParameters_output.png differ
diff --git a/docs/source/images/ISISReflectometryPolref_failed_transfer_run.png b/docs/source/images/ISISReflectometryPolref_failed_transfer_run.png
index 79f9860a18105fce722fef6b9c4b610091c4d5a5..bd4bd47385233947371f1a7b8bd26ad5a83d32cf 100644
Binary files a/docs/source/images/ISISReflectometryPolref_failed_transfer_run.png and b/docs/source/images/ISISReflectometryPolref_failed_transfer_run.png differ
diff --git a/docs/source/images/NoPeakRadius_3.9.png b/docs/source/images/NoPeakRadius_3.9.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8e515f062e9f77c7a28cb0e79d13cc80a28ffd4
Binary files /dev/null and b/docs/source/images/NoPeakRadius_3.9.png differ
diff --git a/docs/source/images/PeakRadius_Fit.png b/docs/source/images/PeakRadius_Fit.png
new file mode 100644
index 0000000000000000000000000000000000000000..b9cfc71c6a220ee13382a097ae911aa6bca61841
Binary files /dev/null and b/docs/source/images/PeakRadius_Fit.png differ
diff --git a/docs/source/images/release38.png b/docs/source/images/release38.png
new file mode 100644
index 0000000000000000000000000000000000000000..433124b8bd2a1a2a6b0aa0588da0fb3cad0c85fd
Binary files /dev/null and b/docs/source/images/release38.png differ
diff --git a/docs/source/interfaces/CrystalFieldPythonInterface.rst b/docs/source/interfaces/CrystalFieldPythonInterface.rst
index 3e764b69ab79fd3f5f878d25340f395f93bb0c4d..db8f3a598bb32e3da5020fb4c84f61427ad4494a 100644
--- a/docs/source/interfaces/CrystalFieldPythonInterface.rst
+++ b/docs/source/interfaces/CrystalFieldPythonInterface.rst
@@ -332,6 +332,12 @@ If there are multiple ions define `CrystalField` objects for each ion separately
     cf2 = CrystalField('Pr', 'C2v', **params)
     cf = cf1 + cf2
 
+The expression that combines the `CrystalField` objects also defines the contributions of each site into the overall intensity.
+The higher the coefficient of the object in the expression the higher its relative contribution. For example::
+
+    cf = 2*cf1 + cf2
+
+means that the intensity of `cf1` should be twice that of `cf2`.
 
 Fitting
 -------
@@ -355,14 +361,14 @@ After fitting finishes the `CrystalField` object updates automatically and conta
 Finding Initial Parameters
 --------------------------
 
-If the initial values of the fitting parameters are not known they can be estimated using `monte_carlo()` method.
+If the initial values of the fitting parameters are not known they can be estimated using `estimate_parameters()` method.
 It randomly searches the parameter space in a given region such that the calculated spectra are as close to the
 fit data as possible. The method uses :ref:`EstimateFitParameters <algm-EstimateFitParameters>` internally. See
 algorithm's description for the available properties.
 Here is an example of a fit with initial estimation::
 
     from CrystalField.fitting import makeWorkspace
-    from CrystalField import CrystalField, CrystalFieldFit
+    from CrystalField import CrystalField, CrystalFieldFit, Background, Function
 
     # Create some crystal field data
     origin = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544,
@@ -370,18 +376,26 @@ Here is an example of a fit with initial estimation::
     x, y = origin.getSpectrum()
     ws = makeWorkspace(x, y)
 
-    # Define a CrystalField object.
+    # Define a CrystalField object with parameters slightly shifted.
     cf = CrystalField('Ce', 'C2v', B20=0, B22=0, B40=0, B42=0, B44=0,
                       Temperature=44.0, FWHM=1.0, ResolutionModel=([0, 100], [1, 1]), FWHMVariation=0)
 
     # Set any ties on the field parameters.
     cf.ties(B20=0.37737)
-    # Define the search intervals. Only these parameters will be estimated.
-    cf.constraints('2<B22<6', '-0.2<B40<0.2', '-0.2<B42<0.2', '-0.2<B44<0.2')
     # Create a fit object
     fit = CrystalFieldFit(cf, InputWorkspace=ws)
     # Find initial values for the field parameters.
-    fit.monte_carlo(NSamples=1000)
+    # You need to define the energy splitting and names of parameters to estimate.
+    # Optionally additional constraints can be set on tied parameters (eg, peak centres).
+    fit.estimate_parameters(EnergySplitting=50,
+                            Parameters=['B22', 'B40', 'B42', 'B44'],
+                            Constraints='20<f1.PeakCentre<45,20<f2.PeakCentre<45',
+                            NSamples=1000)
+    print 'Returned', fit.get_number_estimates(), 'sets of parameters.'
+    # The first set (the smallest chi squared) is selected by default.
+    # Select a different parameter set if required
+    fit.select_estimated_parameters(3)
+    print cf['B22'], cf['B40'], cf['B42'], cf['B44']
     # Run fit
     fit.fit()
 
diff --git a/docs/source/interfaces/ISIS_Reflectometry.rst b/docs/source/interfaces/ISIS_Reflectometry.rst
index 7a7527eaf3d22b7b31674af35a7265838e7484ae..2f11e40546da785df6a51d38e236a5e737677f34 100644
--- a/docs/source/interfaces/ISIS_Reflectometry.rst
+++ b/docs/source/interfaces/ISIS_Reflectometry.rst
@@ -56,7 +56,7 @@ A table workspace called ``MyTable`` should now exist in the ADS (:ref:`Analysis
 In addition the table workspace should be opened as well and the processing table
 (shown below) should now contain four rows (13460, 13462, 13469, 13470).
 
-.. figure:: /images/ISISReflectometryPolref_INTER_table.PNG
+.. figure:: /images/ISISReflectometryPolref_INTER_table.png
   :align: center
 
 Let's process the first group, which consists of the first two rows of the
@@ -373,7 +373,7 @@ In the image below we select two runs from the Search table that we wish to tran
 Attempting to transfer an invalid run will result in that run not being transferred to the processing table. If the transfer was not successful then that specific
 run will be highlighted in the Search table.
 
-.. figure:: /images/ISISReflectometryPolref_failed_transfer_run.PNG
+.. figure:: /images/ISISReflectometryPolref_failed_transfer_run.png
    :alt: Failed transfer will be highlighted in orange, successful transfer is put into processing table
 
 Hovering over the highlighted run with your cursor will allow you to see why the run was invalid.
diff --git a/docs/source/interfaces/MuonAnalysis_test_guides/index.rst b/docs/source/interfaces/MuonAnalysis_test_guides/index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..9214e1c0bdad26f5aa34ab23d99409d569bfa6a5
--- /dev/null
+++ b/docs/source/interfaces/MuonAnalysis_test_guides/index.rst
@@ -0,0 +1,19 @@
+.. Muon Analysis Test Guides 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
+
+.. _MuonAnalysis_test_guides contents:
+
+=========================
+Muon Analysis Test Guides
+=========================
+
+.. toctree::
+   :glob:
+   :maxdepth: 1
+
+   *
+
diff --git a/docs/source/interfaces/Tomographic_Reconstruction.rst b/docs/source/interfaces/Tomographic_Reconstruction.rst
index 409838f2e0a1088262f6004193f2638df5c14ba2..074645dde24ea424a0305d390364ddc21f83dc61 100644
--- a/docs/source/interfaces/Tomographic_Reconstruction.rst
+++ b/docs/source/interfaces/Tomographic_Reconstruction.rst
@@ -342,9 +342,15 @@ same location:
 Running jobs locally
 --------------------
 
-This capability is being developed at the moment, and it requires
-additional setup steps on the local analysis machine. Basic
-functionality is supported only on the IMAT data analysis machine.
+You can run local reconstructions as well, however that requires properly setting up the:
+
+- External python interpretor path, for example:
+  - C:/Anaconda/python.exe for Windows
+  - ~/Anaconda2/bin/python for Linux
+- PYTHONPATH environment variable should contain the Python directories 
+that have the installed plugins for the supported tools
+- (Optional) Scripts directory
+  - By default this will be properly setup from the Mantid installation
 
 Visualization
 -------------
diff --git a/docs/source/interfaces/index.rst b/docs/source/interfaces/index.rst
index 8996c5b5eefab0c688904d3433884702bacb32dd..a5aad9e94446971187d1549c05e2f85bc8b387f0 100644
--- a/docs/source/interfaces/index.rst
+++ b/docs/source/interfaces/index.rst
@@ -17,4 +17,5 @@
    :maxdepth: 1
 
    *
+   MuonAnalysis_test_guides/index
 
diff --git a/docs/source/release/v3.8.0/index.rst b/docs/source/release/v3.8.0/index.rst
index 90227bd6100faca1a044333cdc8d808f0215b9fc..9b45cec8db0eb2449b1f4e6b8dee741f67ca89a7 100644
--- a/docs/source/release/v3.8.0/index.rst
+++ b/docs/source/release/v3.8.0/index.rst
@@ -2,7 +2,7 @@
 Mantid 3.8.0 Release Notes
 ==========================
 
-.. figure:: ../../images/release38.png
+.. figure:: /images/release38.png
    :class: screenshot
    :width: 500px
    :align: right
diff --git a/docs/source/release/v3.9.0/diffraction.rst b/docs/source/release/v3.9.0/diffraction.rst
index b3aa65723f1c4fde9c185fd9dce14b3717e8f332..2f1909182e95739dd208afaa75f18bccc1dbd63f 100644
--- a/docs/source/release/v3.9.0/diffraction.rst
+++ b/docs/source/release/v3.9.0/diffraction.rst
@@ -10,6 +10,14 @@ Crystal Improvements
 :ref:`algm-FindUBUsingLatticeParameters` will now return an oriented lattice even when the number of peaks used is very low.
 :ref:`algm-FindUBUsingLatticeParameters` has a new option to fix lattice parameters. This will find an orientation, but without optimisation between indexed HKLs and q vectors.
 
+
+Single Crystal Diffraction
+--------------------------
+HB3A's IDF is modified to allow its detector center shifted from default position.
+:ref:`algm-LoadSpiceXML2DDet` has new options for users to input amount of detector's shift in X and Y direction.
+:ref:`algm-ConvertCWSDExpToMomentum` has new options for users to input amount of detector's shift in X and Y direction.
+User interface *HFIR 4Circle Reduction* has been modified to allow user to specify wave length, detector center and distance between detector and sample.
+
 Engineering Diffraction
 -----------------------
 
@@ -25,6 +33,18 @@ information about the empty sample environment and instrument.
 
 :ref:`algm-SetDetScale` has a new option, DetScaleFile, to input a text file with each line containing the detector number and scale factor for that detector.  These scales will be used in SaveHKL and AnvredCorrection.  If scales for a detector are given in both the DetScaleList text string and the DetScaleFile file, the values from the text string will be used.
 
+High Pressure
+-------------
+
+:ref:`algm-CreateGroupingWorkspace` has a new option to create one group of 4 columns of SNAP detectors and another with the remaining 2 columns. This grouping is used frequently in their reduction.
+
+:ref:`algm-SNAPReduce` is new to mantid, but not for SNAP
+users. Adding the algorithm to mantid installations will reduce the
+amount of issues that SNAP users will encounter trying to reduce their
+data.
+
+New scripts for correcting diamond anvil cell attenuation. These are found in `scripts/DiamondAttenuationCorrection <https://github.com/peterfpeterson/mantid/tree/diamond_atten/scripts/DiamondAttenuationCorrection>`_.
+
 Full list of `diffraction <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.9%22+is%3Amerged+label%3A%22Component%3A+Diffraction%22>`_
 and
 `imaging <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.9%22+is%3Amerged+label%3A%22Component%3A+Imaging%22>`_ changes on GitHub.
diff --git a/docs/source/release/v3.9.0/framework.rst b/docs/source/release/v3.9.0/framework.rst
index f2affaefb1c154296813b25b0c0bfe62481bb311..bef013ff305fc09519badd41d7fd74a7c24d8da2 100644
--- a/docs/source/release/v3.9.0/framework.rst
+++ b/docs/source/release/v3.9.0/framework.rst
@@ -20,15 +20,34 @@ Improved
 
 - :ref:`CalculateFlatBackground <algm-CalculateFlatBackground>` has a new mode 'Moving Average' which takes the minimum of a moving window average as the flat background.
 - :ref:`StartLiveData <algm-StartLiveData>` and its dialog now support dynamic listener properties, based on the specific LiveListener being used.
-- :ref: All algorithms using `AsciiPointBase` now have a new property 'Separator' which allows the delimiter to be set to either comma, space or tab. This affects `SaveReflCustomAscii <algm-SaveReflCustomAscii>`, `SaveReflThreeColumnAscii <algm-SaveReflThreeColumnAscii>`, `SaveANSTOAscii <algm-SaveANSTOAscii>` and `SaveILLCosmosAscii <algm-SaveILLCosmosAscii>`.
+- All algorithms using `AsciiPointBase` now have a new property 'Separator' which allows the delimiter to be set to either comma, space or tab. This affects `SaveReflCustomAscii <algm-SaveReflCustomAscii>`, `SaveReflThreeColumnAscii <algm-SaveReflThreeColumnAscii>`, `SaveANSTOAscii <algm-SaveANSTOAscii>` and `SaveILLCosmosAscii <algm-SaveILLCosmosAscii>`.
 - :ref:`ReplaceSpecialValues <algm-ReplaceSpecialValues>` now can replace 'small' values below a user specified threshold.
-- :ref:`MonteCarloAbsorption <algm-MonteCarloAbsorption>` gained a new option: `Interpolation`.
-  This controls the method used for interpolation. Availabile options are: `Linear` & `CSpline`.
+- :ref:`SaveMDWorkspaceToVTK <algm-SaveMDWorkspaceToVTK>` has a working progress bar.
+- :ref:`SumSpectra <algm-SumSpectra>` has an option to ignore special floating point values called 'RemoveSpecialValues'. This is off by default but when enabled will ignore values such as NaN or Infinity during the summation of the spectra.  It was also updated to fix special values being used in some cases when the option was selected.
+- :ref:`MonteCarloAbsorption <algm-MonteCarloAbsorption>`:
+   * an `Interpolation` option has been added. Availabile options are: `Linear` & `CSpline`.
+   * the method of selecting the scattering point has ben updated to give better agreement with numerical algorithms such as :ref:`CylinderAbsorption <algm-CylinderAbsorption>`.
 
 Deprecated
 ##########
 
 - :ref:`CorrectFlightPaths <algm-CorrectFlightPaths>` has been renamed to ConvertToConstantL2.
+- :ref:`AbortRemoteJob	 <algm-AbortRemoteJob>` use version 2 instead.
+- :ref:`Authenticate	 <algm-Authenticate>` use version 2 instead.
+- :ref:`CentroidPeaksMD	 <algm-CentroidPeaksMD>` use version 2 instead.
+- :ref:`ConvertEmptyToTof	 <algm-ConvertEmptyToTof>`.
+- :ref:`ConvertUnitsUsingDetectorTable	 <algm-ConvertUnitsUsingDetectorTable>`.
+- :ref:`DownloadRemoteFile	 <algm-DownloadRemoteFile>` use version 2 instead.
+- :ref:`FFTSmooth	 <algm-FFTSmooth>` use version 2 instead.
+- :ref:`OneStepMDEW	 <algm-OneStepMDEW>`.
+- :ref:`QueryAllRemoteJobs	 <algm-QueryAllRemoteJobs>` use version 2 instead.
+- :ref:`RefinePowderInstrumentParameters	 <algm-RefinePowderInstrumentParameters>` use version 2 instead.
+- :ref:`SetupILLD33Reduction	 <algm-SetupILLD33Reduction>.
+- :ref:`StartRemoteTransaction	 <algm-StartRemoteTransaction>` use version 2 instead.
+- :ref:`LoadILLAscii	 <algm-LoadILLAscii>`.
+- :ref:`StopRemoteTransaction	 <algm-StopRemoteTransaction>` use version 2 instead.
+- :ref:`SubmitRemoteJob	 <algm-SubmitRemoteJob>` use version 2 instead.
+- :ref:`Transpose3D	 <algm-Transpose3D>` use TransposeMD instead.
 
 MD Algorithms (VATES CLI)
 #########################
@@ -39,15 +58,22 @@ Performance
 CurveFitting
 ------------
 
-New
-###
-
+- Systemtest, FittingBenchmarks, added for testing fit minimizer benchmarking scripts generating the tables displayed on :ref:`FittingMinimzers page <FittingMinimizers>`. This Systemtest also demo how these tables can be created as a standard Mantid script.
 - Algorithm :ref:`CalculateCostFunction <algm-CalculateCostFunction>` calculates a value of any available cost function.
 - Algorithm :ref:`EstimateFitParameters <algm-EstimateFitParameters>` estimates initial values of a fiting function in given intervals.
+- Fit Function :ref:`FunctionQDepends <func-FunctionQDepends>` as the base class for QENS models depending on Q.
 
 Improved
 ########
 
+- The `Peak Radius` global setting for 1D peaks that limits the interval on which they are calculated is replaced with `PeakRadius` property of the :ref:`Fit <algm-Fit>` algorithm (see algorithm's description for the details).
+
+.. figure:: ../../images/NoPeakRadius_3.9.png
+   :class: screenshot
+   :width: 550px
+
+- The output and normalization MDHistoWorkspaces from :ref:`MDNormSCD <algm-MDNormSCD>` and :ref:`MDNormDirectSC <algm-MDNormDirectSC>` have the 'displayNormalization' set to 'NoNormalization'. For older outputs, the `setDisplayNormalization` function is now exposed to python.
+
 Python
 ------
 
diff --git a/docs/source/release/v3.9.0/imaging.rst b/docs/source/release/v3.9.0/imaging.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5b20bd2bebb9f08ab6e37d94d38e0e90f2cfed3d
--- /dev/null
+++ b/docs/source/release/v3.9.0/imaging.rst
@@ -0,0 +1,24 @@
+=====================
+Imaging Changes
+=====================
+
+.. contents:: Table of Contents
+   :local:
+
+Tomographic reconstruction graphical user interface
+###################################################
+
+- Running local reconstructions is now possible, only a single reconstruction process can be run at any one time
+
+Bug Fixes
+---------
+- The external interpreter and scripts paths are no longer ignored and are now correctly appended when running a local reconstruction
+- Local reconstruction processes are now also updated in the reconstruction jobs list
+- The reconstruction jobs list command line is now Read Only
+- Clicking Cancel now cancels the running reconstruction process
+- The reconstruction scripts will now work with TomoPy v1.x.x, however the results have yet to be tested
+- Selecting the Center of Rotation, Area for Normalsation and Region of Interest will now always follow the exact position of the mouse
+- Multiple success/warning/error messages will no longer be shown after an operation. 
+|
+
+`Full list of changes on github <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.9%22+is%3Amerged+label%3A%22Component%3A+Imaging%22>`__
diff --git a/docs/source/release/v3.9.0/index.rst b/docs/source/release/v3.9.0/index.rst
index 7ecf71a22447a8084c4c5115895e04b4b265e719..73c942256096b3a34f86c2c691bed021f3972c79 100644
--- a/docs/source/release/v3.9.0/index.rst
+++ b/docs/source/release/v3.9.0/index.rst
@@ -37,7 +37,12 @@ Citation
 
 Please cite any usage of Mantid as follows:
 
+- *O. Arnold, et al., Mantid—Data analysis and visualization package for neutron scattering and μSR experiments, Nuclear Instruments and Methods in Physics Research Section A, Volume 764, 11 November 2014, Pages 156-166*, doi: `10.1016/j.nima.2014.07.029 <http://dx.doi.org/10.1016/j.nima.2014.07.029>`_
+
+If you want to cite this specific release please use:
+
 - *Mantid 3.9: Manipulation and Analysis Toolkit for Instrument Data.; Mantid Project*. doi: http://dx.doi.org/10.5286/SOFTWARE/MANTID3.9
+  `Full author list <http://data.datacite.org/10.5286/SOFTWARE/MANTID3.9>`_
 
 Changes
 -------
@@ -51,6 +56,7 @@ Changes
    Indirect Inelastic <indirect_inelastic>
    SANS <sans>
    Diffraction <diffraction>
+   Imaging <imaging>
    Muon Analysis <muon>
    Reflectometry <reflectometry>
 
diff --git a/docs/source/release/v3.9.0/indirect_inelastic.rst b/docs/source/release/v3.9.0/indirect_inelastic.rst
index 8441395d45e086e95ca02348fecf702bf9306809..2cc86e028fb501fda44f468c6b0e3777e94229ee 100644
--- a/docs/source/release/v3.9.0/indirect_inelastic.rst
+++ b/docs/source/release/v3.9.0/indirect_inelastic.rst
@@ -11,7 +11,7 @@ New features
 Algorithms
 ##########
 
-- :ref:`EnergyWindowScan <algm-EnergyWindowScan>` and :ref:`IndirectEnergyWindowScan <algm-IndirectEnergyWindowScan>` have been added
+- :ref:`EnergyWindowScan <algm-EnergyWindowScan>` and :ref:`IndirectQuickRun <algm-IndirectQuickRun>` have been added
   to perform a quick run of *EnergyTransfer*, *Elwin* and optional *MSDFit*
 - A new algorithm :ref:`NMoldyn4Interpolation <algm-NMoldyn4Interpolation>` which interpolates simulated data onto reference OSIRIS data
 
@@ -19,6 +19,7 @@ Data Reduction
 ##############
 
 - Q-values in :ref:`BASISReduction <algm-BASISReduction>` output are now point data so that their values display correctly when plotted
+- When plotting *ConvFit* results "Two Lorentzians" will produce plots for both lorentzians
 
 Data Analysis
 #############
@@ -26,11 +27,6 @@ Data Analysis
 - :ref:`TeixeiraWaterSQE <func-TeixeiraWaterSQE>` models translation of water-like molecules (jump diffusion).
 - :ref:`GetQsInQENSData <algm-GetQsInQENSData>` Extracts or computes Q values from a MatrixWorkspace.
 
-Improvements
-------------
-
-- When plotting from interfaces the plots now display error bars as standard
-
 Corrections
 ###########
 
@@ -59,11 +55,14 @@ Improvements
 ------------
 
 - Data saved in an ASCII format using the *EnergyTransfer* interface can be re-loaded into Mantid
+- TOSCA instrument definition file has been updated
+- When plotting from interfaces the plots now display error bars as standard
 
 Bugfixes
 --------
 
 - Clicking 'Save' without creating a res file in *ISISCalibration* no longer causes an error
+- Fixed issue when trying to plot multiple spectra
 
 
 `Full list of changes on GitHub <http://github.com/mantidproject/mantid/pulls?q=is%3Apr+milestone%3A%22Release+3.9%22+is%3Amerged+label%3A%22Component%3A+Indirect+Inelastic%22>`_
diff --git a/docs/source/release/v3.9.0/muon.rst b/docs/source/release/v3.9.0/muon.rst
index 4af00096a68c529e772f61fcd3dd301f81f9ddb8..232ebb506ebd2c94c8399fca2dc2a754b5a49b27 100644
--- a/docs/source/release/v3.9.0/muon.rst
+++ b/docs/source/release/v3.9.0/muon.rst
@@ -20,6 +20,7 @@ Muon Analysis
 - The "compatibility mode" option has been renamed "Enable multiple fitting", and defaults to off. The interface will therefore look the same as it did in Mantid 3.7 by default. To enable the new multi-fitting functionality, just tick the box on the settings tab.
 - The layout of the new fitting tab UI has been improved to give more space for the fitting function, and enable the relative space given to each section to be adjusted by the user.
 - Fixed a bug where stale plot guesses would be left on the graph in some situations.
+- Fixed a bug with load current run that meant it would be actually loading old data due to caching. Data from current run files is no longer cached behind the scenes.
 
 Algorithms
 ----------
diff --git a/docs/source/release/v3.9.0/reflectometry.rst b/docs/source/release/v3.9.0/reflectometry.rst
index cb4ecc20fe2c0cef5fd250e099e71170d779d55a..75b3b6e41432f046288a5b08f3b2a7ebd4e6b75f 100644
--- a/docs/source/release/v3.9.0/reflectometry.rst
+++ b/docs/source/release/v3.9.0/reflectometry.rst
@@ -19,8 +19,12 @@ ISIS Reflectometry (Polref)
 
 - Settings tab now displays individual global options for experiment and instrument settings.
 - New 'Save ASCII' tab added, similar in function and purpose to the 'Save Workspaces' window accessible from Interfaces->ISIS Reflectometry->File->Save Workspaces.
+- When runs are transferred to the processing table groups are now labeled according to run title.
 - Column :literal:`dQ/Q` is used as the rebin parameter to stitch workspaces.
+- Fixed a bug where if the user answered 'no' to a popup asking if they wanted to process all runs, the progress bar would show activity as though a data reduction was occurring.
+- The interface is now arranged in two different groups. Groups apply to tabs 'Run' and 'Settings'.
 - Documentation regarding the interface has been updated accordingly.
+- Error messages are displayed if the user either attempts to transfer zero runs or transfer runs with a different strategy to the one they used to search for runs with. 
 
 ISIS Reflectometry
 ##################
diff --git a/docs/source/release/v3.9.0/ui.rst b/docs/source/release/v3.9.0/ui.rst
index df71e9bba2c497f6c1d3eecb8e6f756d3ddc755e..85f435aaa7f6f1f903eca4bd3c08118e6b297448 100644
--- a/docs/source/release/v3.9.0/ui.rst
+++ b/docs/source/release/v3.9.0/ui.rst
@@ -23,6 +23,8 @@ User Interface
 Instrument View
 ###############
  - New peak comparison tool on the pick tab. The user can select two peaks and information relating to their properties and the angles between them.
+ - Added the ability to drag and drog mask workspaces onto the instrument view. This will apply the store workspace to the view.
+ - Added the ability to store masking/ROI/grouping shapes to a table workspace which can be dragged & dropped back onto different instrument views 
 
 Plotting Improvements
 #####################
@@ -52,12 +54,17 @@ Bugs Resolved
 
 - Fixed a bug where checking or unchecking "show invisible workspaces" in View->Preferences->Mantid->Options would have no effect on workspaces loaded in the dock.
 - The Spectrum Viewer now reports two theta and azimuthal angle correctly.
-- Fixed crash when clicking "Help->Ask for Help" on Linux-based systems with Firefox set as the default browser.  
+- Fixed crash when clicking "Help->Ask for Help" on Linux-based systems with Firefox set as the default browser.
+- The "Filter log values by" option in the Sample Logs dialog now works out the log statistics with the correct filter applied, and deals correctly with aborted runs.
 - Fixed crash when loading data and the algorithm widget is hidden
 - Fixed exception being thrown when saving project with custom interfaces open
 - The "Plot Surface from Group" and "Plot Contour from Group" options have been fixed and now work for both histogram and point data. Note that all workspaces in the group must have the same X data.
 - Fixed a bug where enabling auto rebinning in the slice viewer and zooming would not rebin the workspace if it was a histogram workspace.
 - Legend placement has been fixed in the "tiled plot"/``plotSubplots`` option, and these graphs now use Mantid's default plot style options.
+- Fixed a bug where saving a plot created from columns of a table window are loaded back as a blank plot from a Mantid project.
+- Fixed a bug where saving a tiled plot saved to a project file would be reloaded with different size plots.
+- Fixed a bug where minimised windows would not stay minimised after being serialised to a Mantid project
+- Fixed a bug where changing the integration range of the instrument view would clear the applied zooming.
 
 SliceViewer Improvements
 ------------------------
@@ -76,3 +83,7 @@ VSI Improvements
 
 - ParaView updated to v5.2.0
 - The sources and views more reliably show progress in the VSI status bar. 
+- Added a button to the standard view which applies the threshold filter.
+- Update the cut button to match the equivalent ParaView icon.
+- Changed the fallback for a MDHistoworkspace opened in the (incompatible) SplatterPlot view to the MultiSlice view.
+- Faster initial loading of a MDHistoworkspace in the MultiSlice and ThreeSlice view.
diff --git a/instrument/Facilities.xml b/instrument/Facilities.xml
index 2b6399ddd6f8b7e78b2de02f37cc287407e97100..f6f481aa96e1dcdb8d8e2650c72d6631220e029b 100644
--- a/instrument/Facilities.xml
+++ b/instrument/Facilities.xml
@@ -2,6 +2,7 @@
 <facilities>
 
 <facility name="ISIS" zeropadding="5" FileExtensions=".nxs,.raw,.sav,.n*,.s*,.add,.nxspe">
+
   <archive>
     <archiveSearch plugin="ISISDataSearch" />
   </archive>
@@ -23,100 +24,134 @@
 
   <instrument name="ALF">
     <technique>Single Crystal Diffraction</technique>
-    <livedata address="NDXALF:6789" />
+    <livedata>
+      <connection name="histo" address="NDXALF:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="CRISP" shortname="CSP">
-    <zeropadding size="8" startRunNumber="99778" prefix="CRISP"/> 	
+    <zeropadding size="8" startRunNumber="99778" prefix="CRISP" />
     <technique>Reflectometry</technique>
-    <livedata address="NDXCRISP:6789" />
+    <livedata>
+      <connection name="histo" address="NDXCRISP:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ENGIN-X" shortname="ENGINX" >
-    <zeropadding size="8"/>
+    <zeropadding size="8" />
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXENGINX:6789" />
+    <livedata default="histo">
+      <connection name="histo" address="NDXENGINX:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ENGIN-X_EVENT" shortname="ENGINX" >
-    <zeropadding size="8"/>
+    <zeropadding size="8" />
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXENGINX:10000" listener="ISISLiveEventDataListener" />
+    <livedata default="event">
+      <connection name="event" address="NDXENGINX:10000" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="GEM">
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXGEM:6789" />
+    <livedata>
+      <connection name="histo" address="NDXGEM:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="HET">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXHET:6789" />
+    <livedata>
+      <connection name="histo" address="NDXHET:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="HRPD" shortname="HRP">
     <technique>Powder Diffraction</technique>
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXHRPD:6789" />
+    <livedata>
+      <connection name="histo" address="NDXHRPD:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="IMAT">
     <technique>Neutron Imaging</technique>
-    <livedata address="NDXIMAT:6789" />
+    <livedata>
+      <connection name="histo" address="NDXIMAT:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="INES" shortname="INS" beamline="N8">
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXINES:6789" />
+    <livedata>
+      <connection name="histo" address="NDXINES:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="INTER">
     <technique>Reflectometry</technique>
     <zeropadding size="8"/>
-    <livedata address="NDXINTER:6789" />
+    <livedata>
+      <connection name="histo" address="NDXINTER:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="IRIS" shortname="IRS" beamline="N6">
     <zeropadding size="8" startRunNumber="54938" prefix="IRIS"/>
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Indirect Geometry Spectroscopy</technique>
-    <livedata address="NDXIRIS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXIRIS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="LARMOR">
     <technique>Small Angle Scattering</technique>
     <zeropadding size="8"/>
-    <livedata address="NDXLARMOR:6789" />
+    <livedata>
+      <connection name="histo" address="NDXLARMOR:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="LOQ">
     <technique>Small Angle Scattering</technique>
-    <livedata address="NDXLOQ:6789" />
+    <livedata>
+      <connection name="histo" address="NDXLOQ:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MAPS" shortname="MAP">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXMAPS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXMAPS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MARI" shortname="MAR">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXMARI:6789" />
+    <livedata>
+      <connection name="histo" address="NDXMARI:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MERLIN" shortname="MER">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXMERLIN:6789" />
+    <livedata>
+      <connection name="histo" address="NDXMERLIN:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MERLIN_EVENT" shortname="MER">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXMERLIN:10000" listener="ISISLiveEventDataListener" />
+    <livedata>
+      <connection name="event" address="NDXMERLIN:10000" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="OSIRIS" shortname="OSI" beamline="N6">
@@ -124,25 +159,33 @@
     <technique>Neutron Diffraction</technique>
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Indirect Geometry Spectroscopy</technique>
-    <livedata address="NDXOSIRIS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXOSIRIS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="PEARL" shortname="PRL">
     <zeropadding size="5" startRunNumber="1" prefix="PRL"/>
     <zeropadding size="8" startRunNumber="71010" prefix="PEARL"/>
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXPEARL:6789" />
+    <livedata>
+      <connection name="histo" address="NDXPEARL:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="POLARIS" shortname="POL">
     <technique>Neutron Diffraction</technique>
-    <livedata address="NDXPOLARIS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXPOLARIS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="SANDALS" shortname="SLS">
     <technique>Neutron Diffraction</technique>
     <technique>Neutron Diffraction with isotopic substitution</technique>
-    <livedata address="NDXSANDALS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXSANDALS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="SURF" shortname="SRF">
@@ -150,13 +193,17 @@
     <zeropadding size="6" startRunNumber="100000" prefix="SRF"/>
     <zeropadding size="8" startRunNumber="104604" prefix="SURF"/>
     <technique>Reflectometry</technique>
-    <livedata address="NDXSURF:6789" />
+    <livedata>
+      <connection name="histo" address="NDXSURF:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="SXD">
     <technique>Neutron Diffraction</technique>
     <technique>Single Crystal Diffraction</technique>
-    <livedata address="NDXSXD:6789" />
+    <livedata>
+      <connection name="histo" address="NDXSXD:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="TFXA" shortname="TFX">
@@ -167,64 +214,84 @@
   <instrument name="TOSCA" shortname="TSC">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Indirect Geometry Spectroscopy</technique>
-    <livedata address="NDXTOSCA:6789" />
+    <livedata>
+      <connection name="histo" address="NDXTOSCA:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="VESUVIO" shortname="EVS">
     <technique>Neutron Compton Scattering</technique>
     <technique>TOF Indirect Geometry Diffraction</technique>
-    <livedata address="NDXVESUVIO:6789" />
+    <livedata>
+      <connection name="histo" address="NDXVESUVIO:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="LET">
     <zeropadding size="8"/>
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXLET:6789" />
+    <livedata>
+      <connection name="histo" address="NDXLET:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="LET_EVENT" shortname="LET">
     <zeropadding size="8"/>
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="NDXLET:10000" listener="ISISLiveEventDataListener" />
+    <livedata>
+      <connection name="event" address="NDXLET:10000" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="NIMROD">
     <zeropadding size="8"/>
     <technique>Neutron Diffraction</technique>
     <technique>Neutron Diffraction with isotopic substitution</technique>
-    <livedata address="NDXNIMROD:6789" />
+    <livedata>
+      <connection name="histo" address="NDXNIMROD:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="OFFSPEC">
     <zeropadding size="8"/>
     <technique>Reflectometry</technique>
-    <livedata address="NDXOFFSPEC:6789" />
+    <livedata>
+      <connection name="histo" address="NDXOFFSPEC:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="OFFSPEC_EVENT" shortname="OFFSPEC">
     <zeropadding size="8"/>
     <technique>Reflectometry</technique>
-    <livedata address="NDXOFFSPEC:10000" listener="ISISLiveEventDataListener" />
+    <livedata>
+      <connection name="event" address="NDXOFFSPEC:10000" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="POLREF">
     <zeropadding size="8"/>
     <technique>Reflectometry</technique>
-    <livedata address="NDXPOLREF:6789" />
+    <livedata>
+      <connection name="histo" address="NDXPOLREF:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="SANS2D">
     <zeropadding size="8"/>
     <technique>Small Angle Scattering</technique>
-    <livedata address="NDXSANS2D:6789" />
+    <livedata>
+      <connection name="histo" address="NDXSANS2D:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="SANS2D_EVENT" shortname="SANS2D">
     <zeropadding size="8"/>
     <technique>Small Angle Scattering</technique>
-    <livedata address="NDXSANS2D:10000" listener="ISISLiveEventDataListener" />
+    <livedata>
+      <connection name="event" address="NDXSANS2D:10000" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="WISH">
@@ -232,7 +299,9 @@
     <technique>Neutron Diffraction</technique>
     <technique>Powder Diffraction</technique>
     <technique>Single Crystal Diffraction</technique>
-    <livedata address="NDXWISH:6789" />
+    <livedata>
+      <connection name="histo" address="NDXWISH:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="HIFI">
@@ -240,14 +309,18 @@
     <technique>Muon level crossing resonance</technique>
     <technique>Muon spectroscopy</technique>
     <technique>Radio frequency muSR</technique>
-    <livedata address="NDXHIFI:6789" />
+    <livedata>
+      <connection name="histo" address="NDXHIFI:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MUSR">
     <zeropadding size="8"/>
     <technique>Muon spectroscopy</technique>
     <technique>Radio frequency muSR</technique>
-    <livedata address="NDXMUSR:6789" />
+    <livedata>
+      <connection name="histo" address="NDXMUSR:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="MUT">
@@ -260,7 +333,9 @@
     <zeropadding size="8"/>
     <technique>Muon spectroscopy</technique>
     <technique>Radio frequency muSR</technique>
-    <livedata address="NDXEMU:6789" />
+    <livedata>
+      <connection name="histo" address="NDXEMU:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ARGUS">
@@ -268,20 +343,23 @@
     <zeropadding size="8" startRunNumber="57942"/>
     <technique>Muon spectroscopy</technique>
     <technique>Radio frequency muSR</technique>
-    <livedata address="NDXARGUS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXARGUS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="CHRONUS">
     <zeropadding size="8"/>
     <technique>Muon spectroscopy</technique>
     <technique>Radio frequency muSR</technique>
-    <livedata address="NDXCHRONUS:6789" />
+    <livedata>
+      <connection name="histo" address="NDXCHRONUS:6789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
-  <livedata listener="ISISHistoDataListener"/>
-
 </facility>
 
+
 <facility name="HFIR" FileExtensions=".nxs,.dat,.xml">
 
    <instrument name="HB1">
@@ -316,7 +394,6 @@
       <technique>technique</technique>
    </instrument>
 
-
    <instrument name="GPSANS">
       <technique>Small Angle Scattering</technique>
    </instrument>
@@ -335,6 +412,7 @@
 
 </facility>
 
+
 <facility name="SNS" delimiter="_" FileExtensions=".nxs.h5,_event.nxs,.nxs,.dat,_runinfo.xml,_histo.nxs">
 
    <archive>
@@ -362,13 +440,17 @@
 
    <instrument name="USANS" shortname="USANS" beamline="1A">
       <technique>Small Angle Scattering</technique>
-      <livedata address="bl1a-daq1.sns.gov:31415" />
+      <livedata>
+      <connection name="event" address="bl1a-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="NOMAD" shortname="NOM" beamline="1B">
    	<technique>Neutron Diffraction</technique>
    	<technique>Neutron Amorphous</technique>
-        <livedata address="bl1b-daq1.sns.gov:31415" />
+        <livedata>
+      <connection name="event" address="bl1b-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="BASIS" shortname="BSS" beamline="2">
@@ -387,7 +469,9 @@
 
    <instrument name="REF_L" beamline="4B">
       <technique>Reflectometry</technique>
-      <livedata address="bl4b-daq1.sns.gov:31415" />
+      <livedata>
+      <connection name="event" address="bl4b-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="CNCS" beamline="5">
@@ -407,12 +491,16 @@
    <instrument name="CORELLI" beamline="9">
 	<technique>Neutron Diffraction</technique>
 	<technique>Diffuse Scattering</technique>
-	<livedata address="bl9-daq1.sns.gov:31415" />
+	<livedata>
+      <connection name="event" address="bl9-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="POWGEN" shortname="PG3" beamline="11A">
 	<technique>Neutron Diffraction</technique>
-        <livedata address="bl11a-daq1.sns.gov:31415" />
+        <livedata>
+      <connection name="event" address="bl11a-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="MANDI" beamline="11B">
@@ -424,28 +512,36 @@
    <instrument name="TOPAZ" beamline="12">
 	<technique>Neutron Diffraction</technique>
     <technique>Single Crystal Diffraction</technique>
-    <livedata listener="TOPAZLiveEventDataListener" address="128.219.164.132:9000" />
+    <livedata>
+      <connection name="event" address="128.219.164.132:9000" listener="TOPAZLiveEventDataListener" />
+    </livedata>
     <!-- Act like we're ISawEV talking to event_catcher -->
    </instrument>
 
   <instrument name="HYSPEC" shortname="HYS" beamline="14B">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
-    <livedata address="bl14b-daq1.sns.gov:31415" />
+    <livedata>
+      <connection name="event" address="bl14b-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="VISION" shortname="VIS" beamline="16B">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Indirect Geometry Spectroscopy</technique>
     <technique>Neutron Diffraction</technique>
-    <livedata address="bl16b-daq1.sns.gov:31415" />
+    <livedata>
+      <connection name="event" address="bl16b-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
   </instrument>
 
    <instrument name="SEQUOIA" shortname="SEQ" beamline="17">
     <technique>Neutron Spectroscopy</technique>
     <technique>TOF Direct Geometry Spectroscopy</technique>
     <technique>Neutron Diffraction</technique>
-    <livedata address="bl17-daq1.sns.gov:31415" />
+    <livedata>
+      <connection name="event" address="bl17-daq1.sns.gov:31415" listener="SNSLiveEventDataListener" />
+    </livedata>
    </instrument>
 
    <instrument name="ARCS" beamline="18">
@@ -463,8 +559,6 @@
       <technique>Small Wide Angle Scattering</technique>
    </instrument>
 
-   <livedata listener="SNSLiveEventDataListener"/>
-
 </facility>
 
 <facility name="NCNR" FileExtensions=".dat,.xml">
@@ -659,22 +753,30 @@
 <facility name="TEST_LIVE" FileExtensions=".nxs,.raw">
   <instrument name="ISIS_Histogram">
     <technique>Test Listener</technique>
-    <livedata address="localhost:56789" listener="ISISHistoDataListener"/>
+    <livedata>
+      <connection name="histo" address="localhost:56789" listener="ISISHistoDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ISIS_Event">
     <technique>Test Listener</technique>
-    <livedata address="localhost:59876" listener="ISISLiveEventDataListener" />
+    <livedata>
+      <connection name="event" address="localhost:59876" listener="ISISLiveEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ADARA_FileReader">
     <technique>Test Listener</technique>
-    <livedata listener="FileEventDataListener" address="127.0.0.1:0" />
+    <livedata>
+      <connection name="file" address="127.0.0.1:0" listener="FileEventDataListener" />
+    </livedata>
   </instrument>
 
   <instrument name="ADARA_FakeEvent">
     <technique>Test Listener</technique>
-    <livedata listener="FakeEventDataListener" address="127.0.0.1:0" />
+    <livedata>
+      <connection name="fake" address="127.0.0.1:0" listener="FakeEventDataListener" />
+    </livedata>
   </instrument>
 
 </facility>
diff --git a/instrument/HB3A_Definition.xml b/instrument/HB3A_Definition.xml
index 35f73f3af74250df6bcd1b1a910b9a176887a5a7..3cd97a7ca82d4e53e2d4015b721a63efdc94c562 100644
--- a/instrument/HB3A_Definition.xml
+++ b/instrument/HB3A_Definition.xml
@@ -12,7 +12,7 @@
   </component>
   <type is="SamplePos" name="sample-position"/>
   <!--PANEL-->
-  <component idfillbyfirst="x" idstart="1" idstepbyrow="256" type="panel">
+  <component idfillbyfirst="x" idstart="1" idstepbyrow="256" type="arm">
     <location name="bank1">
       <parameter name="r-position">
 	      <logfile eq="1.0*value+0.3750" id="diffr"/>
@@ -28,13 +28,19 @@
       </parameter>
     </location>
   </component>
+  <type name="arm">
+	  <component type="panel">
+		  <location>
+			  <parameter name="x">
+				  <logfile eq='value' id='deltax'/>
+			  </parameter>
+			  <parameter name="y">
+				  <logfile eq='value' id='deltay'/>
+			  </parameter>
+		  </location>
+	  </component>
+  </type>
   <type is="rectangular_detector" name="panel" type="pixel" xpixels="256" xstart="0.0252015625" xstep="-0.0001984375" ypixels="256" ystart="-0.022621875" ystep="0.0001984375">
-	  <parameter name="xstart">
-		  <value val="0.02530078125"/>
-	  </parameter>
-	  <parameter name="ystart">
-		  <value val="-0.02530078125"/>
-	  </parameter>
  </type>
   <type is="detector" name="pixel">
     <cuboid id="pixel-shape">
diff --git a/instrument/IDFs_for_UNIT_TESTING/UnitTestFacilities.xml b/instrument/IDFs_for_UNIT_TESTING/UnitTestFacilities.xml
index b87e614b3dbfb46f128ac9deecf2ff83c457f97c..06f3978d8137a40de44419a05e53018cc6d43386 100644
--- a/instrument/IDFs_for_UNIT_TESTING/UnitTestFacilities.xml
+++ b/instrument/IDFs_for_UNIT_TESTING/UnitTestFacilities.xml
@@ -3,28 +3,34 @@
 
 <facility name="TEST" FileExtensions=".nxs,.dat,.xml">
 
-   <livedata listener="MockILiveListener"/>
-
-   <instrument name="MINITOPAZ"> 
-      <technique>Test Neutron Diffraction</technique>
-      <livedata address="127.0.0.1:0" />
-   </instrument>
+  <instrument name="MINITOPAZ">
+    <technique>Test Neutron Diffraction</technique>
+    <livedata>
+      <connection name="default" address="127.0.0.1:0" listener="MockILiveListener" />
+    </livedata>
+  </instrument>
 
   <instrument name="TESTHISTOLISTENER"> 
     <zeropadding size="8"/>
     <zeropadding size="11" startRunNumber="300" prefix="TST"/>
     <technique>Test ISISHistoDataListener</technique>
-    <livedata listener="ISISHistoDataListener" address="127.0.0.1:56789" />
+    <livedata>
+      <connection name="default" listener="ISISHistoDataListener" address="127.0.0.1:56789" />
+    </livedata>
   </instrument>
 
   <instrument name="TestDataListener">
     <technique>Test Listener</technique>
-    <livedata listener="TestDataListener" address="127.0.0.1:0" />
+    <livedata>
+      <connection name="default" listener="TestDataListener" address="127.0.0.1:0" />
+    </livedata>
   </instrument>
 
   <instrument name="FakeEventDataListener">
     <technique>Test Listener</technique>
-    <livedata listener="FakeEventDataListener" address="127.0.0.1:0" />
+    <livedata>
+      <connection name="default" listener="FakeEventDataListener" address="127.0.0.1:0" />
+    </livedata>
   </instrument>
 
 </facility>
diff --git a/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd b/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd
index 2035427f3e05888d6e1eab8b74e581d2926973d6..c6cbde1cdeb9e8a6077b976d396d1d6d013ebd9c 100644
--- a/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd
+++ b/instrument/Schema/Facilities/1.0/FacilitiesSchema.xsd
@@ -82,8 +82,14 @@
                     <xs:element name="technique" maxOccurs="unbounded" type="xs:string"/>
                     <xs:element name="livedata">
                       <xs:complexType>
-                        <xs:attribute name ="address" type="xs:string" use="required"/>
-                        <xs:attribute name="listener" type="xs:string" use="optional"/>
+                        <xs:attribute name="default" type="xs:string" use="optional"/>
+                        <xs:element name="connection" minOccurs="1" maxOccurs="unbounded">
+                          <xs:complexType>
+                            <xs:attribute name="name" type="xs:string" use="required"/>
+                            <xs:attribute name="address" type="xs:string" use="required"/>
+                            <xs:attribute name="listener" type="xs:string" use="required"/>
+                          </xs:complexType>
+                        </xs:element>
                       </xs:complexType>
                     </xs:element>
                   </xs:choice>
@@ -92,11 +98,6 @@
                   <xs:attribute name="beamline" type="xs:string" use="optional"/>
                 </xs:complexType>
               </xs:element>
-              <xs:element name="livedata" minOccurs="0">
-                <xs:complexType>
-                  <xs:attribute name="listener" type="xs:string" use="required"/>
-                </xs:complexType>
-              </xs:element>
             </xs:choice>
             <xs:attribute name="name"/>
             <xs:attribute name="zeropadding"/>
diff --git a/instrument/TOSCA_Definition.xml b/instrument/TOSCA_Definition.xml
index a964103d6273f4964d7c1ee01d7d66def6a29c94..8806b3c20fd554231fc443c773470bfee4a65149 100644
--- a/instrument/TOSCA_Definition.xml
+++ b/instrument/TOSCA_Definition.xml
@@ -6,7 +6,7 @@
             xsi:schemaLocation="http://www.mantidproject.org/IDF/1.0 http://schema.mantidproject.org/IDF/1.0/IDFSchema.xsd"
             name="TOSCA"
             valid-from="2006-08-10 23:59:59"
-            valid-to="2100-01-31 23:59:59"
+            valid-to="2016-11-25 23:59:59"
             last-modified="2011-03-21 00:00:00" >
 
   <defaults>
diff --git a/instrument/TOSCA_Definition_2016.xml b/instrument/TOSCA_Definition_2016.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3a884a3522ca215ad2c0c5a772a7c07533a42e6c
--- /dev/null
+++ b/instrument/TOSCA_Definition_2016.xml
@@ -0,0 +1,715 @@
+<?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="TOSCA"
+            valid-from="2016-11-25 23:59:59"
+            valid-to="2100-01-31 23:59:59"
+            last-modified="2011-03-21 00:00:00" >
+
+  <defaults>
+    <length unit="meter"/>
+    <angle unit="degree"/>
+    <reference-frame>
+      <!-- The z-axis is set parallel to and in the direction of the beam. the 
+           y-axis points up and the coordinate system is right handed. -->
+      <along-beam axis="z"/>
+      <pointing-up axis="y"/>
+      <handedness val="right"/>
+    </reference-frame>
+  </defaults>
+
+  <!--  SOURCE AND SAMPLE POSITION -->
+
+  <component type="moderator">
+    <location z="-17.01" />
+  </component>
+
+  <type name="moderator" is="Source">
+  </type>
+
+  <component type="sample-position">
+    <location />
+  </component>
+
+  <type name="sample-position" is="SamplePos">
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.02" y="-0.02" z="0.0"  />
+      <left-front-top-point  x="0.02" y="-0.02" z="0.02"  />
+      <left-back-bottom-point  x="-0.02" y="-0.02" z="0.0"  />
+      <right-front-bottom-point  x="0.02" y="0.02" z="0.0"  />
+    </cuboid>
+    <algebra val="shape" />
+  </type>
+
+  <!-- MONITORS -->
+  <component type="monitor1" idlist="monitor1">
+    <location z="-1.1385" />
+  </component>
+
+  <type name="monitor1" is="monitor">
+    <cuboid id="shape">
+      <left-front-bottom-point x="0.0025" y="-0.1" z="0.0"  />
+      <left-front-top-point  x="0.0025" y="-0.1" z="0.02"  />
+      <left-back-bottom-point  x="-0.0025" y="-0.1" z="0.0"  />
+      <right-front-bottom-point  x="0.0025" y="0.1" z="0.0"  />
+    </cuboid>
+  </type>
+
+  <!-- DETECTORS -->
+
+  <component type="back" idlist="back">  
+    <location />
+  </component>
+
+  <component type="front" idlist="front">  
+    <location />
+  </component>
+
+  <component type="diffraction" idlist="diffraction">
+    <location />
+  </component>
+
+  <type name="back">
+    <component type="tube" > 
+      <location r="0.56370" t="140.8250595" p="150.0" rot="60.0" name="Detector #1" /> 
+      <parameter name="Efixed"> <value val="2.690280" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57275" t="139.7268737" p="150.0" rot="60.0" name="Detector #2" /> 
+      <parameter name="Efixed"> <value val="2.771000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58139" t="138.7320442" p="150.0" rot="60.0" name="Detector #3" /> 
+      <parameter name="Efixed"> <value val="2.855410" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58909" t="137.8857039" p="150.0" rot="60.0" name="Detector #4" /> 
+      <parameter name="Efixed"> <value val="2.943700"/> </parameter> 
+    </component> 
+    <component type="tube" > 
+      <location r="0.59795" t="136.9549250" p="150.0" rot="60.0" name="Detector #5" /> 
+      <parameter name="Efixed"> <value val="3.036910" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60815" t="135.9356820" p="150.0" rot="60.0" name="Detector #6" /> 
+      <parameter name="Efixed"> <value val="3.134920" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61800" t="135.0000000" p="150.0" rot="60.0" name="Detector #7" /> 
+      <parameter name="Efixed"> <value val="3.238630" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62553" t="134.3143712" p="150.0" rot="60.0" name="Detector #8" /> 
+      <parameter name="Efixed"> <value val="3.345900" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63820" t="133.2140449" p="150.0" rot="60.0" name="Detector #9" /> 
+      <parameter name="Efixed"> <value val="3.461600" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64925" t="132.3046077" p="150.0" rot="60.0" name="Detector #10" /> 
+      <parameter name="Efixed"> <value val="3.582930" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66204" t="131.3051250" p="150.0" rot="60.0" name="Detector #11" /> 
+      <parameter name="Efixed"> <value val="3.711220" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67394" t="130.4221151" p="150.0" rot="60.0" name="Detector #12" /> 
+      <parameter name="Efixed"> <value val="3.846910" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68674" t="129.5185603" p="150.0" rot="60.0" name="Detector #13" /> 
+      <parameter name="Efixed"> <value val="3.990450" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="128.6289408" p="150.0" rot="60.0" name="Detector #14" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56697" t="140.4212644" p="210.0" rot="120.0" name="Detector #15" /> 
+      <parameter name="Efixed"> <value val="2.711400" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57273" t="139.7292352" p="210.0" rot="120.0" name="Detector #16" /> 
+      <parameter name="Efixed"> <value val="2.791200" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58159" t="138.7095962" p="210.0" rot="120.0" name="Detector #17" /> 
+      <parameter name="Efixed"> <value val="2.876300" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.59101" t="137.6802142" p="210.0" rot="120.0" name="Detector #18" /> 
+      <parameter name="Efixed"> <value val="2.967800" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60202" t="136.5417863" p="210.0" rot="120.0" name="Detector #19" /> 
+      <parameter name="Efixed"> <value val="3.065600" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61305" t="135.4645161" p="210.0" rot="120.0" name="Detector #20" /> 
+      <parameter name="Efixed"> <value val="3.169800" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62244" t="134.5927407" p="210.0" rot="120.0" name="Detector #21" /> 
+      <parameter name="Efixed"> <value val="3.280600" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63452" t="133.5270497" p="210.0" rot="120.0" name="Detector #22" /> 
+      <parameter name="Efixed"> <value val="3.400100" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64940" t="132.2925646" p="210.0" rot="120.0" name="Detector #23" /> 
+      <parameter name="Efixed"> <value val="3.528800" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66191" t="131.3150135" p="210.0" rot="120.0" name="Detector #24" /> 
+      <parameter name="Efixed"> <value val="3.666600" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67482" t="130.3585065" p="210.0" rot="120.0" name="Detector #25" /> 
+      <parameter name="Efixed"> <value val="3.813200" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68980" t="129.3092171" p="210.0" rot="120.0" name="Detector #26" /> 
+      <parameter name="Efixed"> <value val="3.973100" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70642" t="128.2140307" p="210.0" rot="120.0" name="Detector #27" /> 
+      <parameter name="Efixed"> <value val="4.146300" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="128.6289408" p="210.0" rot="120.0" name="Detector #28" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56940" t="140.1263856" p="270.0" rot="180.0" name="Detector #29" /> 
+      <parameter name="Efixed"> <value val="2.709560" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57486" t="139.4792890" p="270.0" rot="180.0" name="Detector #30" /> 
+      <parameter name="Efixed"> <value val="2.789910" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58484" t="138.3483445" p="270.0" rot="180.0" name="Detector #31" /> 
+      <parameter name="Efixed"> <value val="2.878350" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.59564" t="137.1933654" p="270.0" rot="180.0" name="Detector #32" /> 
+      <parameter name="Efixed"> <value val="2.973660" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60434" t="136.3101592" p="270.0" rot="180.0" name="Detector #33" /> 
+      <parameter name="Efixed"> <value val="3.075680" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61560" t="135.2238131" p="270.0" rot="180.0" name="Detector #34" /> 
+      <parameter name="Efixed"> <value val="3.187090" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62627" t="134.2483089" p="270.0" rot="180.0" name="Detector #35" /> 
+      <parameter name="Efixed"> <value val="3.307450" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64092" t="132.9860183" p="270.0" rot="180.0" name="Detector #36" /> 
+      <parameter name="Efixed"> <value val="3.438560" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65612" t="131.7609698" p="270.0" rot="180.0" name="Detector #37" /> 
+      <parameter name="Efixed"> <value val="3.581780" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67119" t="130.6223597" p="270.0" rot="180.0" name="Detector #38" /> 
+      <parameter name="Efixed"> <value val="3.737090" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68877" t="129.3794046" p="270.0" rot="180.0" name="Detector #39" /> 
+      <parameter name="Efixed"> <value val="3.906990" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70746" t="128.1477470" p="270.0" rot="180.0" name="Detector #40" /> 
+      <parameter name="Efixed"> <value val="4.093350" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.72661" t="126.9710935" p="270.0" rot="180.0" name="Detector #41" /> 
+      <parameter name="Efixed"> <value val="4.297320" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="128.6289408" p="270.0" rot="180.0" name="Detector #42" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56746" t="140.3614522" p="330.0" rot="240.0" name="Detector #43" /> 
+      <parameter name="Efixed"> <value val="2.695290" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57458" t="139.5119672" p="330.0" rot="240.0" name="Detector #44" /> 
+      <parameter name="Efixed"> <value val="2.773110" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58325" t="138.5242550" p="330.0" rot="240.0" name="Detector #45" /> 
+      <parameter name="Efixed"> <value val="2.857010" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58955" t="137.8362758" p="330.0" rot="240.0" name="Detector #46" /> 
+      <parameter name="Efixed"> <value val="2.946360" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60136" t="136.6081885" p="330.0" rot="240.0" name="Detector #47" /> 
+      <parameter name="Efixed"> <value val="3.044560" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61266" t="135.5015972" p="330.0" rot="240.0" name="Detector #48" /> 
+      <parameter name="Efixed"> <value val="3.149860" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62338" t="134.5076258" p="330.0" rot="240.0" name="Detector #49" /> 
+      <parameter name="Efixed"> <value val="3.263620" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63521" t="133.4679613" p="330.0" rot="240.0" name="Detector #50" /> 
+      <parameter name="Efixed"> <value val="3.386460" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65000" t="132.2444707" p="330.0" rot="240.0" name="Detector #51" /> 
+      <parameter name="Efixed"> <value val="3.520580" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66507" t="131.0761606" p="330.0" rot="240.0" name="Detector #52" /> 
+      <parameter name="Efixed"> <value val="3.665070" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67977" t="130.0048698" p="330.0" rot="240.0" name="Detector #53" /> 
+      <parameter name="Efixed"> <value val="3.823790" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.69574" t="128.9098389" p="330.0" rot="240.0" name="Detector #54" /> 
+      <parameter name="Efixed"> <value val="3.995720" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.71370" t="127.7553324" p="330.0" rot="240.0" name="Detector #55" /> 
+      <parameter name="Efixed"> <value val="4.183510" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="128.6289408" p="330.0" rot="240.0" name="Detector #56" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56356" t="140.8425303" p="390.0" rot="300.0" name="Detector #57" /> 
+      <parameter name="Efixed"> <value val="2.691220" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57218" t="139.7942880" p="390.0" rot="300.0" name="Detector #58" /> 
+      <parameter name="Efixed"> <value val="2.770220" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58014" t="138.8729233" p="390.0" rot="300.0" name="Detector #59" /> 
+      <parameter name="Efixed"> <value val="2.853400" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58958" t="137.8330566" p="390.0" rot="300.0" name="Detector #60" /> 
+      <parameter name="Efixed"> <value val="2.942070" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60177" t="136.5669120" p="390.0" rot="300.0" name="Detector #61" /> 
+      <parameter name="Efixed"> <value val="3.036440" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60821" t="135.9298424" p="390.0" rot="300.0" name="Detector #62" /> 
+      <parameter name="Efixed"> <value val="3.135540" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61705" t="135.0882797" p="390.0" rot="300.0" name="Detector #63" /> 
+      <parameter name="Efixed"> <value val="3.240510" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62989" t="133.9284248" p="390.0" rot="300.0" name="Detector #64" /> 
+      <parameter name="Efixed"> <value val="3.354510" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64195" t="132.9003934" p="390.0" rot="300.0" name="Detector #65" /> 
+      <parameter name="Efixed"> <value val="3.474760" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65498" t="131.8500731" p="390.0" rot="300.0" name="Detector #66" /> 
+      <parameter name="Efixed"> <value val="3.603410" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66910" t="130.7760529" p="390.0" rot="300.0" name="Detector #67" /> 
+      <parameter name="Efixed"> <value val="3.740930" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68430" t="129.6872876" p="390.0" rot="300.0" name="Detector #68" /> 
+      <parameter name="Efixed"> <value val="3.888930" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.69355" t="129.0560258" p="390.0" rot="300.0" name="Detector #69" /> 
+      <parameter name="Efixed"> <value val="4.043890" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="128.6289408" p="390.0" rot="300.0" name="Detector #70" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+  </type>
+
+  <type name="front">
+    <component type="tube" > 
+      <location r="0.56287" t="39.0711405" p="150.0" rot="60.0" name="Detector #71" /> 
+      <parameter name="Efixed"> <value val="2.690050" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57191" t="40.1736992" p="150.0" rot="60.0" name="Detector #72" /> 
+      <parameter name="Efixed"> <value val="2.766250" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57991" t="41.1010455" p="150.0" rot="60.0" name="Detector #73" /> 
+      <parameter name="Efixed"> <value val="2.860390" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58735" t="41.9261975" p="150.0" rot="60.0" name="Detector #74" /> 
+      <parameter name="Efixed"> <value val="2.952490" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60016" t="43.2704960" p="150.0" rot="60.0" name="Detector #75" /> 
+      <parameter name="Efixed"> <value val="3.052270" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60978" t="44.2223360" p="150.0" rot="60.0" name="Detector #76" /> 
+      <parameter name="Efixed"> <value val="3.156690" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62000" t="45.1845283" p="150.0" rot="60.0" name="Detector #77" /> 
+      <parameter name="Efixed"> <value val="3.267580" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63028" t="46.1057165" p="150.0" rot="60.0" name="Detector #78" /> 
+      <parameter name="Efixed"> <value val="3.385450" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64397" t="47.2663943" p="150.0" rot="60.0" name="Detector #79" /> 
+      <parameter name="Efixed"> <value val="3.512280" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65787" t="48.3749721" p="150.0" rot="60.0" name="Detector #80" /> 
+      <parameter name="Efixed"> <value val="3.648180" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67388" t="49.5735398" p="150.0" rot="60.0" name="Detector #81" /> 
+      <parameter name="Efixed"> <value val="3.792910" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68722" t="50.5144429" p="150.0" rot="60.0" name="Detector #82" /> 
+      <parameter name="Efixed"> <value val="3.947030" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70304" t="51.5687694" p="150.0" rot="60.0" name="Detector #83" /> 
+      <parameter name="Efixed"> <value val="4.112830" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="51.3710592" p="150.0" rot="60.0" name="Detector #84" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56463" t="39.2906118" p="210.0" rot="120.0" name="Detector #85" /> 
+      <parameter name="Efixed"> <value val="2.711270" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57336" t="40.3450198" p="210.0" rot="120.0" name="Detector #86" /> 
+      <parameter name="Efixed"> <value val="2.790290" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58214" t="41.3520046" p="210.0" rot="120.0" name="Detector #87" /> 
+      <parameter name="Efixed"> <value val="2.875850" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.59107" t="42.3261729" p="210.0" rot="120.0" name="Detector #88" /> 
+      <parameter name="Efixed"> <value val="2.968390" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60258" t="43.5143774" p="210.0" rot="120.0" name="Detector #89" /> 
+      <parameter name="Efixed"> <value val="3.069580" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61444" t="44.6670652" p="210.0" rot="120.0" name="Detector #90" /> 
+      <parameter name="Efixed"> <value val="3.179160" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62424" t="45.5699125" p="210.0" rot="120.0" name="Detector #91" /> 
+      <parameter name="Efixed"> <value val="3.297780" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63950" t="46.8952864" p="210.0" rot="120.0" name="Detector #92" /> 
+      <parameter name="Efixed"> <value val="3.428740" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65562" t="48.2000032" p="210.0" rot="120.0" name="Detector #93" /> 
+      <parameter name="Efixed"> <value val="3.571460" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66889" t="49.2084315" p="210.0" rot="120.0" name="Detector #94" /> 
+      <parameter name="Efixed"> <value val="3.725890" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68722" t="50.5144429" p="210.0" rot="120.0" name="Detector #95" /> 
+      <parameter name="Efixed"> <value val="3.897650" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70749" t="51.8541613" p="210.0" rot="120.0" name="Detector #96" /> 
+      <parameter name="Efixed"> <value val="4.086060" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.72794" t="53.1076678" p="210.0" rot="120.0" name="Detector #97" /> 
+      <parameter name="Efixed"> <value val="4.293330" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="51.3710592" p="210.0" rot="120.0" name="Detector #98" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56172" t="38.9264282" p="270.0" rot="180.0" name="Detector #99" /> 
+      <parameter name="Efixed"> <value val="2.710510" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56879" t="39.7999991" p="270.0" rot="180.0" name="Detector #100" /> 
+      <parameter name="Efixed"> <value val="2.788980" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57828" t="40.9155771" p="270.0" rot="180.0" name="Detector #101" /> 
+      <parameter name="Efixed"> <value val="2.874580" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58386" t="41.5434180" p="270.0" rot="180.0" name="Detector #102" /> 
+      <parameter name="Efixed"> <value val="3.068150" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.59803" t="43.0532807" p="270.0" rot="180.0" name="Detector #103" /> 
+      <parameter name="Efixed"> <value val="3.068150" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60932" t="44.1778730" p="270.0" rot="180.0" name="Detector #104" /> 
+      <parameter name="Efixed"> <value val="3.177850" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62343" t="45.4968910" p="270.0" rot="180.0" name="Detector #105" /> 
+      <parameter name="Efixed"> <value val="3.297760" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63560" t="46.5653543" p="270.0" rot="180.0" name="Detector #106" /> 
+      <parameter name="Efixed"> <value val="3.427800" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65215" t="47.9268411" p="270.0" rot="180.0" name="Detector #107" /> 
+      <parameter name="Efixed"> <value val="3.571110" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66709" t="49.0748892" p="270.0" rot="180.0" name="Detector #108" /> 
+      <parameter name="Efixed"> <value val="3.726370" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.68570" t="50.4097202" p="270.0" rot="180.0" name="Detector #109" /> 
+      <parameter name="Efixed"> <value val="3.897560" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70653" t="51.7929921" p="270.0" rot="180.0" name="Detector #110" /> 
+      <parameter name="Efixed"> <value val="4.087070" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.72616" t="53.0021741" p="270.0" rot="180.0" name="Detector #111" /> 
+      <parameter name="Efixed"> <value val="4.294290" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="51.3710592" p="270.0" rot="180.0" name="Detector #112" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56350" t="39.1499775" p="330.0" rot="240.0" name="Detector #113" /> 
+      <parameter name="Efixed"> <value val="2.713690" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57377" t="40.3931962" p="330.0" rot="240.0" name="Detector #114" /> 
+      <parameter name="Efixed"> <value val="2.802390" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58080" t="41.2015857" p="330.0" rot="240.0" name="Detector #115" /> 
+      <parameter name="Efixed"> <value val="2.893380" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.59264" t="42.4925653" p="330.0" rot="240.0" name="Detector #116" /> 
+      <parameter name="Efixed"> <value val="2.989900" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60046" t="43.3008959" p="330.0" rot="240.0" name="Detector #117" /> 
+      <parameter name="Efixed"> <value val="3.088330" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.61251" t="44.4841217" p="330.0" rot="240.0" name="Detector #118" /> 
+      <parameter name="Efixed"> <value val="3.192660" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62265" t="45.4263074" p="330.0" rot="240.0" name="Detector #119" /> 
+      <parameter name="Efixed"> <value val="3.299820" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63144" t="46.2069009" p="330.0" rot="240.0" name="Detector #120" /> 
+      <parameter name="Efixed"> <value val="3.410560" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64536" t="47.3802994" p="330.0" rot="240.0" name="Detector #121" /> 
+      <parameter name="Efixed"> <value val="3.528660" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.65448" t="48.1107094" p="330.0" rot="240.0" name="Detector #122" /> 
+      <parameter name="Efixed"> <value val="3.648260" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66854" t="49.1825423" p="330.0" rot="240.0" name="Detector #123" /> 
+      <parameter name="Efixed"> <value val="3.775230" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67979" t="49.9965449" p="330.0" rot="240.0" name="Detector #124" /> 
+      <parameter name="Efixed"> <value val="3.906190" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.69304" t="50.9097545" p="330.0" rot="240.0" name="Detector #125" /> 
+      <parameter name="Efixed"> <value val="4.042820" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="51.3710592" p="330.0" rot="240.0" name="Detector #126" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.56139" t="38.8847087" p="390.0" rot="300.0" name="Detector #127" /> 
+      <parameter name="Efixed"> <value val="2.688160" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.57304" t="40.3073375" p="390.0" rot="300.0" name="Detector #128" /> 
+      <parameter name="Efixed"> <value val="2.787040" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58139" t="41.2679558" p="390.0" rot="300.0" name="Detector #129" /> 
+      <parameter name="Efixed"> <value val="2.864760" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.58820" t="42.0183094" p="390.0" rot="300.0" name="Detector #130" /> 
+      <parameter name="Efixed"> <value val="2.952710" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60028" t="43.2826617" p="390.0" rot="300.0" name="Detector #131" /> 
+      <parameter name="Efixed"> <value val="3.048190" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.60831" t="44.0798864" p="390.0" rot="300.0" name="Detector #132" /> 
+      <parameter name="Efixed"> <value val="3.157880" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.62104" t="45.2797817" p="390.0" rot="300.0" name="Detector #133" /> 
+      <parameter name="Efixed"> <value val="3.268740" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.63551" t="46.5576713" p="390.0" rot="300.0" name="Detector #134" /> 
+      <parameter name="Efixed"> <value val="3.394370" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.64570" t="47.4080548" p="390.0" rot="300.0" name="Detector #135" /> 
+      <parameter name="Efixed"> <value val="3.524460" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.66097" t="48.6133244" p="390.0" rot="300.0" name="Detector #136" /> 
+      <parameter name="Efixed"> <value val="3.664730" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.67463" t="49.6277789" p="390.0" rot="300.0" name="Detector #137" /> 
+      <parameter name="Efixed"> <value val="3.811590" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.69126" t="50.7897939" p="390.0" rot="300.0" name="Detector #138" /> 
+      <parameter name="Efixed"> <value val="3.968720" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70513" t="51.7033958" p="390.0" rot="300.0" name="Detector #139" /> 
+      <parameter name="Efixed"> <value val="4.134120" /> </parameter>
+    </component> 
+    <component type="tube" > 
+      <location r="0.70000" t="51.3710592" p="390.0" rot="300.0" name="Detector #140" /> 
+      <parameter name="Efixed"> <value val="4.000000" /> </parameter>
+    </component>
+  </type>
+
+  <type name="diffraction">
+    <!-- Detector ID 170 -->
+    <component type="tube" > 
+      <location r="0.1" t="49.6277789" p="30" rot="300.0" name="Diff #1" /> 
+    </component>
+    <!-- Detector ID 171 -->
+    <component type="tube" > 
+      <location r="0.12" t="50.7897939" p="30" rot="300.0" name="Diff #2" /> 
+    </component> 
+    <!-- Detector ID 172 -->
+    <component type="tube" > 
+      <location r="0.14" t="51.7033958" p="30" rot="300.0" name="Diff #3" /> 
+    </component> 
+    <!-- For some reason Detector ID 15 (FIFTEEN) is next (?) -->
+    <component type="tube" > 
+      <location r="0.16" t="51.3710592" p="30" rot="300.0" name="Diff #4" /> 
+    </component>
+    <!-- ... 177 --> <!-- (Spectra 146) -->
+    <component type="tube" > 
+      <location r="1.21" t="179" p="0" rot="0" name="Diff #5" /> 
+    </component> 
+    <!-- ... 178 -->
+    <component type="tube" > 
+      <location r="1.21" t="179" p="0" rot="0" name="Diff #6" /> 
+    </component>
+    <!-- ... 179 -->    
+    <component type="tube" > 
+      <location r="1.21" t="179" p="0" rot="0" name="Diff #7" /> 
+    </component>
+    <!-- ... 180 -->
+    <component type="tube" > 
+      <location r="1.21" t="179" p="0" rot="0" name="Diff #8" /> 
+    </component>
+  </type>
+
+  <type name="tube" is="detector">
+    <cylinder id="shape">
+      <centre-of-bottom-base x="-0.03" y="0.0" z="0.0" />
+      <axis x="1.0" y="0.0" z="0" />
+      <radius val="0.005" />
+      <height val="0.06" />
+    </cylinder>
+    <algebra val="shape" />
+  </type>  
+
+  <!-- DETECTOR ID LISTS -->
+
+  <idlist idname="back">
+    <id start="1" end="14" />
+    <id start="17" end="30" />
+    <id start="33" end="46" />
+    <id start="49" end="62" />
+    <id start="65" end="78" />
+  </idlist>
+
+  <idlist idname="front">
+    <id start="81" end="94" />
+    <id start="97" end="110" />
+    <id start="113" end="126" />
+    <id start="129" end="142" />	
+    <id start="145" end="158" />
+  </idlist>
+
+  <idlist idname="monitor1">
+    <id val="194" />
+  </idlist>
+
+  <idlist idname="diffraction">
+    <id start="170" end="173" />
+    <!-- Having this value as 15 causes problems in the ConvertToEnergy scripts
+    <id val="15" /> -->
+    <id start="177" end="180" />
+  </idlist>  
+
+</instrument>
diff --git a/instrument/TOSCA_Parameters.xml b/instrument/TOSCA_Parameters.xml
index ee9239c9b9b42b99dc68410150643bea1f69b72b..363ccd05c05bd3aef477dae983ac4ff87d97ce87 100644
--- a/instrument/TOSCA_Parameters.xml
+++ b/instrument/TOSCA_Parameters.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <parameter-file instrument="TOSCA"
   valid-from="2000-03-31 15:20:00"
-  valid-to="2100-01-31 23:59:59" >
+  valid-to="2016-11-25 23:59:59" >
 
   <component-link name = "TOSCA">
 
diff --git a/instrument/TOSCA_Parameters_2016.xml b/instrument/TOSCA_Parameters_2016.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a005d1d1b6fae53e4bc7b5672df2ca7abaf64701
--- /dev/null
+++ b/instrument/TOSCA_Parameters_2016.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<parameter-file instrument="TOSCA"
+  valid-from="2016-11-25 23:59:59"
+  valid-to="2100-01-31 23:59:59" >
+
+  <component-link name = "TOSCA">
+
+    <parameter name="deltaE-mode" type="string">
+      <value val="indirect"/>
+    </parameter>
+
+    <!-- These properties are neceessary for use in the Indirect CTE interface. -->
+    <parameter name="analysers" type="string">
+      <value val="graphite,diffraction" />
+    </parameter>
+    <parameter name="refl-graphite" type="string">
+      <value val="002" />
+    </parameter>
+    <parameter name="refl-diffraction" type="string">
+      <value val="diffspec" />
+    </parameter>
+
+    <!-- Available options are "true" or "false". -->
+    <parameter name="cm-1-convert-choice" type="string">
+      <value val="true" />
+    </parameter>
+    <parameter name="save-nexus-choice" type="string">
+      <value val="false" />
+    </parameter>
+    <parameter name="save-ascii-choice" type="string">
+      <value val="true" />
+    </parameter>
+    <parameter name="fold-frames-choice" type="string">
+      <value val="true" />
+    </parameter>
+
+    <!-- This parameter will be taken as a default value for the rebinning of
+            the data in DeltaE. The existence of the parameter will make rebinning
+            the default, as opposed to not rebinning.
+            This is necessary so that the spectra can be grouped.
+    -->
+    <parameter name="rebin-default" type="string">
+      <value val="-2.5,0.015,3,-0.005,1000" />
+    </parameter>
+
+    <!-- Reduction workflow parameters under this line -->
+    <parameter name="Workflow.InfoTable" type="string">
+      <value val="inst_abrv, run_number, user_name, run_title, hd_dur" />
+    </parameter>
+
+    <!-- This is actually spectrum index, NOT spectrum number -->
+    <parameter name="Workflow.Monitor1-SpectrumNumber" >
+      <value val="141" />
+    </parameter>
+    <parameter name="Workflow.Monitor1-Area" >
+      <value val="5.391011e-5" />
+    </parameter>
+    <parameter name="Workflow.Monitor1-Thickness" >
+      <value val="0.013" />
+    </parameter>
+    <parameter name="Workflow.Monitor1-ScalingFactor">
+      <value val="1e9" />
+    </parameter>
+    <parameter name="Workflow.Monitor1-Attenuation" >
+      <value val="8.3" />
+    </parameter>
+
+    <parameter name="Workflow.UnwrapMonitor" type="string">
+      <value val="Never" />
+    </parameter>
+    <parameter name="Workflow.ChopDataIfGreaterThan">
+      <value val="40000" />
+    </parameter>
+    <parameter name="Workflow.GroupingMethod" type="string">
+      <value val="File" />
+    </parameter>
+    <parameter name="Workflow.GroupingFile" type="string">
+      <value val="TOSCA_Grouping.xml" />
+    </parameter>
+    <parameter name="Workflow.Masking" type="string">
+      <value val="IdentifyNoisyDetectors" />
+    </parameter>
+
+  </component-link>
+
+</parameter-file>
diff --git a/scripts/Calibration/tube.py b/scripts/Calibration/tube.py
index cb1a97d2e8fdf5a0233f5fac5a8cff3d0c0475fb..4d091ecd8212459c70c7775674d48c5e7a3d2d4d 100644
--- a/scripts/Calibration/tube.py
+++ b/scripts/Calibration/tube.py
@@ -1,11 +1,26 @@
 # pylint: disable=invalid-name
-"""
+import numpy
+import os
+import re
+
+from mantid.kernel import V3D
+from mantid.api import (MatrixWorkspace, ITableWorkspace)
+from mantid.simpleapi import (mtd, CreateEmptyTableWorkspace, DeleteWorkspace, config)
+from tube_spec import TubeSpec
+from ideal_tube import IdealTube
+from tube_calib_fit_params import TubeCalibFitParams
+from tube_calib import getCalibration
+
+# Need to avoid flake8 warning but we can't do that with this
+# buried directly in the string
+CALIBRATE_SIGNATURE = "ws, tubeSet, knownPositions, funcForm, [fitPar, margin, rangeList, calibTable, plotTube, excludeShorTubes, overridePeaks, fitPolyn, outputPeak]" # noqa
+
+__doc__ = _MODULE_DOC="""
 =========================
 Definition of Calibration
 =========================
 
-.. autofunction:: tube.calibrate(ws, tubeSet, knownPositions, funcForm, [fitPar, margin, rangeList, calibTable,
-                                 plotTube, excludeShorTubes, overridePeaks, fitPolyn, outputPeak])
+.. autofunction:: calibrate({0})
 
 =========
 Use Cases
@@ -49,19 +64,7 @@ Other Useful Methods
 
 .. autofunction:: tube.readCalibrationFile
 
-"""
-
-import numpy
-import os
-import re
-
-from mantid.kernel import V3D
-from mantid.api import (MatrixWorkspace, ITableWorkspace)
-from mantid.simpleapi import (mtd, CreateEmptyTableWorkspace, DeleteWorkspace, config)
-from tube_spec import TubeSpec
-from ideal_tube import IdealTube
-from tube_calib_fit_params import TubeCalibFitParams
-from tube_calib import getCalibration
+""".format(CALIBRATE_SIGNATURE)
 
 
 def calibrate(ws, tubeSet, knownPositions, funcForm, **kwargs):
diff --git a/scripts/CompareFitMinimizers/fitting_benchmarking.py b/scripts/CompareFitMinimizers/fitting_benchmarking.py
new file mode 100644
index 0000000000000000000000000000000000000000..fb4e9890e83eddd5464f60a0a391634728a87f20
--- /dev/null
+++ b/scripts/CompareFitMinimizers/fitting_benchmarking.py
@@ -0,0 +1,404 @@
+"""
+Classes and utility functions to support benchmarking of fitting minimizers in
+Mantid or other packages useable from Python.  These benchmarks are
+focused on comparing different minimizers in terms of accuracy and
+computation time.
+"""
+# 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>
+
+from __future__ import (absolute_import, division, print_function)
+
+import os
+import time
+
+import numpy as np
+
+import mantid.simpleapi as msapi
+
+import input_parsing as iparsing
+import results_output as fitout
+import test_result
+
+
+def run_all_with_or_without_errors(base_problem_files_dir, use_errors, minimizers,
+                                   group_names, group_suffix_names, color_scale, save_to_file=False):
+    """
+    Run all benchmark problems available, with/without using weights in the cost
+    function. This is just a convenience function meant to be used by system/unit tests, or other scripts
+
+    ALL means: NIST + CUTEST + any fitting problems against observed Neutron data (+ any other
+    which may be added in the future)
+
+    At this point in time it is assumed that the problem files are in store relative to
+    a base_problem_files_dir as follows:
+
+        CUTEst/
+        NIST_nonlinear_regression/
+        Neutron_data/
+
+    Be warned this function can be verbose.
+
+    @param base_problem_files_dir :: base directory path of all the benchmark problems
+    @param use_errors :: whether to use observational errors as weights in the cost function
+    @param minimizers :: list of minimizers to test
+    @param group_names :: names for display purposes
+    @param group_suffix_names :: group names to use as suffixes, for example in file names
+    @param color_scale :: list with pairs of threshold value - color, to produce color
+    @param save_to_file :: whether to save the table outputs to files following specific naming conventions
+    """
+
+    # Assume the benchmark problems are stores as follows
+    nist_group_dir = os.path.join(base_problem_files_dir, 'NIST_nonlinear_regression')
+    cutest_group_dir = os.path.join(base_problem_files_dir, 'CUTEst')
+    neutron_data_group_dirs = [os.path.join(base_problem_files_dir, 'Neutron_data')]
+
+    problems, results_per_group = do_fitting_benchmark(nist_group_dir=nist_group_dir,
+                                                       cutest_group_dir=cutest_group_dir,
+                                                       neutron_data_group_dirs=neutron_data_group_dirs,
+                                                       minimizers=minimizers, use_errors=use_errors)
+
+    # Results for every test problem in each group
+    for idx, group_results in enumerate(results_per_group):
+        print("\n\n")
+        print("********************************************************")
+        print("**************** RESULTS FOR GROUP {0}, {1} ************".format(idx+1,
+                                                                                group_names[idx]))
+        print("********************************************************")
+        fitout.print_group_results_tables(minimizers, group_results, problems[idx],
+                                          group_name=group_suffix_names[idx],
+                                          use_errors=use_errors,
+                                          simple_text=True, rst=True, save_to_file=save_to_file,
+                                          color_scale=color_scale)
+
+    # Results aggregated (median) by group (NIST, Neutron data, CUTEst, etc.)
+    header = '\n\n**************** OVERALL SUMMARY - ALL GROUPS ******** \n\n'
+    print(header)
+    fitout.print_overall_results_table(minimizers, results_per_group, problems, group_names,
+                                       use_errors=use_errors, save_to_file=save_to_file)
+
+    # Flush to reduce mix-up with system tests/runner output
+    import sys
+    sys.stdout.flush()
+
+
+def do_fitting_benchmark(nist_group_dir=None, cutest_group_dir=None, neutron_data_group_dirs=None,
+                         minimizers=None, use_errors=True):
+    """
+    Run a fit minimizer benchmark against groups of fitting problems.
+
+    Unless group directories of fitting problems are specified no fitting benchmarking is done.
+
+    NIST and CUTEst refer to the NIST and CUTEst fitting test problem sets, where
+    for example CUTEst is used for fit tests in the mathematical numerical literature.
+
+    The Neutron_data group contain fit tests against real noisy experimental neutron data.
+    This latter group may grow to contain fitting example from multiple directories.
+
+    @param nist_group_dir :: whether to try to load NIST problems
+    @param cutest_group_dir :: whether to try to load CUTEst problems
+    @param neutron_data_group_dirs :: base directory where fitting problems are located including NIST+CUTEst
+    @param minimizers :: list of minimizers to test
+    @param use_errors :: whether to use observational errors as weights in the cost function
+    """
+
+    # Several blocks of problems. Results for each block will be calculated sequentially, and
+    # will go into a separate table
+    problem_blocks = []
+
+    if nist_group_dir:
+        # get NIST problems grouped into blocks of problems, in blocks of increasing difficulty
+        problem_blocks.extend(get_nist_problem_files(nist_group_dir))
+
+    if cutest_group_dir:
+        # get CUTEet problems - just treated as one block of problems
+        problem_blocks.extend([get_cutest_problem_files(cutest_group_dir)])
+
+    if neutron_data_group_dirs:
+        problem_blocks.extend(get_data_groups(neutron_data_group_dirs))
+
+    prob_results = [do_fitting_benchmark_group(block, minimizers, use_errors=use_errors) for
+                    block in problem_blocks]
+
+    probs, results = zip(*prob_results)
+
+    if len(probs) != len(results):
+        raise RuntimeError('probs : {0}, prob_results: {1}'.format(len(probs), len(results)))
+
+    return probs, results
+
+
+def do_fitting_benchmark_group(problem_files, minimizers, use_errors=True):
+    """
+    Applies minimizers to a group (collection) of test problems. For example the
+    collection of all NIST problems
+
+    @param problem_files :: a list of list of files that define a group of
+    test problems. For example all the NIST files sub-groupped according to level
+    of fitting difficulty, where the lowest list level list the file names
+
+    @param minimizers :: list of minimizers to test
+    @param use_errors :: whether to use observational errors as weights in the cost function
+
+    @returns :: problem definitions loaded from the files, and results of running them with
+    the minimizers requested
+    """
+
+    problems = []
+    results_per_problem = []
+    for prob_file in problem_files:
+        try:
+            # Note the CUTEst problem are assumed to be expressed in NIST format
+            prob = iparsing.load_nist_fitting_problem_file(prob_file)
+        except (AttributeError, RuntimeError):
+            prob = iparsing.load_neutron_data_fitting_problem_file(prob_file)
+
+        print("* Testing fitting for problem definition file {0}".format(prob_file))
+        print("* Testing fitting of problem {0}".format(prob.name))
+
+        results_prob = do_fitting_benchmark_one_problem(prob, minimizers, use_errors)
+        results_per_problem.extend(results_prob)
+
+    return problems, results_per_problem
+
+
+def do_fitting_benchmark_one_problem(prob, minimizers, use_errors=True):
+    """
+    One problem with potentially several starting points, returns a list (start points) of
+    lists (minimizers).
+
+    @param prob :: fitting problem
+    @param minimizers :: list of minimizers to evaluate/compare
+    @param use_errors :: whether to use observational errors when evaluating accuracy (in the
+                         cost function)
+    """
+
+    wks, cost_function = prepare_wks_cost_function(prob, use_errors)
+
+    # Each NIST problem generate two results per file - from two different starting points
+    results_fit_problem = []
+
+    # Get function definitions for the problem - one for each starting point
+    function_defs = get_function_definitions(prob)
+
+    # Loop over the different starting points
+    for user_func in function_defs:
+        results_problem_start = []
+        for minimizer_name in minimizers:
+            t_start = time.clock()
+
+            status, chi2, fit_wks, params, errors = run_fit(wks, prob, function=user_func,
+                                                            minimizer=minimizer_name,
+                                                            cost_function=cost_function)
+            t_end = time.clock()
+            print("*** with minimizer {0}, Status: {1}, chi2: {2}".format(minimizer_name, status, chi2))
+            print("   params: {0}, errors: {1}".format(params, errors))
+
+            def sum_of_squares(values):
+                return np.sum(np.square(values))
+
+            if fit_wks:
+                sum_err_sq = sum_of_squares(fit_wks.readY(2))
+                # print " output simulated values: {0}".format(fit_wks.readY(1))
+            else:
+                sum_err_sq = float("inf")
+                print(" WARNING: no output fit workspace")
+
+            print("   sum sq: {0}".format(sum_err_sq))
+
+            result = test_result.FittingTestResult()
+            result.problem = prob
+            result.fit_status = status
+            result.fit_chi2 = chi2
+            result.params = params
+            result.errors = errors
+            result.sum_err_sq = sum_err_sq
+            result.runtime = t_end - t_start
+            print("Result object: {0}".format(result))
+            results_problem_start.append(result)
+
+        results_fit_problem.append(results_problem_start)
+
+    return results_fit_problem
+
+
+def run_fit(wks, prob, function, minimizer='Levenberg-Marquardt', cost_function='Least squares'):
+    """
+    Fits the data in a workspace with a function, using the algorithm Fit.
+    Importantly, the option IgnoreInvalidData is enabled. Check the documentation of Fit for the
+    implications of this.
+
+    @param wks :: MatrixWorkspace with data to fit, in the format expected by the algorithm Fit
+    @param prob :: Problem definition
+    @param function :: function definition as used in the algorithm Fit
+    @param minimizer :: minimizer to use in Fit
+    @param cost_function :: cost function to use in Fit
+
+    @returns the fitted parameter values and error estimates for these
+    """
+    status = None
+    chi2 = None
+    param_tbl = None
+    fit_wks = None
+    try:
+        # When using 'Least squares' (weighted by errors), ignore nans and zero errors, but don't
+        # ignore them when using 'Unweighted least squares' as that would ignore all values!
+        ignore_invalid = cost_function == 'Least squares'
+
+        # Note the ugly adhoc exception. We need to reconsider these WISH problems:
+        if 'WISH17701' in prob.name:
+            ignore_invalid = False
+
+        status, chi2, covar_tbl, param_tbl, fit_wks = msapi.Fit(function, wks, Output='ws_fitting_test',
+                                                                Minimizer=minimizer,
+                                                                CostFunction=cost_function,
+                                                                IgnoreInvalidData=ignore_invalid,
+                                                                StartX=prob.start_x, EndX=prob.end_x)
+
+        calc_chi2 = msapi.CalculateChiSquared(Function=function,
+                                              InputWorkspace=wks, IgnoreInvalidData=ignore_invalid)
+        print("*** with minimizer {0}, calculated: chi2: {1}".format(minimizer, calc_chi2))
+
+    except RuntimeError as rerr:
+        print("Warning, Fit probably failed. Going on. Error: {0}".format(str(rerr)))
+
+    if param_tbl:
+        params = param_tbl.column(1)[:-1]
+        errors = param_tbl.column(2)[:-1]
+    else:
+        params = None
+        errors = None
+
+    return status, chi2, fit_wks, params, errors
+
+
+def prepare_wks_cost_function(prob, use_errors):
+    """
+    Build a workspace ready for Fit() and a cost function string according to the problem
+    definition.
+    """
+    if use_errors:
+        data_e = None
+        if not isinstance(prob.data_pattern_obs_errors, np.ndarray):
+            # Fake observational errors
+            data_e = np.sqrt(prob.data_pattern_in)
+        else:
+            data_e = prob.data_pattern_obs_errors
+
+        wks = msapi.CreateWorkspace(DataX=prob.data_pattern_in, DataY=prob.data_pattern_out,
+                                    DataE=data_e)
+        cost_function = 'Least squares'
+    else:
+        wks = msapi.CreateWorkspace(DataX=prob.data_pattern_in, DataY=prob.data_pattern_out)
+        cost_function = 'Unweighted least squares'
+
+    return wks, cost_function
+
+
+def get_function_definitions(prob):
+    """
+    Produces function definition strings (as a full definition in
+    muparser format, including the function and the initial values for
+    the parameters), one for every different starting point defined in
+    the test problem.
+
+    @param prob :: fitting test problem object
+
+    @returns :: list of function strings ready for Fit()
+    """
+    function_defs = []
+    if prob.starting_values:
+        num_starts = len(prob.starting_values[0][1])
+        for start_idx in range(0, num_starts):
+
+            print("=================== starting values,: {0}, with idx: {1} ================".
+                  format(prob.starting_values, start_idx))
+            start_string = ''  # like: 'b1=250, b2=0.0005'
+            for param in prob.starting_values:
+                start_string += ('{0}={1},'.format(param[0], param[1][start_idx]))
+
+            if 'name' in prob.equation:
+                function_defs.append(prob.equation)
+            else:
+                function_defs.append("name=UserFunction, Formula={0}, {1}".format(prob.equation, start_string))
+    else:
+        # Equation from a neutron data spec file. Ready to be used
+        function_defs.append(prob.equation)
+
+    return function_defs
+
+
+def get_nist_problem_files(search_dir):
+    """
+    Group the NIST problem files into separeate blocks according
+    to assumed fitting different levels: lower, average,
+    higher.
+
+    @returns :: list of list of problem files
+    """
+    # Grouped by "level of difficulty"
+    nist_lower = ['Misra1a.dat', 'Chwirut2.dat', 'Chwirut1.dat', 'Lanczos3.dat',
+                  'Gauss1.dat', 'Gauss2.dat', 'DanWood.dat', 'Misra1b.dat']
+
+    nist_average = ['Kirby2.dat', 'Hahn1.dat',
+                    # 'Nelson.dat' needs log[y] parsing / DONE, needs x1, x2
+                    'MGH17.dat', 'Lanczos1.dat', 'Lanczos2.dat', 'Gauss3.dat',
+                    'Misra1c.dat', 'Misra1d.dat',
+                    # 'Roszman1.dat' <=== needs handling the  'pi = 3.1415...' / DOME
+                    # And the 'arctan()'/ DONE, but generated lots of NaNs
+                    'ENSO.dat']
+    nist_higher = ['MGH09.dat', 'Thurber.dat', 'BoxBOD.dat', 'Rat42.dat',
+                   'MGH10.dat', 'Eckerle4.dat', 'Rat43.dat', 'Bennett5.dat']
+
+    nist_lower_files = [os.path.join(search_dir, fname) for fname in nist_lower]
+    nist_average_files = [os.path.join(search_dir, fname) for fname in nist_average]
+    nist_higher_files = [os.path.join(search_dir, fname) for fname in nist_higher]
+    problem_files = [nist_lower_files, nist_average_files, nist_higher_files]
+
+    return problem_files
+
+
+def get_cutest_problem_files(search_dir):
+
+    cutest_all = ['PALMER6C.dat', 'PALMER7C.dat', 'PALMER8C.dat', 'YFITU.dat', 'VESUVIOLS.dat', 'DMN15102LS.dat']
+
+    cutest_files = [os.path.join(search_dir, fname) for fname in cutest_all]
+
+    return cutest_files
+
+
+def get_data_groups(data_groups_dirs):
+
+    problem_groups = []
+    for grp_dir in data_groups_dirs:
+        problem_groups.append(get_data_group_problem_files(grp_dir))
+
+    return problem_groups
+
+
+def get_data_group_problem_files(grp_dir):
+    import glob
+
+    search_str = os.path.join(grp_dir, "*.txt")
+    probs = glob.glob(search_str)
+
+    probs.sort()
+    print ("Found test problem files: ", probs)
+    return probs
diff --git a/scripts/CompareFitMinimizers/input_parsing.py b/scripts/CompareFitMinimizers/input_parsing.py
new file mode 100644
index 0000000000000000000000000000000000000000..641c3ba41b855f47d9c6e22a96e80367e9defa4a
--- /dev/null
+++ b/scripts/CompareFitMinimizers/input_parsing.py
@@ -0,0 +1,271 @@
+"""
+Parse input files describing fitting test examples and load the
+information into problem objects
+
+"""
+# 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>
+
+from __future__ import (absolute_import, division, print_function)
+
+import os
+import re
+
+import numpy as np
+
+import test_problem
+
+
+def load_nist_fitting_problem_file(problem_filename):
+    with open(problem_filename) as spec_file:
+        return parse_nist_file(spec_file)
+
+
+def parse_data_pattern(data_text):
+    """
+    Parses the data part of a NIST test problem file (the columns of
+    values) and produces a numpy array with the data.
+
+    """
+    if not data_text:
+        return None
+
+    first = data_text[0].strip()
+    dim = len(first.split())
+    data_points = np.zeros((len(data_text), dim))
+
+    for idx, line in enumerate(data_text):
+        line = line.strip()
+        point_text = line.split()
+        point = [float(val) for val in point_text]
+        data_points[idx, :] = point
+
+    return data_points
+
+
+def parse_equation(eq_text):
+    """
+    Parses the equation text (possibly multi-line) and does a rough
+    conversion from NIST equation format to muparser format
+
+    @param eq_text :: equation formula as given in a NIST problem description
+    @return formula ready to be used in the 'Formula=' of functions 'UserFunction' of
+            the Fit algorithm
+    """
+    start_normal = r'\s*y\s*=(.+)'
+    start_log = r'\s*log\[y\]\s*=(.+)'
+    # try first the usual syntax
+    if re.match(start_normal, eq_text):
+        match = re.search(r'y\s*=(.+)\s*\+\s*e', eq_text)
+        equation = match.group(1).strip()
+    # log-syntax used in NIST/Nelson
+    elif re.match(start_log, eq_text):
+        match = re.search(r'log\[y\]\s*=(.+)\s*\+\s*e', eq_text)
+        equation = "exp(" + match.group(1).strip() + ")"
+    else:
+        raise RuntimeError("Unrecognized equation syntax when trying to parse a NIST "
+                           "equation: " + eq_text)
+
+    # 'NIST equation syntax' => muparser syntax
+    # brackets for muparser
+    equation = equation.replace('[', '(')
+    equation = equation.replace(']', ')')
+    equation = equation.replace('arctan', 'atan')
+    equation = equation.replace('**', '^')
+    return equation
+
+
+def parse_starting_values(lines):
+    starting_vals = []
+    for line in lines:
+        if not line.strip() or line.startswith('Residual'):
+            break
+
+        comps = line.split()
+        if 6 != len(comps) and 5 != len(comps):
+            raise RuntimeError("Failed to parse this line as starting "
+                               "values information: {0}".format(line))
+
+        # A bit weak/lax parsing, if there is one less column, assume only one start point
+        if 6 == len(comps):
+            alt_values = [float(comps[2]), float(comps[3])]
+        elif 5 == len(comps):
+            alt_values = [float(comps[2])]
+
+        starting_vals.append([comps[0], alt_values])
+
+    return starting_vals
+
+
+def parse_nist_file(spec_file):
+    """
+    Produce a fitting test problem definition object from a NIST text file.
+
+    @param spec_file :: input file, as a standard NIST text (.dat) file
+    """
+
+    lines = spec_file.readlines()
+    equation_text, data_pattern_text, starting_values, residual_sum_sq = parse_nist_file_line_by_line(lines)
+
+    if not equation_text or not data_pattern_text:
+        raise RuntimeError('Could not find the equation and data after parsing the lines of this file: {0}'.
+                           format(spec_file.name))
+
+    data_pattern = parse_data_pattern(data_pattern_text)
+    parsed_eq = parse_equation(equation_text)
+
+    prob = test_problem.FittingTestProblem()
+    prob.name = os.path.basename(spec_file.name)
+    prob.linked_name = ("`{0} <http://www.itl.nist.gov/div898/strd/nls/data/{1}.shtml>`__".
+                        format(prob.name, prob.name.lower()))
+    prob.equation = parsed_eq
+    prob.starting_values = starting_values
+    prob.data_pattern_in = data_pattern[:, 1:]
+    prob.data_pattern_out = data_pattern[:, 0]
+    prob.ref_residual_sum_sq = residual_sum_sq
+
+    return prob
+
+
+def parse_nist_file_line_by_line(lines):
+    """
+    Get several relevant pieces of information from the lines of a NIST problem file
+    This parser is far from great but it does the job.
+
+    @param lines :: lines as directly loaded from a file
+
+    @returns :: the equation string, the data string, the starting values, and the
+    certified chi^2, as found in the text lines
+    """
+
+    idx, data_idx = 0, 0
+    data_pattern_text = None
+    residual_sum_sq = 0
+    equation_text = None
+    starting_values = None
+    # The first line should be:
+    # NIST/ITL StRD
+    while idx < len(lines):
+        line = lines[idx].strip()
+        idx += 1
+
+        if not line:
+            continue
+
+        if line.startswith('Model:'):
+            # Would skip number of parameters, and empty line, but not
+            # adequate for all test problems
+            # idx += 3
+
+            # Before 'y = ...' there can be lines like 'pi = 3.14159...'
+            while (not re.match(r'\s*y\s*=(.+)', lines[idx])
+                   and not re.match(r'\s*log\[y\]\s*=(.+)', lines[idx]))\
+                   and idx < len(lines):  # [\s*\+\s*e]
+                idx += 1
+            # Next non-empty lines are assumed to continue the equation
+            equation_text = ''
+            while lines[idx].strip():
+                equation_text += lines[idx].strip()
+                idx += 1
+
+        elif 'Starting values' in line or 'Starting Values' in line:
+            # 1 empty line, and one heading line before values
+            idx += 2
+            starting_values = parse_starting_values(lines[idx:])
+            idx += len(starting_values)
+
+        elif line.startswith('Residual Sum of Squares'):
+            residual_sum_sq = float(line.split()[4])
+
+        elif line.startswith('Data:'):
+            if 0 == data_idx:
+                data_idx += 1
+            elif 1 == data_idx:
+                data_pattern_text = lines[idx:]
+                idx = len(lines)
+            else:
+                raise RuntimeError('Error parsing data line: {}'.format(line))
+        else:
+            print("unknown line in supposedly NIST test file, ignoring: {0}".format(line))
+
+    return equation_text, data_pattern_text, starting_values, residual_sum_sq
+
+
+def load_neutron_data_fitting_problem_file(fname):
+    """
+    Builds a FittingTestProblem object from a text file. The file is expected to
+    have a list of variables (input filename, name, equation, etc.)
+
+    Other alternatives could be ConfigParser (ini format, parser not extermely
+    good), or JSON.
+
+    @param fname :: name of the file to load
+    """
+    with open(fname) as probf:
+        entries = get_neutron_data_problem_entries(probf)
+
+        prob = test_problem.FittingTestProblem()
+        get_fitting_neutron_data(entries['input_file'], prob)
+        prob.name = entries['name']
+        prob.equation = entries['function']
+        prob.starting_values = None
+        if 'fit_parameters' in entries:
+            prob.start_x = entries['fit_parameters']['StartX']
+            prob.end_x = entries['fit_parameters']['EndX']
+
+    return prob
+
+
+def get_neutron_data_problem_entries(problem_file):
+    """
+    Get values from the lines of a "neutron fitting problem definition file",
+    They are returned as a dictionary of key (lhs) - value (rhs).
+    """
+    entries = {}
+    for line in problem_file:
+        # discard comments
+        line = line.partition('#')[0]
+        line = line.rstrip()
+        if not line:
+            continue
+
+        # take values (lhs = rhs)
+        lhs, rhs = line.split("=", 1)
+        # assumes it is safe to evaluate the rhs (it's a string for example)
+        entries[lhs.strip()] = eval(rhs.strip())
+
+    return entries
+
+
+def get_fitting_neutron_data(fname, prob):
+    """
+    Load the X-Y-E data from a file and put the values into a fitting problem
+    definition object.
+
+    @param fname :: file name to load (using mantid loaders)
+    @param prob :: problem definition to populate with X-Y-E data.
+    """
+    import mantid.simpleapi as msapi
+
+    wks = msapi.Load(fname)
+    prob.data_pattern_in = wks.readX(0)
+    prob.data_pattern_out = wks.readY(0)
+    prob.data_pattern_obs_errors = wks.readE(0)
+    prob.ref_residual_sum_sq = 0
diff --git a/scripts/CompareFitMinimizers/post_processing.py b/scripts/CompareFitMinimizers/post_processing.py
new file mode 100644
index 0000000000000000000000000000000000000000..2a947ace4b06391f913fb735f7908c4bbf5a56e9
--- /dev/null
+++ b/scripts/CompareFitMinimizers/post_processing.py
@@ -0,0 +1,115 @@
+# 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>
+
+import numpy as np
+from scipy import stats  # older version of numpy does not support nanmean and nanmedian
+
+
+def calc_summary_table(minimizers, group_results):
+    """
+    Calculates a summary from problem-individual results. At the moment the only summary
+    statistic calculated is the median. The output is produced as numpy matrices.
+
+    @param minimizers :: list of minimizers used (their names)
+
+    @param group_results :: results from running fitting tests on different problems (list
+    of lists, where the first level is the group, and the second level is the individual test).
+
+
+    @returns two numpy matrices (where columns are the groups, and rows are the minimizers)
+    with summary statistic (median) from the problem-individual results.
+    """
+
+    num_groups = len(group_results)
+    num_minimizers = len(minimizers)
+
+    groups_norm_acc = np.zeros((num_groups, num_minimizers))
+    groups_norm_runtime = np.zeros((num_groups, num_minimizers))
+    for group_idx, results_per_test in enumerate(group_results):
+        num_tests = len(results_per_test)
+        accuracy_tbl = np.zeros((num_tests, num_minimizers))
+        time_tbl = np.zeros((num_tests, num_minimizers))
+
+        for test_idx in range(0, num_tests):
+            for minimiz_idx in range(0, num_minimizers):
+                accuracy_tbl[test_idx, minimiz_idx] = results_per_test[test_idx][minimiz_idx].sum_err_sq
+                time_tbl[test_idx, minimiz_idx] = results_per_test[test_idx][minimiz_idx].runtime
+
+        # Min across all alternative runs/minimizers
+        min_sum_err_sq = np.nanmin(accuracy_tbl, 1)
+        min_runtime = np.nanmin(time_tbl, 1)
+
+        norm_acc_rankings = accuracy_tbl / min_sum_err_sq[:, None]
+        norm_runtime_rankings = time_tbl / min_runtime[:, None]
+
+        groups_norm_acc[group_idx, :] = stats.nanmedian(norm_acc_rankings, 0)
+        groups_norm_runtime[group_idx, :] = stats.nanmedian(norm_runtime_rankings, 0)
+
+    return groups_norm_acc, groups_norm_runtime
+
+
+def calc_accuracy_runtime_tbls(results_per_test, minimizers):
+    """
+    This produces a numpy matrix for convenience, with
+    1 row per problem+start, 1 column per minimizer
+    """
+    num_tests = len(results_per_test)
+    num_minimizers = len(minimizers)
+    accuracy_tbl = np.zeros((num_tests, num_minimizers))
+    time_tbl = np.zeros((num_tests, num_minimizers))
+    for test_idx in range(0, num_tests):
+        for minimiz_idx in range(0, num_minimizers):
+            accuracy_tbl[test_idx, minimiz_idx] = results_per_test[test_idx][minimiz_idx].sum_err_sq
+            time_tbl[test_idx, minimiz_idx] = results_per_test[test_idx][minimiz_idx].runtime
+
+    return accuracy_tbl, time_tbl
+
+
+def calc_norm_summary_tables(accuracy_tbl, time_tbl):
+    """
+    Calculate normalized performance/ranking summary, as numpy
+    matrices as usual for convenience, and matrices of additional
+    statistics (min, max, percentiles, etc.)
+
+    Here normalized means relative to the best which gets a 1, all
+    others get the ratio resulting from dividing by the performance of
+    the best.
+    """
+    # Min across all minimizers, i.e. for each fit problem what is the lowest chi-squared and the lowest time
+    min_sum_err_sq = np.nanmin(accuracy_tbl, 1)
+    min_runtime = np.nanmin(time_tbl, 1)
+
+    # create normalised tables
+    norm_acc_rankings = accuracy_tbl / min_sum_err_sq[:, None]
+    norm_runtimes = time_tbl / min_runtime[:, None]
+
+    summary_cells_acc = np.array([np.nanmin(norm_acc_rankings, 0),
+                                  np.nanmax(norm_acc_rankings, 0),
+                                  stats.nanmean(norm_acc_rankings, 0),
+                                  stats.nanmedian(norm_acc_rankings, 0)
+                                  ])
+
+    summary_cells_runtime = np.array([np.nanmin(norm_runtimes, 0),
+                                      np.nanmax(norm_runtimes, 0),
+                                      stats.nanmean(norm_runtimes, 0),
+                                      stats.nanmedian(norm_runtimes, 0)
+                                      ])
+
+    return norm_acc_rankings, norm_runtimes, summary_cells_acc, summary_cells_runtime
diff --git a/scripts/CompareFitMinimizers/results_output.py b/scripts/CompareFitMinimizers/results_output.py
new file mode 100644
index 0000000000000000000000000000000000000000..57d28e5c23af2b95e2ca6723f5c3b07b132b5130
--- /dev/null
+++ b/scripts/CompareFitMinimizers/results_output.py
@@ -0,0 +1,474 @@
+"""
+Produce output tables from fitting benchmarking results, in different
+formats such as RST and plain text.
+"""
+# 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>
+
+from __future__ import (absolute_import, division, print_function)
+
+import numpy as np
+from scipy import stats  # older version of numpy does not support nanmean and nanmedian
+import post_processing as postproc
+
+# Some naming conventions for the output files
+BENCHMARK_VERSION_STR = 'v3.8'
+FILENAME_SUFFIX_ACCURACY = 'acc'
+FILENAME_SUFFIX_RUNTIME = 'runtime'
+
+
+def print_group_results_tables(minimizers, results_per_test, problems_obj, group_name, use_errors,
+                               simple_text=True, rst=False, save_to_file=False, color_scale=None):
+    """
+    Prints out results for a group of fit problems in accuracy and runtime tables, in a summary
+    format and both as simple text, rst format and/or to file depending on input arguments
+
+    @param minimizers :: list of minimizer names
+    @param results_per_test :: result objects
+    @param problems_obj :: definitions of the test problems
+    @param group_name :: name of this group of problems (example 'NIST "lower difficulty"', or
+                         'Neutron data')
+    @param use_errors :: whether to use observational errors
+    @param simple_text :: whether to print the tables in a simple text format
+    @param rst :: whether to print the tables in rst format. They are printed to the standard outputs
+                  and to files following specific naming conventions
+    @param save_to_file :: If rst=True, whether to save the tables to files following specific naming conventions
+    @param color_scale :: threshold-color pairs. This is used for RST tables. The number of levels
+                          must be consistent with the style sheet used in the documentation pages (5
+                          at the moment).
+    """
+    linked_problems = build_indiv_linked_problems(results_per_test, group_name)
+
+    # Calculate summary tables
+    accuracy_tbl, runtime_tbl = postproc.calc_accuracy_runtime_tbls(results_per_test, minimizers)
+    norm_acc_rankings, norm_runtimes, summary_cells_acc, summary_cells_runtime = \
+        postproc.calc_norm_summary_tables(accuracy_tbl, runtime_tbl)
+
+    if simple_text:
+        print_tables_simple_text(minimizers, results_per_test, accuracy_tbl, runtime_tbl, norm_acc_rankings)
+
+    if rst:
+        # print out accuracy table for this group of fit problems
+        tbl_acc_indiv = build_rst_table(minimizers, linked_problems, norm_acc_rankings,
+                                        comparison_type='accuracy', comparison_dim='',
+                                        using_errors=use_errors, color_scale=color_scale)
+        header = " ************* Comparison of sum of square errors (RST): *********\n"
+        header += " *****************************************************************\n"
+        header += "\n\n"
+        print(header)
+        print (tbl_acc_indiv)
+
+        # optionally save the above table to file
+        if save_to_file:
+            fname = ('comparison_{weighted}_{version}_{metric_type}_{group_name}.txt'.
+                     format(weighted=weighted_suffix_string(use_errors),
+                            version=BENCHMARK_VERSION_STR, metric_type=FILENAME_SUFFIX_ACCURACY, group_name=group_name))
+            with open(fname, 'w') as tbl_file:
+                print(tbl_acc_indiv, file=tbl_file)
+
+        # print out accuracy summary table for this group of fit problems
+        ext_summary_cols = minimizers
+        ext_summary_rows = ['Best ranking', 'Worst ranking', 'Average', 'Median']
+        tbl_acc_summary = build_rst_table(ext_summary_cols, ext_summary_rows, summary_cells_acc,
+                                          comparison_type='accuracy', comparison_dim='',
+                                          using_errors=use_errors, color_scale=color_scale)
+        header = '**************** Statistics/Summary (accuracy): ******** \n\n'
+        print(header)
+        print(tbl_acc_summary)
+
+        # print out runtime table for this group of fit problems
+        tbl_runtime_indiv = build_rst_table(minimizers, linked_problems, norm_runtimes,
+                                            comparison_type='runtime', comparison_dim='',
+                                            using_errors=use_errors, color_scale=color_scale)
+        header = " ************* Comparison of runtimes (RST): ****************\n"
+        header += " *****************************************************************\n"
+        header += "\n\n"
+        print(header)
+        print (tbl_runtime_indiv)
+
+        # optionally save the above table to file
+        if save_to_file:
+            fname = ('comparison_{weighted}_{version}_{metric_type}_{group_name}.txt'.
+                     format(weighted=weighted_suffix_string(use_errors),
+                            version=BENCHMARK_VERSION_STR, metric_type=FILENAME_SUFFIX_RUNTIME, group_name=group_name))
+            with open(fname, 'w') as tbl_file:
+                print(tbl_runtime_indiv, file=tbl_file)
+
+        # print out runtime summary table for this group of fit problems
+        tbl_runtime_summary = build_rst_table(ext_summary_cols, ext_summary_rows, summary_cells_runtime,
+                                              comparison_type='runtime', comparison_dim='',
+                                              using_errors=use_errors, color_scale=color_scale)
+        header = '**************** Statistics/Summary (runtime): ******** \n\n'
+        print(header)
+        print(tbl_runtime_summary)
+
+
+def build_indiv_linked_problems(results_per_test, group_name):
+    """
+    Makes a list of linked problem names which would be used for the
+    rows of the first column of the tables of individual results.
+
+    @param results_per_test :: results as produces by the fitting tests
+    @param group_name :: name of the group (NIST, Neutron data, etc.) this problem is part of
+
+    @returns :: list of problems with their description link tags
+    """
+    num_tests = len(results_per_test)
+    prev_name = ''
+    prob_count = 1
+    linked_problems = []
+    for test_idx in range(0, num_tests):
+        raw_name = results_per_test[test_idx][0].problem.name
+        name = raw_name.split('.')[0]
+        if name == prev_name:
+            prob_count += 1
+        else:
+            prob_count = 1
+
+        prev_name = name
+        name_index = name + ' ' + str(prob_count)
+
+        # TO-DO: move this to the nist loader, not here!
+        if 'nist_' in group_name:
+            linked_problems.append("`{0} <http://www.itl.nist.gov/div898/strd/nls/data/{1}.shtml>`__".
+                                   format(name_index, name.lower()))
+        else:
+            linked_problems.append(name)
+
+    return linked_problems
+
+
+def build_group_linked_names(group_names):
+    """
+    Add a link for RST tables if there is a website or similar describing the group.
+
+    @param group_names :: names as plain text
+
+    @returns :: names with RST links if available
+    """
+    linked_names = []
+    for name in group_names:
+        # This should be tidied up. We currently don't have links for groups other than NIST
+        if 'NIST' in name:
+            linked = "`{0} <http://www.itl.nist.gov/div898/strd/nls/nls_main.shtml>`__".format(name)
+        else:
+            linked = name
+
+        linked_names.append(linked)
+
+    return linked_names
+
+
+def print_overall_results_table(minimizers, group_results, problems, group_names, use_errors,
+                                simple_text=True, save_to_file=False):
+
+    groups_norm_acc, groups_norm_runtime = postproc.calc_summary_table(minimizers, group_results)
+
+    grp_linked_names = build_group_linked_names(group_names)
+
+    header = '**************** Accuracy ******** \n\n'
+    print(header)
+    tbl_all_summary_acc = build_rst_table(minimizers, grp_linked_names, groups_norm_acc,
+                                          comparison_type='summary', comparison_dim='accuracy',
+                                          using_errors=use_errors)
+    print(tbl_all_summary_acc)
+
+    if save_to_file:
+        fname = ('comparison_{weighted}_{version}_{metric_type}_{group_name}.txt'.
+                 format(weighted=weighted_suffix_string(use_errors),
+                        version=BENCHMARK_VERSION_STR, metric_type=FILENAME_SUFFIX_ACCURACY, group_name='summary'))
+        with open(fname, 'w') as tbl_file:
+            print(tbl_all_summary_acc, file=tbl_file)
+
+    header = '**************** Runtime ******** \n\n'
+    print(header)
+    tbl_all_summary_runtime = build_rst_table(minimizers, grp_linked_names, groups_norm_runtime,
+                                              comparison_type='summary', comparison_dim='runtime',
+                                              using_errors=use_errors)
+    print(tbl_all_summary_runtime)
+
+    if save_to_file:
+        fname = ('comparison_{weighted}_{version}_{metric_type}_{group_name}.txt'.
+                 format(weighted=weighted_suffix_string(use_errors),
+                        version=BENCHMARK_VERSION_STR, metric_type=FILENAME_SUFFIX_RUNTIME, group_name='summary'))
+        with open(fname, 'w') as tbl_file:
+            print(tbl_all_summary_runtime, file=tbl_file)
+
+
+def weighted_suffix_string(use_errors):
+    """
+    Produces a suffix weighted/unweighted. Used to generate names of
+    output files.
+    """
+    values = {True: 'weighted', False: 'unweighted'}
+    return values[use_errors]
+
+
+def display_name_for_minimizers(names):
+    """
+    Converts minimizer names into their "display names". For example
+    to rename DTRS to "Trust region" or similar
+
+    """
+    display_names = names
+    # Quick fix for DTRS name in version 3.8 - REMOVE
+    for idx, minimizer in enumerate(names):
+        if 'DTRS' == minimizer:
+            display_names[idx] = 'Trust Region'
+
+    return display_names
+
+
+def calc_cell_len_rst_table(columns_txt, items_link):
+    """
+    Calculate what width in ascii characters we need for an RST table.
+
+    @param columns_txt :: list of the contents of the column headers
+    """
+    # One length for all cells
+    cell_len = 50
+    cell_len = 0
+    for col in columns_txt:
+        new_len = len(col) + 2
+        if new_len > cell_len:
+            cell_len = new_len
+
+    # Beware of the long links
+    links_len = 0
+    if items_link and isinstance(items_link, list):
+        links_len = max([len(item) for item in items_link])
+    elif items_link:
+        links_len = len(items_link)
+
+    additional_len = 0
+    if items_link:
+        additional_len = links_len
+    cell_len += int(additional_len/1.2)
+
+    return cell_len
+
+
+def build_rst_table(columns_txt, rows_txt, cells, comparison_type, comparison_dim,
+                    using_errors, color_scale=None):
+    """"
+    Builds an RST table as a string, given the list of column and row headers,
+    and a 2D numpy array with values for the cells.
+    This can be tricky/counterintuitive, see:
+    http://docutils.sourceforge.net/docs/dev/rst/problems.html
+
+    @param columns_txt :: the text for the columns, one item per column
+    @param rows_txt :: the text for the rows (will go in the leftmost column)
+    @param cells :: a 2D numpy array with as many rows as items have been given
+    in rows_txt, and as many columns as items have been given in columns_txt
+
+    @param comparison_type :: whether this is a 'summary', or a full 'accuracy', or 'runtime'
+                              table.
+    @param comparison_dim :: dimension (accuracy / runtime)
+    @param using_errors :: whether this comparison uses errors in the cost function
+    (weighted or unweighted), required to link the table properly
+
+    @param color_scale :: list with pairs of threshold value - color, to produce color
+    tags for the cells
+    """
+    columns_txt = display_name_for_minimizers(columns_txt)
+
+    items_link = build_items_links(comparison_type, comparison_dim, using_errors)
+
+    cell_len = calc_cell_len_rst_table(columns_txt, items_link)
+
+    # The first column tends to be disproportionately long if it has a link
+    first_col_len = calc_first_col_len(cell_len, rows_txt)
+
+    tbl_header_top, tbl_header_text, tbl_header_bottom = build_rst_table_header_chunks(first_col_len, cell_len,
+                                                                                       columns_txt)
+
+    tbl_header = tbl_header_top + '\n' + tbl_header_text + '\n' + tbl_header_bottom + '\n'
+    # the footer is in general the delimiter between rows, including the last one
+    tbl_footer = tbl_header_top + '\n'
+
+    tbl_body = ''
+    for row in range(0, cells.shape[0]):
+        # Pick either individual or group link
+        if isinstance(items_link, list):
+            link = items_link[row]
+        else:
+            link = items_link
+
+        tbl_body += '|' + rows_txt[row].ljust(first_col_len, ' ') + '|'
+        for col in range(0, cells.shape[1]):
+            tbl_body += format_cell_value_rst(cells[row, col], cell_len, color_scale, link) + '|'
+
+        tbl_body += '\n'
+        tbl_body += tbl_footer
+
+    return tbl_header + tbl_body
+
+
+def build_rst_table_header_chunks(first_col_len, cell_len, columns_txt):
+    """
+    Prepare the horizontal and vertical lines in the RST headers.
+
+    @param first_col_len :: length (in characters) of the first column
+    @param cell_len :: length of all other cells
+    """
+    tbl_header_top = '+'
+    tbl_header_text = '|'
+    tbl_header_bottom = '+'
+
+    # First column in the header for the name of the test or statistics
+    tbl_header_top += '-'.ljust(first_col_len, '-') + '+'
+    tbl_header_text += ' '.ljust(first_col_len, ' ') + '|'
+    tbl_header_bottom += '='.ljust(first_col_len, '=') + '+'
+    for col_name in columns_txt:
+        tbl_header_top += '-'.ljust(cell_len, '-') + '+'
+        tbl_header_text += col_name.ljust(cell_len, ' ') + '|'
+        tbl_header_bottom += '='.ljust(cell_len, '=') + '+'
+
+    return tbl_header_top, tbl_header_text, tbl_header_bottom
+
+
+def calc_first_col_len(cell_len, rows_txt):
+    first_col_len = cell_len
+    for row_name in rows_txt:
+        name_len = len(row_name)
+        if name_len > first_col_len:
+            first_col_len = name_len
+
+    return first_col_len
+
+
+def build_items_links(comparison_type, comparison_dim, using_errors):
+    """
+    Figure out the links from rst table cells to other pages/sections of pages.
+
+    @param comparison_type :: whether this is a 'summary', or a full 'accuracy', or 'runtime' table.
+    @param comparison_dim :: dimension (accuracy / runtime)
+    @param using_errors :: whether using observational errors in cost functions
+
+    @returns :: link or links to use from table cells.
+    """
+    if 'summary' == comparison_type:
+        items_link = ['Minimizers_{0}_comparison_in_terms_of_{1}_nist_lower'.
+                      format(weighted_suffix_string(using_errors), comparison_dim),
+                      'Minimizers_{0}_comparison_in_terms_of_{1}_nist_average'.
+                      format(weighted_suffix_string(using_errors), comparison_dim),
+                      'Minimizers_{0}_comparison_in_terms_of_{1}_nist_higher'.
+                      format(weighted_suffix_string(using_errors), comparison_dim),
+                      'Minimizers_{0}_comparison_in_terms_of_{1}_cutest'.
+                      format(weighted_suffix_string(using_errors), comparison_dim),
+                      'Minimizers_{0}_comparison_in_terms_of_{1}_neutron_data'.
+                      format(weighted_suffix_string(using_errors), comparison_dim),
+                      ]
+    elif 'accuracy' == comparison_type or 'runtime' == comparison_type:
+        if using_errors:
+            items_link = 'FittingMinimizersComparisonDetailedWithWeights'
+        else:
+            items_link = 'FittingMinimizersComparisonDetailed'
+    else:
+        items_link = ''
+
+    return items_link
+
+
+def format_cell_value_rst(value, width, color_scale=None, items_link=None):
+    """
+    Build the content string for a table cell, adding style/color tags
+    if required.
+
+    """
+    if not color_scale:
+        if not items_link:
+            value_text = ' {0:.4g}'.format(value).ljust(width, ' ')
+        else:
+            value_text = ' :ref:`{0:.4g} <{1}>`'.format(value, items_link).ljust(width, ' ')
+    else:
+        color = ''
+        for color_descr in color_scale:
+            if value <= color_descr[0]:
+                color = color_descr[1]
+                break
+        if not color:
+            color = color_scale[-1][1]
+        value_text = " :{0}:`{1:.4g}`".format(color, value).ljust(width, ' ')
+
+    return value_text
+
+
+def print_tables_simple_text(minimizers, results_per_test, accuracy_tbl, time_tbl, norm_acc_rankings):
+    """
+    Produces tables in plain ascii, without any markup.  This is much
+    easier to read than RST and useful when developing or just
+    checking the output of the runs from the system test logs.
+
+    """
+
+    header = " ============= Comparison of sum of square errors: ===============\n"
+    header += " =================================================================\n"
+    header += "\n\n"
+
+    for minimiz in minimizers:
+        header += " {0} |".format(minimiz)
+    header += "\n"
+    print(header)
+
+    min_sum_err_sq = np.amin(accuracy_tbl, 1)
+    num_tests = len(results_per_test)
+    results_text = ''
+    for test_idx in range(0, num_tests):
+        results_text += "{0}\t".format(results_per_test[test_idx][0].problem.name)
+        for minimiz_idx, minimiz in enumerate(minimizers):
+            # 'e' format is easier to read in raw text output than 'g'
+            results_text += (" {0:.10g}".
+                             format(results_per_test[test_idx][minimiz_idx].sum_err_sq /
+                                    min_sum_err_sq[test_idx]))
+        results_text += "\n"
+
+    # If some of the fits fail badly, they'll produce 'nan' values =>
+    # 'nan' errors. Requires np.nanmedian() and the like nan-safe
+    # functions.
+
+    # summary lines
+    results_text += '---------------- Summary (accuracy): -------- \n'
+    results_text += 'Best ranking: {0}\n'.format(np.nanmin(norm_acc_rankings, 0))
+    results_text += 'Worst ranking: {0}\n'.format(np.nanmax(norm_acc_rankings, 0))
+    results_text += 'Mean: {0}\n'.format(stats.nanmean(norm_acc_rankings, 0))
+    results_text += 'Median: {0}\n'.format(stats.nanmedian(norm_acc_rankings, 0))
+    results_text += '\n'
+
+    print(results_text)
+
+    print(" ======== Time: =======")
+    time_text = ''
+    for test_idx in range(0, num_tests):
+        time_text += "{0}\t".format(results_per_test[test_idx][0].problem.name)
+        for minimiz_idx, minimiz in enumerate(minimizers):
+            time_text += " {0}".format(results_per_test[test_idx][minimiz_idx].runtime)
+        time_text += "\n"
+
+    min_runtime = np.amin(time_tbl, 1)
+    norm_runtimes = time_tbl / min_runtime[:, None]
+    time_text += '---------------- Summary (run time): -------- \n'
+    time_text += 'Best ranking: {0}\n'.format(np.nanmin(norm_runtimes, 0))
+    time_text += 'Worst ranking: {0}\n'.format(np.nanmax(norm_runtimes, 0))
+    time_text += 'Mean: {0}\n'.format(stats.nanmean(norm_runtimes, 0))
+    time_text += 'Median: {0}\n'.format(stats.nanmedian(norm_runtimes, 0))
+    time_text += '\n'
+
+    print(time_text)
diff --git a/scripts/CompareFitMinimizers/test_problem.py b/scripts/CompareFitMinimizers/test_problem.py
new file mode 100644
index 0000000000000000000000000000000000000000..5f8f80854b625bf736b42f837aae07e557804640
--- /dev/null
+++ b/scripts/CompareFitMinimizers/test_problem.py
@@ -0,0 +1,43 @@
+# 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 FittingTestProblem(object):
+    """
+    Definition of a fitting test problem, normally loaded from a problem definition file.
+    """
+    def __init__(self):
+        self.name = None
+        # If there is an online/documentation link describing this problem
+        self.linked_name = None
+        self.equation = None
+        self.start_x = None
+        self.end_x = None
+        # can be for example the list of starting values from NIST test problems
+        self.starting_values = None
+        # The Mantid X
+        self.data_pattern_in = None
+        # The Mantid Y
+        self.data_pattern_out = None
+        # The Mantid E
+        self.data_pattern_obs_errors = None
+        # The 'certified' or reference sum of squares, if provided (for example
+        # in NIST tests).
+        self.ref_residual_sum_sq = None
diff --git a/scripts/CompareFitMinimizers/test_result.py b/scripts/CompareFitMinimizers/test_result.py
new file mode 100644
index 0000000000000000000000000000000000000000..ed4d663e957c5d031a01edee5738187ea4f25f36
--- /dev/null
+++ b/scripts/CompareFitMinimizers/test_result.py
@@ -0,0 +1,37 @@
+# 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 FittingTestResult(object):
+    """
+    Minimal definition of a class to hold results from a fitting problem test.
+    """
+
+    def __init__(self):
+        self.problem = None
+        self.fit_status = None
+        self.fit_chi2 = None
+        # Workspace with data to fit
+        self.fit_wks = None
+        self.params = None
+        self.errors = None
+        self.sum_err_sq = None
+        # Time it took to run the Fit algorithm
+        self.runtime = None
diff --git a/scripts/DiamondAttenuationCorrection/FitTrans.py b/scripts/DiamondAttenuationCorrection/FitTrans.py
new file mode 100644
index 0000000000000000000000000000000000000000..e18aeebdae721a3b435c6f046bc4b3b1968f57f2
--- /dev/null
+++ b/scripts/DiamondAttenuationCorrection/FitTrans.py
@@ -0,0 +1,1304 @@
+'''
+1. all the functions are defined and built consistently.
+
+
+
+
+Data types:
+- Use only numpy arrays to ensure consistency across formatting and type
+*** x, x0 = parameters vector - 1D numpy array
+*** setang1, setang2 = angles for refinement - 1D numpy arrays, 3 elements
+*** hkl1, hkl2 = numpy arrays (3 columns) having all the hkl indices from the 2 diamonds
+*** UB1, UB2 = numpy arrays (3x3) holds UB matrices from input files
+***
+'''
+# Import all needed libraries
+from matplotlib import pyplot as plt
+import numpy as np
+import itertools as itt
+import UBMatrixGenerator as UBMG
+import scipy.optimize as sp
+
+__author__ = 'cip'
+
+# Define global variables
+global hkl1, hkl2
+global UB1, pkcalcint1
+global UB2, pkcalcint2
+global pktype
+global lam, y, e, TOF
+global L1
+global ttot
+global fxsamediam
+global neqv1, eqvlab1, neqv2, eqvlab2
+global difa, function_verbose
+global figure_name_attenuation, run_number
+
+
+def dlmread(filename):
+    '''
+    Function to read parameters from file after previous fit
+    '''
+    content = []
+    with open(filename, "r") as f:
+        for line in f.readlines():
+            content.append(float(line))
+    return np.array(content)
+
+
+def calcDspacing(a, b, c, alp, bet, gam, h, k, l):
+    '''
+    %CALCDSPACING for general unit cell: a,b,c,alp,bet,gam returns d-spacing for
+    %reflection h,k,l
+    %
+    '''
+    ca = np.cos(np.radians(alp))
+    cb = np.cos(np.radians(bet))
+    cg = np.cos(np.radians(gam))
+    sa = np.sin(np.radians(alp))
+    sb = np.sin(np.radians(bet))
+    sg = np.sin(np.radians(gam))
+
+    oneoverdsq = (1.0 - ca**2 - cb**2 - cg**2 + 2 * ca * cb * cg)**(-1) * \
+                 ((h * sa / a)**2 + (k * sb / b)**2 + (l * sg / c)**2
+                  + (2 * k * l / (b * c)) * (cb * cg - ca) + (2 * l * h / (c * a)) * (cg * ca - cb)
+                  + (2 * h * k / (a * b)) * (ca * cb - cg))
+
+    d = np.sqrt(1.0 / oneoverdsq)
+    return d
+
+
+def genhkl(hmin, hmax, kmin, kmax, lmin, lmax):
+    '''
+    genhkl generates array of hkl values
+    total number of points will be (hmax-hmin)
+    '''
+    hvals = np.arange(hmin, hmax + 1, 1)
+    kvals = np.arange(kmin, kmax + 1, 1)
+    lvals = np.arange(lmin, lmax + 1, 1)
+
+    nh = len(hvals)
+    nk = len(kvals)
+    nl = len(lvals)
+
+    l = 0
+    hkl = np.zeros(shape=(nh * nl * nk, 3))
+    for i in range(nh):
+        for j in range(nk):
+            for k in range(nl):
+                hkl[l][0] = hvals[i]
+                hkl[l][1] = kvals[j]
+                hkl[l][2] = lvals[k]
+                l += 1
+    return hkl
+
+
+def mod(a, b):
+    return a % b
+
+
+def forbidden(h, k, l):
+    '''
+    %returns logical positive if this hkl is fobidden according to
+    %   diamond reflections conditions....
+    '''
+    ah = abs(h)
+    ak = abs(k)
+    al = abs(l)
+
+    if ((h == 0) and (k == 0) and (l == 0)):
+        result = 1
+        boolresult = bool(result)
+        return boolresult
+    else:
+        result = 0
+
+    if ((ah == 2) and (ak == 2) and (al == 2)):  # allowed, but vanishingly weak
+        result = 1
+        boolresult = bool(result)
+        return boolresult
+    else:
+        result = 0
+
+    # condition 1
+    if ((h != 0)and (k != 0) and (l != 0)):  # general hkl
+        term1 = h + k
+        term2 = h + l  # all have to be even
+        term3 = k + l
+        if not((term1 % 2) == 0 and (term2 % 2) == 0 and (term3 % 2) == 0):
+            result = 1
+            boolresult = bool(result)
+            return boolresult
+        else:
+            result = 0
+
+    #% condition 2
+    if ((h == 0) and (k != 0) and (l != 0)):  # 0kl reflections
+        term1 = k + l
+        mod4 = mod(term1, 4)
+        if not(mod4 == 0 and mod(k, 2) == 0 and mod(l, 2) == 0):
+            result = 1
+            boolresult = bool(result)
+            return boolresult
+        else:
+            result = 0
+
+    # condition 3
+    if (h == k):  # hhl reflections
+        if not(mod(h + l, 2) == 0):
+            result = 1
+            boolresult = bool(result)
+            return boolresult
+        else:
+            result = 0
+
+    # condition 4
+    if ((h == 0) and (k == 0) and (l != 0)):   # 00l reflections not including 000
+        mod4 = mod(l, 4)
+        if not(mod4 == 0):
+            result = 1
+            boolresult = bool(result)
+            return boolresult
+        else:
+            result = 0
+
+    boolresult = bool(result)
+    return boolresult
+
+
+def allowedDiamRefs(hmin, hmax, kmin, kmax, lmin, lmax):
+    '''
+    %UNTITLED6 generates a list of allowed reflections for diamond between
+    %   limits provided sorted descending according to d-spacing
+    '''
+    # obtain all hkl within limits...
+    allhkl = genhkl(hmin, hmax, kmin, kmax, lmin, lmax)
+    # now purge those violating extinction conditions...
+
+    n = len(allhkl)
+
+    # set all forbidden hkl's to zero
+    # hkl or lhk or klh
+    for i in range(n):
+        h = allhkl[i][0]
+        k = allhkl[i][1]
+        l = allhkl[i][2]
+        if forbidden(h, k, l) or forbidden(l, h, k) or forbidden(k, l, h):
+            allhkl[i] = 0  # set equal to zero
+
+    k = 0
+    d = []  # np.zeros(0)
+    # create new array with all h!=0 k!=0 l!=0
+    hkl = np.zeros(shape=(0, 3))
+    for i in range(n):
+        if not(allhkl[i][0] == 0 and allhkl[i][1] == 0 and allhkl[i][2] == 0):
+            hkl = np.vstack((hkl, [allhkl[i][0], allhkl[i][1], allhkl[i][2]]))
+            d.append(calcDspacing(3.56683, 3.56683, 3.56683, 90,
+                                  90, 90, hkl[k][0], hkl[k][1], hkl[k][2]))
+            k += 1
+    d = np.array(d)
+
+    # ORDER hkl according to d-spacing
+    B = sorted(d)[::-1]  # returns d sorted in descending order
+    IX = np.argsort(d)[::-1]  # and corresponding elements
+
+    sorthkl = np.zeros(shape=(k, 3))
+    for i in range(k):
+        sorthkl[i] = hkl[IX[i]]
+        d[i] = B[i]
+        # print('hkl: {0:0.3f} {1:0.3f} {2:0.3f} d-spacing: {3:0.3f} A'.format(sorthkl[i][0], sorthkl[i][1],
+        #    sorthkl[i][2], d[i]))
+
+    return sorthkl
+
+
+def getISAWub(fullfilename):
+    '''
+    %getISAWub reads UB determined by ISAW and stored in file "fname"
+    %   Detailed explanation goes here
+
+
+    % [filename pathname ~] = ...
+    %     uigetfile('*.dat','Choose UB file (generated by ISAW)');
+    % fullfilename = [pathname filename];
+    '''
+    fileID = fullfilename
+    if fileID == 1:
+        print('Error opening file: ' + fullfilename)
+    f = open(fileID, "r")
+    lines = f.readlines()
+    f.close()
+
+    # Build UB matrix and lattice
+    UB = np.zeros(shape=(3, 3))
+    lattice = np.zeros(shape=(2, 6))
+    for i in range(3):
+        UB[i][0], UB[i][1], UB[i][2] = lines[i].split()
+    UB = UB.transpose()
+    for i in range(3, 5):
+        lattice[i - 3][0], lattice[i - 3][1], lattice[i - 3][2], lattice[i - 3][3], lattice[i - 3][4], lattice[i - 3][5], \
+            non = lines[i].split()
+
+    print('Successfully got UB and lattice')
+
+    return UB, lattice
+
+
+def pkintread(hkl, loc):
+    '''
+    %reads calculated Fcalc and converts to
+    %Fobs using Buras-Gerard Eqn.
+    %inputs are hkl(nref,3) and
+    % loc(nref,3), which contains, lambda, d-spacing and ttheta for
+    % each of the nref reflections.
+
+    % get Fcalcs for diamond, generated by GSAS (using lattice parameter 3.5668
+    % and Uiso(C) = 0.0038
+
+    % disp('in pkintread');
+
+
+    returns pkint = np. array - 1D vector
+    '''
+    #A = np.genfromtxt('diamond_reflist.csv', delimiter=',', skip_header=True)
+    # print A
+    A = np.array([[1.00000000e+00,   1.00000000e+00,   1.00000000e+00,   8.00000000e+00,
+                   2.06110000e+00,   5.54000000e+04],
+                  [2.00000000e+00,   2.00000000e+00,   0.00000000e+00,   1.20000000e+01,
+                   1.26220000e+00,   7.52000000e+04],
+                  [3.00000000e+00,   1.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   1.07640000e+00,   2.98000000e+04],
+                  [2.00000000e+00,   2.00000000e+00,   2.00000000e+00,   8.00000000e+00,
+                   1.03060000e+00,   2.50000000e-25],
+                  [4.00000000e+00,   0.00000000e+00,   0.00000000e+00,   6.00000000e+00,
+                   8.92500000e-01,   4.05000000e+04],
+                  [3.00000000e+00,   3.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   8.19000000e-01,  1.61000000e+04],
+                  [4.00000000e+00,   2.00000000e+00,   2.00000000e+00,   2.40000000e+01,
+                   7.28700000e-01,   2.18000000e+04],
+                  [5.00000000e+00,   1.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   6.87000000e-01,   8.64000000e+03],
+                  [3.00000000e+00,   3.00000000e+00,   3.00000000e+00,   8.00000000e+00,
+                   6.87000000e-01,   8.64000000e+03],
+                  [4.00000000e+00,   4.00000000e+00,   0.00000000e+00,  1.20000000e+01,
+                   6.31100000e-01,   1.17000000e+04],
+                  [5.00000000e+00,   3.00000000e+00,   1.00000000e+00,   4.80000000e+01,
+                   6.03400000e-01,   4.65000000e+03],
+                  [4.00000000e+00,   4.00000000e+00,   2.00000000e+00,   2.40000000e+01,
+                   5.95000000e-01,   1.83000000e-12],
+                  [6.00000000e+00,   2.00000000e+00,   0.00000000e+00,   2.40000000e+01,
+                   5.64500000e-01,   6.31000000e+03],
+                  [5.00000000e+00,   3.00000000e+00,   3.00000000e+00,   2.40000000e+01,
+                   5.44400000e-01,   2.50000000e+03],
+                  [6.00000000e+00,   2.00000000e+00,   2.00000000e+00,   2.40000000e+01,
+                   5.38200000e-01,   8.80000000e-26],
+                  [4.00000000e+00,   4.00000000e+00,   4.00000000e+00,   8.00000000e+00,
+                   5.15300000e-01,   3.40000000e+03],
+                  [5.00000000e+00,   5.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   4.99900000e-01,   1.35000000e+03],
+                  [7.00000000e+00,   1.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   4.99900000e-01,   1.35000000e+03],
+                  [6.00000000e+00,   4.00000000e+00,   2.00000000e+00,   4.80000000e+01,
+                   4.77100000e-01,   1.83000000e+03],
+                  [7.00000000e+00,   3.00000000e+00,   1.00000000e+00,   4.80000000e+01,
+                   4.64800000e-01,   7.25000000e+02],
+                  [5.00000000e+00,   5.00000000e+00,   3.00000000e+00,   2.40000000e+01,
+                   4.64800000e-01,   7.25000000e+02],
+                  [8.00000000e+00,   0.00000000e+00,   0.00000000e+00,   6.00000000e+00,
+                   4.46200000e-01,   9.84000000e+02],
+                  [7.00000000e+00,   3.00000000e+00,   3.00000000e+00,   2.40000000e+01,
+                   4.36100000e-01,   3.90000000e+02],
+                  [6.00000000e+00,   4.00000000e+00,   4.00000000e+00,   2.40000000e+01,
+                   4.32900000e-01,   1.53000000e-13],
+                  [6.00000000e+00,   6.00000000e+00,   0.00000000e+00,   1.20000000e+01,
+                   4.20700000e-01,   5.30000000e+02],
+                  [8.00000000e+00,   2.00000000e+00,   2.00000000e+00,   2.40000000e+01,
+                   4.20700000e-01,   5.30000000e+02],
+                  [5.00000000e+00,   5.00000000e+00,   5.00000000e+00,   8.00000000e+00,
+                   4.12200000e-01,   2.10000000e+02],
+                  [7.00000000e+00,   5.00000000e+00,   1.00000000e+00,   4.80000000e+01,
+                   4.12200000e-01,   2.10000000e+02],
+                  [6.00000000e+00,   6.00000000e+00,   2.00000000e+00,   2.40000000e+01,
+                   4.09500000e-01,   1.98000000e-26],
+                  [8.00000000e+00,   4.00000000e+00,   0.00000000e+00,   2.40000000e+01,
+                   3.99100000e-01,   2.85000000e+02],
+                  [7.00000000e+00,   5.00000000e+00,   3.00000000e+00,   4.80000000e+01,
+                   3.91900000e-01,   1.13000000e+02],
+                  [9.00000000e+00,   1.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   3.91900000e-01,   1.13000000e+02],
+                  [8.00000000e+00,   4.00000000e+00,   2.00000000e+00,   4.80000000e+01,
+                   3.89500000e-01,   4.44000000e-14],
+                  [6.00000000e+00,   6.00000000e+00,   4.00000000e+00,   2.40000000e+01,
+                   3.80600000e-01,   1.53000000e+02],
+                  [9.00000000e+00,   3.00000000e+00,   1.00000000e+00,   4.80000000e+01,
+                   3.74200000e-01,   6.08000000e+01],
+                  [8.00000000e+00,   4.00000000e+00,   4.00000000e+00,   2.40000000e+01,
+                   3.64400000e-01,   8.26000000e+01],
+                  [9.00000000e+00,   3.00000000e+00,   3.00000000e+00,   2.40000000e+01,
+                   3.58800000e-01,   3.27000000e+01],
+                  [7.00000000e+00,   5.00000000e+00,   5.00000000e+00,   2.40000000e+01,
+                   3.58800000e-01,   3.27000000e+01],
+                  [7.00000000e+00,   7.00000000e+00,   1.00000000e+00,   2.40000000e+01,
+                   3.58800000e-01,   3.27000000e+01]])
+
+    diamd = A[:, 4]
+    #diamMult = A[:, 3] # unused variable
+    diamFCalcSq = A[:, 5]
+    nref = hkl.shape[0]
+    #% disp(['there are: ' num2str(nref) ' reflections']);
+    #% whos loc
+
+    '''
+    % [i,j] = size(x);
+    % dipspec = zeros(i,j); %array containing dip spectrum
+    % difspec = zeros(i,j); %array containing diffraction spectrum
+    % d = x/sqrt(2);    %dspacings for this lamda range at 90 degrees
+
+    % In order to calculate the scattered intensity I from the Fcalc^2, need to
+    % apply the Buras-Gerward formula:
+    %
+    % Fcalc^2 = I*2*sin(theta)^2/(lamda^2*A*E*incFlux*detEffic)
+    '''
+    pkint = np.zeros(nref)
+
+    for i in range(nref):
+        if loc[i][0] > 0:
+            #% satisfies Bragg condition (otherwise ignore)
+            Fsq = Fsqcalc(loc[i][1], diamd, diamFCalcSq)
+            #% Fsq = 1;
+            L = (np.sin(np.radians(loc[i][2] / 2.0)))**2  # Lorentz correction
+            R = 1.0  # %dipLam(i)^4; %reflectivity correction
+            A = 1.0  # %Absorption correction
+            Ecor = 1
+            pkint[i] = Fsq * R * A / (L * Ecor)  # %scattered intensity
+
+    '''
+    % whos difspec
+    % whos van
+    % whos dipspec
+
+    % difspec = difspec.*van;
+    % dipspec = dipspec.*van;
+
+    % figure(1)
+    % plot(d,difspec)
+    '''
+    return pkint
+
+
+def Fsqcalc(d, diamd, diamFCalcSq):
+    '''
+    % diamond reflections are identified according to their d-spacing
+    % and corresponding calculated Fsq are returned
+
+    % global sf111 sf220 sf311 sf400 sf331
+    '''
+    #n = len(diamd) # unused variable
+    ref = d
+    dif = abs(diamd - ref)
+    i = dif.argmin(0)  # i is index of diamd closest to d
+    Fsq = diamFCalcSq[i]
+    return Fsq
+
+
+def pkposcalc(hkl, UB, setang):
+    '''
+    % calculates some useful numbers from (ISAW calculated) UB
+    % hkl is a 2D array containing all hkl's
+    %
+    '''
+
+    ome = setang[0]
+    phi = setang[1]
+    chi = setang[2]
+    thkl = hkl.transpose()
+
+    Q = UB.dot(thkl)
+
+    Rx = np.array([[1, 0, 0], [0, np.cos(np.radians(ome)), -np.sin(np.radians(ome))],
+                   [0, np.sin(np.radians(ome)), np.cos(np.radians(ome))]])
+    Ry = np.array([[np.cos(np.radians(phi)), 0, np.sin(np.radians(phi))], [0, 1, 0],
+                   [-np.sin(np.radians(phi)), 0, np.cos(np.radians(phi))]])
+    Rz = np.array([[np.cos(np.radians(chi)), -np.sin(np.radians(chi)), 0],
+                   [np.sin(np.radians(chi)), np.cos(np.radians(chi)), 0], [0, 0, 1]])
+    Rall = Rz.dot(Ry).dot(Rx)  # all three rotations
+    # str = sprintf('initial: %6.4f %6.4f %6.4f',Q);
+    # disp(str)
+    Q = Rall.dot(Q)
+    magQ = np.sqrt((Q * Q).sum(axis=0))
+    '''
+    # str = sprintf('Scattering vector: %6.4f %6.4f %6.4f',Q);
+    # if show==1
+    #    disp(str)
+    # end
+    % %calculate angle with incident beam i.e. (-1 0 0)
+    % beam = [1 0 0];
+    % alpha = acosd(dot(Q,beam)/norm(Q));
+    % str = sprintf('Angle scat. vect. to beam: %6.4f',alpha);
+    % if show==1
+    %     disp(str)
+    % end
+    % beam = [0 1 0];
+    % alpha = acosd(dot(Q,beam)/norm(Q));
+    % str = sprintf('Angle scat. vect. to y: %6.4f',alpha);
+    % if show==1
+    %     disp(str)
+    % end
+    % beam = [0 0 1];
+    % alpha = acosd(dot(Q,beam)/norm(Q));
+    % str = sprintf('Angle scat. vect. to z: %6.4f',alpha);
+    % if show==1
+    %     disp(str)
+    % end
+    % Q is a vector pointing to the reciprocal lattice point corresponding to
+    % vector hkl. The coordinate system is in frame I that is right handed with x pointing along
+    % the beam direction and z vertical.
+    '''
+    d = (1.0 / magQ)  # by definition (note ISAW doesn't use 2pi factor)
+    d = d.transpose()
+    '''
+    % In frame I the incident beam vector will be of the form [k 0 0]
+    % where k = 1/lambda
+    % by considering the scattering relation that Q=k_f-k_i, can show that the dot product of
+    % -k_i.Q gives the scattering angle 2theta, thus:
+    '''
+    ttheta = 180 - 2 * np.degrees(np.arccos(-Q[0, :] / magQ))
+    ttheta = ttheta.transpose()
+    # and Bragg's law gives:
+    lambda_1 = 2 * d * np.sin(np.radians(ttheta / 2))
+    lambda_1 = lambda_1.transpose()
+    '''
+    %
+    %   str = sprintf('for hkl: %3i%3i%3i',hkl(1),hkl(2),hkl(3));
+    % disp(str)
+    % str = sprintf('d-spacing is: %6.4f',d);
+    % disp(str)
+    % str = sprintf('ttheta is: %6.4f',ttheta);
+    % disp(str)
+    % str = sprintf('lambda is: %6.4f',lambda);
+    % disp(str)
+    '''
+
+    return lambda_1, d, ttheta
+
+
+def getMANTIDdat_keepbinning(csvfile):
+    '''
+    getMANTIDdat reads data from mantid "SaveAscii" output
+    %   input file name should be 'csvfilename'.csv
+    %   data are returned with binning (xmin:xbin:xmax)
+
+    returns TOF, y , e
+    '''
+    fid = open(csvfile, "r")
+    lines = fid.readlines()
+    x = []
+    y = []
+    e = []
+    if fid < 0:
+        print('Error opening file: ' + csvfile)
+    for i in range(1, len(lines)):
+        a, b, c = lines[i].split(",")
+        x.append(float(a))
+        y.append(float(b))
+        e.append(float(c))
+    fid.close()
+    x = np.array(x)
+    y = np.array(y)
+    e = np.array(e)
+
+    return x, y, e
+
+
+def findeqvs(hkl):
+    '''
+    FINDEQVS runs through array of hkls and labels those that are equivalent
+    %in the m-3m point group.
+    %
+    % there are n reflections.
+    % hkl has dimensions nx3
+    % eqvlab has dimensions nx1
+    '''
+    n, m = hkl.shape
+    eqvlab = np.zeros(n)
+    lab = 1
+    for i in range(n):
+        if eqvlab[i] == 0:  # then it's not been checked yet, so check it
+            eqvlab[i] = lab
+            refhkl = np.array([abs(hkl[i][0]), abs(hkl[i][1]), abs(hkl[i][2])])
+            for j in range(i + 1, n):  # check remaining indices
+                comphkl = np.array(
+                    [abs(hkl[j][0]), abs(hkl[j][1]), abs(hkl[j][2])])
+                # all possible permutations
+                permcomphkl = list(itt.permutations(comphkl))
+                nperm = len(permcomphkl)
+                for k in range(nperm):
+                    if refhkl[0] == permcomphkl[k][0] and refhkl[1] == permcomphkl[k][1] and \
+                            refhkl[2] == permcomphkl[k][2]:
+                        eqvlab[j] = lab
+        lab += 1
+
+    return eqvlab, lab
+
+
+def showx3(x):
+    '''
+    %showx displays all parameters for refinement in reasonably intelligible
+    %form
+    Input : parameter vector and the sets of hkl indices for the diamons
+    '''
+    global hkl1, hkl2
+    global UB1, pkcalcint1
+    global UB2, pkcalcint2
+    global pktype
+    global lam, y, e, TOF
+    global L1
+    global ttot
+    global fxsamediam
+    global neqv1, eqvlab1, neqv2, eqvlab2
+    global difa, function_verbose
+
+    #nref1 = hkl1.shape[0]  # % number of reflections to integrate over # unused variable
+    #nref2 = hkl2.shape[0]  # % number of reflections to integrate over # unused variable
+    # % returns array with same dim as input labelling equivs
+    eqvlab1, neqv1 = findeqvs(hkl1)
+    eqvlab2, neqv2 = findeqvs(hkl2)
+    setang1 = x[0:3]
+    pkmult1 = x[3:4 + neqv1 - 1]
+    setang2 = x[4 + neqv1 - 1:6 + neqv1]
+    pkmult2 = x[6 + neqv1:7 + neqv1 + neqv2 - 1]
+    sf = x[neqv1 + neqv2 + 7 - 1]
+    pkwid1 = x[neqv1 + neqv2 + 8 - 1]
+    #bgd = x[neqv1 + neqv2 + 8 - 1:neqv1 + neqv2 + 9 + 2 - 1] # unused variable
+    pkwid2 = x[neqv1 + neqv2 + 10]
+    # % if diamond intensities the same, allow single scale f
+    relsf = x[neqv1 + neqv2 + 11]
+    delam = x[neqv1 + neqv2 + 12]
+    L2 = x[neqv1 + neqv2 + 13]
+
+    print('_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/\n')
+    print('Setting angles diam {0} : \nalp {1} bet {2} gam {3} \n'.format(
+        1, setang1[0], setang1[1], setang1[2]))
+    print('pkmult1: {0}\n'.format(pkmult1))
+    print('Setting angles diam {0} : \nalp {1} bet {2} gam {3} \n'.format(
+        2, setang2[0], setang2[1], setang2[2]))
+    print('pkmult2: {0}\n'.format(pkmult2))
+    print('Scale factor: {0}\n'.format(sf))
+    print('pkwid1: {0}\n'.format(pkwid1))
+    print('pkwid2: {0}\n'.format(pkwid2))
+    print('Rel. scale factor : {0}\n'.format(relsf))
+    print('Lambda multiplier: {0}\n'.format(delam))
+    print('L2 sample to detector: {0} m\n'.format(L2))
+    print('_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/\n')
+
+
+def SimTransOutput3(name, x):
+    '''
+    %SimTrans calculates transmission spectrum from two crystals
+    %   lam - array containing wavelengths to calc over
+    %   hkl - contains all Nref hkl's that calculation is performed for
+    %   bgd - array containing coefficients of polynomial for background
+    %   sf - overall scale factor
+    %   pktype - 1 = gauss; 2 = lorentz; ...
+    %   UB1 - UB matrix for first crystal
+    %   setang1 - setting angles for first crystal (deviations from ideal UB
+    %               location).
+    %   pkpars1 - position(lambda), position(d-spacing), position(ttheta), width, intensity for each Nref reflections
+    %   UB2,setang2,pkpars2 - as above, for second crystal
+    %
+    % M. Guthrie 21st Jan 2014
+    %
+    % calculate background profile
+    % determine number of coeffs bgd
+    '''
+    global hkl1, hkl2
+    global UB1, pkcalcint1
+    global UB2, pkcalcint2
+    global pktype
+    global lam, y, e, TOF
+    global L1
+    global ttot
+    global fxsamediam
+    global neqv1, eqvlab1, neqv2, eqvlab2
+    global difa, function_verbose
+    global figure_name_attenuation, run_number
+
+    nref1 = hkl1.shape[0]  # % number of reflections to integrate over
+    nref2 = hkl2.shape[0]  # % number of reflections to integrate over
+    # % returns array with same dim as input labelling equivs
+    eqvlab1, neqv1 = findeqvs(hkl1)
+    eqvlab2, neqv2 = findeqvs(hkl2)
+
+    setang1 = x[0:3]
+    pkmult1 = x[3:4 + neqv1 - 1]
+    setang2 = x[4 + neqv1 - 1:6 + neqv1]
+    sf = x[neqv1 + neqv2 + 7 - 1]
+    pkwid1 = x[neqv1 + neqv2 + 7]
+    bgd = x[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1]
+    pkwid2 = x[neqv1 + neqv2 + 10]
+    # % if diamond intensities the same, allow single scale f
+    relsf = x[neqv1 + neqv2 + 11]
+    if fxsamediam == 1:
+        x[6 + neqv1:7 + neqv1 + neqv2 - 1] = x[3:4 + neqv2 - 1] * relsf
+        pkmult2 = x[6 + neqv1:7 + neqv1 + neqv2 - 1]
+    else:
+        pkmult2 = x[6 + neqv1:7 + neqv1 + neqv2 - 1]
+    delam = x[neqv1 + neqv2 + 12]
+    L2 = x[neqv1 + neqv2 + 13]
+
+    shftlam = 0.0039558 * TOF / (L1 + L2) + difa * (TOF**2)
+    # number of lambda points to calculate over
+    npt = shftlam.shape[0]
+    # calculate information for peaks for crystal 1 using hkl,UB1, setang,
+    # pkpos
+    a, b, c = pkposcalc(hkl1, UB1, setang1)
+    pkpars1 = np.column_stack((a, b, c))
+    # calculate information for peaks for crystal 2 using hkl,UB1, setang,
+    # pkpos
+    a, b, c = pkposcalc(hkl2, UB2, setang2)
+    pkpars2 = np.column_stack((a, b, c))
+
+    # generate nptx,nco array containing, x^0,x^1,x^2,...x^nco for
+    # all nonzero background coefficients
+    bgdco = np.where(bgd != 0)[0]
+    nco = bgdco.shape[0]
+    nonzerobgd = np.zeros(nco)
+
+    X = np.ones(shape=(nco, npt))
+    for i in range(nco):
+        X[i, :] = shftlam ** (bgd[bgdco[i]] - 1)
+        nonzerobgd[i] = bgd[bgdco[i]]
+
+    # calculate background profile by multiplying this with coefficients
+    # themselves
+    bgdprof = nonzerobgd.dot(X)
+    #bgdprof = np.outer(nonzerobgd, X)
+    # print bgdprof
+    #bgdprof = bgdprof[0, :]
+    # calculate peaks for crystal 1
+
+    t1 = np.zeros(npt)  # initialise array containing profile
+    for i in range(nref1):
+        if pktype == 1:
+            pkpars1[i][0] = pkpars1[i][0] * delam  # linear lambda shift
+            sig = pkwid1 * pkpars1[i][0] + pkwid2 * \
+                (pkpars1[i][0]**2.)  # const del(lambda)/lambda
+            extScl = pkpars1[i][0]**0  # lambda dependent extinction effect
+            t1 = t1 - extScl * pkmult1[int(eqvlab1[i])] * pkcalcint1[i] * (
+                np.exp(-((shftlam - pkpars1[i][0])**2.) / (2 * (sig**2))))
+
+    # calculate peaks for crystal 2
+    t2 = np.zeros(npt)  # initialise array containing profile
+    for i in range(nref2):
+        if pktype == 1:
+            pkpars2[i][0] = pkpars2[i][0] * delam  # linear lambda shift
+            sig = pkwid1 * pkpars2[i][0] + pkwid2 * \
+                (pkpars2[i][0]**2.)  # const del(lambda)/lambda
+            extScl = pkpars2[i][0]**0  # lambda dependent extinction effect
+            t2 = t2 - extScl * pkmult2[int(eqvlab2[i])] * pkcalcint2[i] * (
+                np.exp(-(shftlam - pkpars2[i][0])**2. / (2 * (sig**2))))
+
+    # calculate final profile
+    ttot = (bgdprof + sf * t1) * (bgdprof + sf * t2)
+    #t1 = 1.0;
+    # t2 = 1.0;
+    # introduce weighting function and calc chi2...
+    w = np.ones(len(shftlam))  # equal weighting everywhere
+    #i1 = np.where(shftlam > 2.15)[0][0]
+    #j1 = np.where(shftlam > 2.65)[0][0]
+    # w[i1:j1] = 5 #extra weighting in region of first peaks
+    # i1 = find(lam>1.68,1,'first');
+    # j1 = find(lam>2.05,1,'first');
+    # w(i1:j1)=5; %extra weighting but not too much
+
+    resid = (y - ttot) * w
+    chi2 = np.sum(resid**2. / (2 * e**2)) / npt
+
+    output = 1
+    if output == 1:
+        diam1trans = sf * t1 + bgdprof
+        diam2trans = sf * t2 + bgdprof
+        out = np.column_stack((shftlam, diam1trans, diam2trans, ttot, y))
+        np.savetxt(name, out, delimiter=',')
+
+    figure_name_attenuation = 'Attenuation ' + run_number
+
+    plt.figure(figure_name_attenuation)
+    plt.plot(shftlam, ttot, 'r', label='Total att.')
+    plt.plot(shftlam, diam1trans, 'k', label='Diam 1 att.')
+    plt.plot(shftlam, diam2trans, 'b', label='Diam 2 att.')
+    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
+               ncol=3, mode="expand", borderaxespad=0.)
+    plt.xlabel('Wavelength (A)')
+    plt.ylabel('Transmission')
+    plt.grid()
+    for i in range(len(pkpars1)):
+        plt.arrow(pkpars1[i, 0] * delam, 1.1, 0.0, 0.025,
+                  fc="k", ec="k", head_width=0, head_length=0)
+    for i in range(len(pkpars2)):
+        plt.arrow(pkpars2[i, 0] * delam, 1.15, 0.0, 0.025,
+                  fc="k", ec="k", head_width=0, head_length=0)
+    plt.xlim(1, 2.7)
+    plt.ylim(0, 1.2)
+    plt.show()
+
+    return chi2
+
+
+def SimTrans3(x):
+    '''
+    %SimTrans calculates transmission spectrum from two crystals
+    %   lam - array containing wavelengths to calc over
+    %   hkl - contains all Nref hkl's that calculation is performed for
+    %   bgd - array containing coefficients of polynomial for background
+    %   sf - overall scale factor
+    %   pktype - 1 = gauss; 2 = lorentz; ...
+    %   UB1 - UB matrix for first crystal
+    %   setang1 - setting angles for first crystal (deviations from ideal UB
+    %               location).
+    %   pkpars1 - position(lambda), position(d-spacing), position(ttheta), width, intensity for each Nref reflections
+    %   UB2,setang2,pkpars2 - as above, for second crystal
+    %
+    % M. Guthrie 21st Jan 2014
+    %
+    % calculate background profile
+    % determine number of coeffs bgd
+    %
+    % version 2 constrains intensities for equivalent dips to be the same
+    % M. Guthrie 3 April 2014
+    %
+    % M. Guthrie 7 April 2014, realised I was making an (obvious) mistake by
+    % adding the transmissions from the two diamonds. Clearly, they should be
+    % multiplied. I've implemented the change...will see what difference it
+    % makes.
+    %
+    % M. Guthrie 9 April 2014, introduced possiblity to refine L2 and also a
+    % scale factor for calculated dip wavelengths (to account for diamond
+    % compressibility).
+    '''
+    global hkl1, hkl2
+    global UB1, pkcalcint1
+    global UB2, pkcalcint2
+    global pktype
+    global lam, y, e, TOF
+    global L1
+    global ttot
+    global fxsamediam
+    global neqv1, eqvlab1, neqv2, eqvlab2
+    global difa, function_verbose
+
+    nref1 = hkl1.shape[0]  # % number of reflections to integrate over
+    nref2 = hkl2.shape[0]  # % number of reflections to integrate over
+    # % returns array with same dim as input labelling equivs
+    eqvlab1, neqv1 = findeqvs(hkl1)
+    eqvlab2, neqv2 = findeqvs(hkl2)
+
+    setang1 = x[0:3]
+    pkmult1 = x[3:4 + neqv1 - 1]
+    setang2 = x[4 + neqv1 - 1:6 + neqv1]
+    sf = x[neqv1 + neqv2 + 7 - 1]
+    pkwid1 = x[neqv1 + neqv2 + 7]
+    bgd = x[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1]
+    pkwid2 = x[neqv1 + neqv2 + 10]
+    # % if diamond intensities the same, allow single scale f
+    relsf = x[neqv1 + neqv2 + 11]
+    if fxsamediam == 1:
+        x[6 + neqv1:7 + neqv1 + neqv2 - 1] = x[3:4 + neqv2 - 1] * relsf
+        pkmult2 = x[6 + neqv1:7 + neqv1 + neqv2 - 1]
+    else:
+        pkmult2 = x[6 + neqv1:7 + neqv1 + neqv2 - 1]
+    delam = x[neqv1 + neqv2 + 12]
+    L2 = x[neqv1 + neqv2 + 13]
+
+    shftlam = 0.0039558 * TOF / (L1 + L2) + difa * (TOF**2)
+    # number of lambda points to calculate over
+    npt = shftlam.shape[0]
+    # calculate information for peaks for crystal 1 using hkl,UB1, setang,
+    # pkpos
+    a, b, c = pkposcalc(hkl1, UB1, setang1)
+    pkpars1 = np.column_stack((a, b, c))
+    # calculate information for peaks for crystal 2 using hkl,UB1, setang,
+    # pkpos
+    a, b, c = pkposcalc(hkl2, UB2, setang2)
+    pkpars2 = np.column_stack((a, b, c))
+
+    # generate nptx,nco array containing, x^0,x^1,x^2,...x^nco for
+    # all nonzero background coefficients
+    bgdco = np.where(bgd != 0)[0]
+    nco = bgdco.shape[0]
+    nonzerobgd = np.zeros(nco)
+
+    X = np.ones(shape=(nco, npt))
+    for i in range(nco):
+        X[i, :] = shftlam ** (bgd[bgdco[i]] - 1)
+        nonzerobgd[i] = bgd[bgdco[i]]
+
+    # calculate background profile by multiplying this with coefficients
+    # themselves
+    bgdprof = nonzerobgd.dot(X)
+    #bgdprof = np.outer(nonzerobgd, X)
+    # print bgdprof
+    #bgdprof = bgdprof[0, :]
+    # calculate peaks for crystal 1
+
+    t1 = np.zeros(npt)  # initialise array containing profile
+    for i in range(nref1):
+        if pktype == 1:
+            pkpars1[i][0] = pkpars1[i][0] * delam  # linear lambda shift
+            sig = pkwid1 * pkpars1[i][0] + pkwid2 * \
+                (pkpars1[i][0]**2.)  # const del(lambda)/lambda
+            extScl = pkpars1[i][0]**0  # lambda dependent extinction effect
+            t1 = t1 - extScl * pkmult1[int(eqvlab1[i])] * pkcalcint1[i] * (
+                np.exp(-((shftlam - pkpars1[i][0])**2.) / (2 * (sig**2))))
+
+    # calculate peaks for crystal 2
+    t2 = np.zeros(npt)  # initialise array containing profile
+    for i in range(nref2):
+        if pktype == 1:
+            pkpars2[i][0] = pkpars2[i][0] * delam  # linear lambda shift
+            sig = pkwid1 * pkpars2[i][0] + pkwid2 * \
+                (pkpars2[i][0]**2.)  # const del(lambda)/lambda
+            extScl = pkpars2[i][0]**0  # lambda dependent extinction effect
+            t2 = t2 - extScl * pkmult2[int(eqvlab2[i])] * pkcalcint2[i] * (
+                np.exp(-(shftlam - pkpars2[i][0])**2. / (2 * (sig**2))))
+
+    # calculate final profile
+    ttot = (bgdprof + sf * t1) * (bgdprof + sf * t2)
+    #t1 = 1.0;
+    # t2 = 1.0;
+    # introduce weighting function and calc chi2...
+    w = np.ones(len(shftlam))  # equal weighting everywhere
+    #i1 = np.where(shftlam > 2.15)[0][0]
+    #j1 = np.where(shftlam > 2.65)[0][0]
+    # w[i1:j1] = 5 #extra weighting in region of first peaks
+    # i1 = find(lam>1.68,1,'first');
+    # j1 = find(lam>2.05,1,'first');
+    # w(i1:j1)=5; %extra weighting but not too much
+
+    resid = (y - ttot) * w
+    chi2 = np.sum(resid**2. / (2 * e**2)) / npt
+
+    # Print if the user wants verbose minimization
+    if function_verbose == 'y':
+        print('Chi^2 ... ' + str(chi2))
+
+    return chi2
+
+
+def FitTrans():
+    '''
+    Main part of the program
+    '''
+    global hkl1, hkl2
+    global UB1, pkcalcint1
+    global UB2, pkcalcint2
+    global pktype
+    global lam, y, e, TOF
+    global L1
+    global ttot
+    global fxsamediam
+    global neqv1, eqvlab1, neqv2, eqvlab2
+    global difa, function_verbose
+    global run_number
+
+    # Customize constraints
+    cnstang = 1  # if set equal to one, setting angles will be constrained between
+    # limits defined by anglim1 and anglim2.
+    anglim1 = 1.0  # if cnstang ~= 1, setting angles for D2 only move by +/- this amount
+    anglim2 = 1.0  # if cnstang ~= 1, setting angles for D2 can only move by +/- this amount
+    fxsamediam = 1  # ==1 fix intensities for given hkl to be identical for both diamonds
+    fixmult = 0  # if ==1 peak multipliers are fixed during refinement
+    initL2 = 0.340  # m dist from centre of instrument to transmission det
+    delinitL2 = 0.005  # m variation in det position allowed within refinement
+    difa = -1e-10  # of order e-10
+
+    function_verbose = 'n'
+
+    # constraint notifications
+    if fxsamediam == 0:
+        print('*diamonds constrained to have same relative dip intensity*\n')
+    else:
+        print('*diamonds allowed to have different dip intensities!*')
+
+    if cnstang == 1:
+        print(
+            '*Diam {0} setting angles constrained to range of +/- {1} about their current values*'.format(1, anglim1))
+        print(
+            '*Diam {0} setting angles constrained to range of +/- {1} about their current values*'.format(2, anglim2))
+    else:
+        print('no constraint on setting angles')
+
+    if fixmult == 1:
+        print('*intensity multipliers fixed*')
+
+    # Get Input Files...
+    peaks_file = str(raw_input('Name of file containing diamond peaks: '))
+
+    run_number = str(raw_input('Input run number for transmission data: '))
+
+    # Build input filenames
+    #fullfilename_ub1 = str(run_number) + 'UB1.dat' # unused variable
+    #fullfilename_ub2 = str(run_number) + 'UB2.dat' # unused variable
+    fullfilename_trans = 'transNorm' + str(run_number) + '.dat'
+
+    # get both UB's
+    UB1, UB2 = UBMG.UBMatrixGen(peaks_file)
+
+    # [filename pathname ~] = ...
+    #     uigetfile('*.dat','Choose UB matrix for upstream diamond:');
+    # fullfilename = [pathname filename];
+    # fullfilename_ub1 = 'snap13108UB1.dat'
+    #UB1, remainder = getISAWub(fullfilename_ub1)
+
+    # [filename pathname ~] = ...
+    #     uigetfile('*.dat','Choose UB matrix for downstream diamond:');
+    # fullfilename = [pathname filename];
+    # fullfilename_ub2 = 'snap13108UB2.dat'
+    #UB2, remainder = getISAWub(fullfilename_ub2)
+
+    # get transmission data...
+    # [filename,pathname,~] = ...
+    #     uigetfile('*.csv','Choose transmission datafile:');
+    # fullfilename = [pathname filename];
+    fullfilename_trans = 'transNorm13148.csv'
+    TOF, yin, ein = getMANTIDdat_keepbinning(fullfilename_trans)
+
+    print('Starting refinement for: ' + fullfilename_trans)
+
+    # set-up simulation
+
+    L1 = 15.0  # m dist to centre of instrument in m
+
+    # global initial conditions
+    sf = 1
+    pktype = 1  # 1 = Gaussian, only current working peaktype
+    pkwid = 0.003  # peak width 'sig' is quadratic in lamda
+    pkwid2 = 2e-4  # sig = pkwid*lam+pkwid2*lam^2
+
+    #####################
+    # Start work...
+    #####################
+
+    # rebin transmission data
+    lam = 0.0039558 * TOF / (L1 + initL2)
+
+    print('wavelength limits: ' +
+          str(lam[0]) + ' and ' + str(lam[len(lam) - 1]))
+    minlam = 0.8
+    maxlam = 3.5
+    imin = np.where(lam >= minlam)[0][0]
+    imax = np.where(lam >= maxlam)[0][0]
+    lam = lam[imin:imax + 1]
+    TOF = TOF[imin:imax + 1]  # this will be the TOF range used in fit
+    y = yin[imin:imax + 1]
+    e = ein[imin:imax + 1]
+    bgd = np.array([1.0, 0.0])
+
+    # generate all allowed diamond hkls:
+    allhkl = allowedDiamRefs(-7, 7, -7, 7, -7, 7)
+
+    # initial conditions for crystal 1
+    setang1 = np.zeros(3)
+    # setang1[1:3] = 0.0 # rotation angles applied to refined UB
+    # use these to calculate resulting peak positions in wavelength
+    # pkpars1(:,1) is lambda
+    # pkpars1(:,2) is d-spacing
+    # pkpars1(:,3) is is 2theta
+    a, b, c = pkposcalc(allhkl, UB1, setang1)
+    pkpars1 = np.column_stack((a, b, c))
+
+    # initial conditions for crystal 2
+    setang2 = np.zeros(3)
+    #setang2[1:3][0] = 0.0
+    a, b, c = pkposcalc(allhkl, UB2, setang2)
+    pkpars2 = np.column_stack((a, b, c))
+
+    # purge all reflections that don't satisfy the Bragg condition and that are
+    # out of wavelength calculation range...
+
+    laminlim = lam[0]
+    lamaxlim = lam[len(lam) - 1]
+
+    nref = len(allhkl)
+
+    k1 = 0
+    k2 = 0
+    hkl1 = np.zeros(shape=(0, 3))
+    hkl2 = np.zeros(shape=(0, 3))
+    for i in range(nref):
+        if laminlim <= pkpars1[i][0] <= lamaxlim:  # reflection in range
+            hkl1 = np.vstack([hkl1, allhkl[i]])
+            k1 += 1
+
+        if laminlim <= pkpars2[i][0] <= lamaxlim:  # reflection in range
+            hkl2 = np.vstack([hkl2, allhkl[i]])
+            k2 += 1
+
+    print('There are: ' + str(k1) + ' expected dips due to Crystal 1')
+    print('There are: ' + str(k2) + ' expected dips due to Crystal 2')
+
+    # determine equivalents
+    # returns array with same dim as input labelling equivs
+    eqvlab1, neqv1 = findeqvs(hkl1)
+    eqvlab2, neqv2 = findeqvs(hkl2)
+
+    # pkpars1 = np.zeros(shape=(k, 6))   #empty array
+    a, b, c = pkposcalc(hkl1, UB1, setang1)
+    pkpars1 = np.column_stack((a, b, c))
+    # Calculated ref intensities
+    pkcalcint1 = pkintread(hkl1, (pkpars1[:, 0:3]))
+    pkcalcint1 *= 1e-6
+    pkmult1 = np.ones(neqv1)  # intensity multiplier for each group of equivs
+
+    # pkpars2 = np.zeros(shape=(l, 6))   #empty array
+    a, b, c = pkposcalc(hkl2, UB2, setang2)
+    pkpars2 = np.column_stack((a, b, c))
+    # Calculated ref intensities
+    pkcalcint2 = pkintread(hkl2, (pkpars2[:, 0:3]))
+    pkcalcint2 *= 1e-6
+    pkmult2 = np.ones(neqv2)  # peak intensity multiplier
+
+    relsf = 1.0    # default value
+    delam = 1.0
+    L2 = initL2
+    tbgd = bgd
+
+    # Either generate, or read variable array from file
+    # This is one big array with all the parameters to be refined in it.
+
+    prevf = str(raw_input('Look for pars from a previous run ([y]/n)? '))
+
+    if prevf == 'n':
+        x0 = np.hstack((setang1, pkmult1, setang2, pkmult2, sf,
+                        pkwid, tbgd, pkwid2, relsf, delam, L2))
+    else:
+            # choose which file to use
+        parfilename = str(raw_input('Choose file with starting pars: '))
+        parfullfilename = parfilename
+        x0 = dlmread(parfullfilename)
+        tog = str(raw_input('Got parameters from: \n' +
+                            parfilename + '\nUse these ([y]/n)?'))
+        if tog == 'n':
+            x0 = np.hstack((setang1, pkmult1, setang2, pkmult2,
+                            sf, pkwid, tbgd, pkwid2, relsf, delam, L2))
+            print('discarding pars from previous run')
+
+    print(str(len(x0)) + ' parameters will be refined')
+
+    nvar = len(x0)
+    print('number of variables: ' + str(nvar))
+    #nref1 = hkl1.shape[0] # unused variable
+    #nref2 = hkl2.shape[0] # unused variable
+
+    # need to apply correction in the case that pars from previous run had
+    # fxsamediam==1 and current run also has fxsamediam==1
+    # to avoid a double multiplication by relsf
+
+    if fxsamediam == 1 and x0[neqv1 + neqv2 + 11] != 1:
+        x0[6 + neqv1:7 + neqv1 + neqv2 - 1] = x0[3:4 +
+                                                 neqv2 - 1] / x0[neqv1 + neqv2 + 11]
+        print('Diam 2 peak multipliers reset: ' + str(x0[neqv1 + neqv2 + 11]))
+
+    # check starting point
+
+    chi2 = SimTrans3(x0)
+    fig_name_start = 'Starting point ' + run_number
+    plt.figure(fig_name_start)
+    plt.plot(lam, y, label='Observed')
+    plt.plot(lam, ttot, label='Calculated')
+    plt.plot(lam, (y - ttot), label='Residual')
+    plt.xlabel('Wavelength (A)')
+    plt.ylabel('Transmission')
+    plt.grid()
+    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
+               ncol=3, mode="expand", borderaxespad=0.)
+    plt.show()
+    print('Initial chi^2 is: ' + str(chi2))
+
+    showx3(x0)
+
+    # Prepare minimization of chi^2 for the calculated profile
+    # Set-up default constraints...
+    # inequalities
+    A = np.zeros(len(x0))
+    A[0:3] = 0  # setang1 *no constraint
+    A[3:4 + neqv1 - 1] = -1.0  # pkmult1 Contrains intensities to be positive
+    A[4 + neqv1 - 1:6 + neqv1] = 0.0  # setang2 *no constraint
+    A[6 + neqv1:7 + neqv1 + neqv2 - 1] = -1.0  # pkmult2
+    A[6 + neqv1 + neqv2] = -1.0     # sf Scale factor must be +ve
+    A[7 + neqv1 + neqv2] = -1.0  # pkwid peak width must be +ve
+    A[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1] = 0.0  # bgd *no constraint
+    A[(neqv1 + neqv2 + 10)] = 0.0  # *no constraint
+    A[(neqv1 + neqv2 + 11)] = 0.0  # *no constraint
+    A[(neqv1 + neqv2 + 12)] = 0.0  # *no constraint
+    A[(neqv1 + neqv2 + 13)] = 0.0  # *no constraint
+
+    # equalities
+    Aeq = np.zeros(len(x0))
+    Aeq[0:3] = 0.0  # setang1
+    Aeq[3:4 + neqv1 - 1] = 0.0  # pkmult1
+    Aeq[4 + neqv1 - 1:6 + neqv1] = 0.0  # setang2
+    Aeq[6 + neqv1:7 + neqv1 + neqv2 - 1] = 0.0  # pkmult2
+    Aeq[6 + neqv1 + neqv2] = 0.0     # sf
+    Aeq[7 + neqv1 + neqv2] = 0.0  # pkwid
+    Aeq[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1] = 0  # unfixed bgd
+    Aeq[neqv1 + neqv2 + 10] = 0
+    Aeq[neqv1 + neqv2 + 11] = 0
+    Aeq[neqv1 + neqv2 + 12] = 0
+    Aeq[neqv1 + neqv2 + 13] = 0
+
+    #beq = 0 # unused variable
+
+    # lower bounds
+    lb = np.zeros(len(x0))
+    lb[0:3] = -10  # setang1
+    lb[3:4 + neqv1 - 1] = 0.5  # pkmult1
+    lb[4 + neqv1 - 1:6 + neqv1] = -10  # setang2
+    lb[6 + neqv1:7 + neqv1 + neqv2 - 1] = 0.5  # pkmult2
+    lb[6 + neqv1 + neqv2] = 0.0     # sf
+    lb[7 + neqv1 + neqv2] = 0.0005  # pkwid
+    lb[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1] = [0.995, -0.0005]  # bgd
+    lb[neqv1 + neqv2 + 10] = 0.5e-4  # 2nd order pkwid
+    lb[neqv1 + neqv2 + 11] = 0.9  # rel scale factor must be positive
+    lb[neqv1 + neqv2 + 12] = 0.9  # min lambda shift
+    # (m) min L2 dist sample to d/stream detector
+    lb[neqv1 + neqv2 + 13] = initL2 - delinitL2
+
+    # upper bounds
+    ub = np.zeros(len(x0))
+    ub[0:3] = 10  # setang1
+    ub[3:4 + neqv1 - 1] = 50  # pkmult1
+    ub[4 + neqv1 - 1:6 + neqv1] = 10  # setang2
+    ub[6 + neqv1:7 + neqv1 + neqv2 - 1] = 50  # pkmult2
+    ub[6 + neqv1 + neqv2] = 50     # sf
+    ub[7 + neqv1 + neqv2] = 0.01  # pkwid
+    ub[neqv1 + neqv2 + 8:neqv1 + neqv2 + 9 + 2 - 1] = [1.005, 0.0005]  # bgd
+    ub[neqv1 + neqv2 + 10] = 1.0e-2  # 2nd order pkwid
+    # diamond shouldn't be more than 2 times bigger!
+    ub[neqv1 + neqv2 + 11] = 1.1
+    ub[neqv1 + neqv2 + 12] = 1.1  # max lambda shift
+    # (m) max L2 dist sample to d/stream detector
+    ub[neqv1 + neqv2 + 13] = initL2 + delinitL2
+
+    # Customize constraints
+
+    if cnstang == 1:
+        # diamond 1
+        lb[0] = x0[0] - anglim1
+        lb[1] = x0[1] - anglim1
+        lb[2] = x0[2] - anglim1
+        ub[0] = x0[0] + anglim1
+        ub[1] = x0[1] + anglim1
+        ub[2] = x0[2] + anglim1
+        # diamond 2
+        lb[3 + neqv1] = x0[3 + neqv1] - anglim2
+        lb[4 + neqv1] = x0[4 + neqv1] - anglim2
+        lb[5 + neqv1] = x0[5 + neqv1] - anglim2
+        ub[3 + neqv1] = x0[3 + neqv1] + anglim2
+        ub[4 + neqv1] = x0[4 + neqv1] + anglim2
+        ub[5 + neqv1] = x0[5 + neqv1] + anglim2
+
+    if fixmult == 1:
+        lb[3:4 + neqv1 - 1] = x0[3:4 + neqv1 - 1] - 0.01
+        lb[6 + neqv1:7 + neqv1 + neqv2 - 1] = x0[6 +
+                                                 neqv1:7 + neqv1 + neqv2 - 1] - 0.01
+        ub[3:4 + neqv1 - 1] = x0[3:4 + neqv1 - 1] + 0.01
+        ub[6 + neqv1:7 + neqv1 + neqv2 - 1] = x0[6 +
+                                                 neqv1:7 + neqv1 + neqv2 - 1] + 0.01
+
+    prompt = str(raw_input('Enter anything to begin refinement...'))
+    print('Refining...\nMight take quite a long time...')
+
+    max_number_iterations = int(
+        raw_input('Maximum number of iterations for minimization: '))
+    function_verbose = str(raw_input('Verbose minimization ([y]/n): '))
+
+    # make dictionary holding constraints for minimization
+    # equalities (all must equal 0) and inequalities
+    cons = []
+    for i in range(len(x0)):
+        cons.append({'type': 'ineq', 'fun': lambda x: -A[i] * x[i]})
+    cons = tuple(cons)
+
+    # bounds have to be list of tuples with (lower, upper) for each parameter
+    bds = np.vstack((lb, ub)).T
+    res = sp.minimize(SimTrans3, x0, method='SLSQP', bounds=bds, constraints=cons, options={'disp': True,
+                                                                                            'maxiter': max_number_iterations})
+
+    # tolerance limits to put in minimization if you want so : 'ftol': 0.001
+
+    x = np.array(res.x)
+    #
+    # minimisation...
+    #
+    # figure(2)
+    # options = optimoptions(@fmincon,'Algorithm','interior-point', 'Display','off', 'MaxFunEvals',10000*nvar,'PlotFcns'
+    #                                         @optimplotfval, 'MaxIter',4000)
+    # x, fval, exitflag, output = fmincon(@SimTrans3,x0,A,b,[],[],Aeq beq
+    # lb,ub,[],options)
+
+    # necessary to update these here...
+    if fxsamediam == 1:
+        # set peak parameters for second diamond to equal those of first
+        # but scaled by relsf
+        # len(x)
+        # neqv1+neqv2+11
+        # x[neqv1+neqv2+11]
+        x[6 + neqv1:7 + neqv1 + neqv2 - 1] = x[3:4 +
+                                               neqv2 - 1] * x[neqv1 + neqv2 + 11]
+        print('Diam 2 peak multipliers reset with factor: ' +
+              str(x[neqv1 + neqv2 + 11]))
+    else:
+        # label ensuring I know that run did not use fxsamediam
+        x[neqv1 + neqv2 + 11] = 1.0
+
+    print('AFTER REFINEMENT')
+    showx3(x)
+
+    ####
+    # output final information
+    ####
+
+    # calculate chi2 for best fit
+    chi2 = SimTrans3(x)
+    print('Final Chi2 = ' + str(chi2))
+
+    # determine output wavelength range using refined L2 value
+
+    #lamscale = x[neqv1 + neqv2 + 12] # unused variable
+    L2 = x[neqv1 + neqv2 + 13]
+    outlam = 0.0039558 * TOF / (L1 + L2) + difa * (TOF**2)
+
+    fig_name_final = 'Final result ' + run_number
+    plt.figure(fig_name_final)
+    plt.plot(outlam, y, 'k', label='Observed')
+    plt.plot(outlam, ttot, 'r', label='Calculated')
+    plt.plot(outlam, (y - ttot), 'b', label='Final residuals')
+    plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
+               ncol=3, mode="expand", borderaxespad=0.)
+    plt.text(2.1, 0.5, 'CHI^2=' + str(chi2))
+    plt.grid()
+    for i in range(len(pkpars1)):
+        plt.arrow(pkpars1[i, 0] * delam, 1.1, 0.0, 0.025,
+                  fc="k", ec="k", head_width=0, head_length=0)
+    for i in range(len(pkpars2)):
+        plt.arrow(pkpars2[i, 0] * delam, 1.15, 0.0, 0.025,
+                  fc="k", ec="k", head_width=0, head_length=0)
+    plt.xlim(1.0, 2.7)
+    plt.ylim(ymax=1.2)
+    plt.xlabel('Wavelength (A)')
+    plt.ylabel('Transmission')
+    plt.show()
+
+    prompt = str(raw_input('output best fit to file ([y]/n): '))
+    if prompt == 'n':
+        print('Ending')
+    else:
+        fitparname = str(run_number) + '.best_fit_pars3.dat'
+        np.savetxt(fitparname, x, delimiter=',')
+        print('output parameters written to file: \n' + fitparname)
+        ofilename = str(run_number) + '.fitted3.dat'
+        SimTransOutput3(ofilename, x)  # generate output file with fitted data
+
+if __name__ == "__main__":
+    FitTrans()
diff --git a/scripts/DiamondAttenuationCorrection/README.md b/scripts/DiamondAttenuationCorrection/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..bca17ffd2d6d008698f90eace5bc6d81d911c64f
--- /dev/null
+++ b/scripts/DiamondAttenuationCorrection/README.md
@@ -0,0 +1,13 @@
+This implements a Diamond Attenuation Correction for performing
+neautron TOF measurements in Diamond Anvil Cells.
+
+It contains a functionality to generate the UB matrices for the 2
+diamonds from a peaks input file where one has selected diamond peaks
+in Mantid beforehand.
+
+Uses that and the normalised, focused and background-corrected
+transmission data to extract the diamond attenuation and outputs it
+alongside the data with the attenuation excluded.
+
+This output can then be focused and the results will be a refinable
+pattern.
diff --git a/scripts/DiamondAttenuationCorrection/UBMatrixGenerator.py b/scripts/DiamondAttenuationCorrection/UBMatrixGenerator.py
new file mode 100644
index 0000000000000000000000000000000000000000..28faf3a576c1e5344f3512cd65a033723f89c581
--- /dev/null
+++ b/scripts/DiamondAttenuationCorrection/UBMatrixGenerator.py
@@ -0,0 +1,304 @@
+'''
+Generate UB matrices from measured list of reflections
+Identifies upstream and downstream diamonds and assigns matrices to them
+'''
+
+# Import all needed libraries
+import numpy as np
+import itertools as itt
+
+# Function to read the reflections measured
+
+
+def getMANTIDpkds(filename):
+    fileID = filename
+    if fileID == 1:
+        print('Error opening file: ' + filename)
+    f = open(fileID, "r")
+    lines = f.readlines()
+    f.close()
+
+    hkl = np.zeros((len(lines) - 2, 3))
+    d = np.zeros((len(lines) - 2))
+    q = np.zeros((len(lines) - 2, 3))
+
+    for i in range(1, len(lines) - 1):
+        elem = lines[i].split(',')
+
+        hkl[i - 1] = elem[2], elem[3], elem[4]
+        d[i - 1] = elem[8]
+        q[i - 1] = float(elem[15].replace('[', '')
+                         ), float(elem[16]), float(elem[17].replace(']', ''))
+
+    return hkl, d, q
+
+# Generate all permutations (including negative) for given hkl
+
+
+def plusAndMinusPermutations(items):
+    for p in itt.permutations(items):
+        for signs in itt.product([-1, 1], repeat=len(items)):
+            yield [a * sign for a, sign in zip(p, signs)]
+
+# Identify equivalent reflections
+
+
+def m3mEquiv(hkl_input, tog):
+    hkl = hkl_input
+    h = float(hkl[0])
+    k = float(hkl[1])
+    l = float(hkl[2])
+    all_equivs = np.asarray(list(plusAndMinusPermutations([h, k, l])))
+    # print all_equivs
+
+    # Remove non-unique equivalents
+    lab = np.zeros(len(all_equivs))  # label unique reflections
+    nlab = 0
+    for i in range(len(all_equivs)):
+        if lab[i] == 0:  # not checked yet
+            nlab += 1
+            for j in range(len(all_equivs)):
+                diff = all_equivs[i] - all_equivs[j]
+                if np.linalg.norm(diff) == 0:  # an identical reflection found
+                    lab[j] = nlab
+
+    #print('number of unique reflections is: {0}\n'.format(nlab))
+
+    # red is reduced array with only distinct reflections in it
+    red = np.zeros((nlab, 3))
+    for i in range(1, nlab + 1):
+        k = np.argmax(lab == i)
+        red[i - 1] = all_equivs[k]
+
+    if tog == 1:
+        k = np.where(red[:, 0] <= 0)[0]
+        eqvs = red[k]
+    else:
+        eqvs = red
+
+    return eqvs
+
+# Match equivalent reflections
+
+
+def EquivMatch(refh, hkl, gam, tol):
+    AllEqv = m3mEquiv(hkl, 1)
+    match = np.zeros(len(AllEqv))
+    nmatch = 0
+    for i in range(len(AllEqv)):
+        h1 = AllEqv[i]
+        bet = np.degrees(np.arccos(np.dot(refh, h1) /
+                                   (np.linalg.norm(refh) * np.linalg.norm(h1))))
+        dif = np.abs(bet - gam)
+        if dif <= tol:
+            match[i] = 1
+            nmatch += 1
+
+    if nmatch == 0:
+        hklmatch = [0, 0, 0]
+    else:
+        ind = np.where(match == 1)
+        hklmatch = AllEqv[ind]
+
+    return hklmatch
+
+'''Jacobsen - Implementation of method articulated in RA Jacobsen
+ Zeitschrift fur Krystallographie(1996).
+
+Note!!!! mantidplot scales reciprocal space coordinates with a factor of
+2 pi.In contrast, ISAWev does not.This algorithm assumes the mantidplot convention!!!!
+
+h1 and h2 are vertical 3x1 coordinate matrices containing h, k, l for two reflections
+Xm_1 and Xm_2 are the corresponding coordinate matrices measured in the (Cartesian)
+diffractometer frame Xm(these are known by mantid for a calibrated instrument)
+
+First check indexing of input reflections by checking angle: angle between reciprocal
+lattice vectors
+'''
+
+
+def Jacobsen(h1, Xm_1, h2, Xm_2):
+    alp = np.degrees(np.arccos(np.dot(h1, h2) /
+                               (np.linalg.norm(h1) * np.linalg.norm(h2))))
+    bet = np.degrees(np.arccos(np.dot(Xm_1, Xm_2) /
+                               (np.linalg.norm(Xm_1) * np.linalg.norm(Xm_2))))
+    if ((alp - bet)**2) > 1:
+        print('check your indexing!')
+
+    a = 3.567  # diamond lattice parameter
+    # recip lattice par(note this is the mantid convention: no 2 pi)
+    ast = (2 * np.pi) / a
+    B = np.array([[ast, 0, 0], [0, ast, 0], [0, 0, ast]])
+    Xm_g = np.cross(Xm_1, Xm_2)
+    Xm = np.column_stack([Xm_1, Xm_2, Xm_g])
+
+    # Vector Q1 is described in reciprocal space by its coordinate matrix h1
+    Xa_1 = B.dot(h1)
+    Xa_2 = B.dot(h2)
+    Xa_g = np.cross(Xa_1, Xa_2)
+    Xa = np.column_stack((Xa_1, Xa_2, Xa_g))
+
+    R = Xa.dot(np.linalg.inv(Xm))
+    U = np.linalg.inv(R)
+
+    UB = U.dot(B)
+
+    return UB
+
+# Guess Miller indices based on d-spacing
+
+
+def guessIndx(d, tol):
+    # guessIndx accepts n d-spacings and returns guess at indexing class for
+    # diamond
+    dref = np.array([2.0593, 1.2611, 1.0754, 0.8917, 0.8183, 0.7281])
+    # note, by default assume that diamond a / a * axis is close to parallel to beam, therefore, h index
+    # will be negative for all reflections
+    href = np.array([[-1, 1, 1], [-2, 2, 0], [-3, 1, 1],
+                     [-4, 0, 0], [-3, 3, 1], [-4, 2, 2]])
+
+    h = np.zeros((len(d), 3))
+    for i in range(len(d)):
+        delta = np.abs(dref - d[i])
+        hit = np.where(delta < tol)
+        h[i] = href[hit]
+
+    return h
+
+
+def UBMatrixGen(fileName):
+    # read ascii file with mantidplot peaks list
+    h, d, q = getMANTIDpkds(fileName)
+    # sort peaks according to d-spacing
+    dsort = sorted(d)[::-1]
+    sortindx = np.argsort(d)[::-1]
+    N = len(d)
+    ublab = np.zeros(N)  # will be label for UB/diamond
+
+    hsort = np.zeros((N, 3))
+    qsort = np.zeros((N, 3))
+    for i in range(N):
+        hsort[i] = h[sortindx[i]]
+        qsort[i] = q[sortindx[i]]
+    d = dsort
+    h = hsort
+    q = qsort
+    h = guessIndx(d, 0.05)  # overwrites what's in original file with guess
+    # based on d-spacing
+
+    # display all reflections with guessed indices, allow choice of one
+    # reflection as reference reflection
+    print('First guess at indexing\n')
+    print('REF | h k l | d-spac(A)')
+    for i in range(N):
+        print('{0:0.0f}    {1:0.0f} {2:0.0f} {3:0.0f}     {4:0.3f}'.format(
+            i, h[i][0], h[i][1], h[i][2], d[i]))
+
+    nref1 = int(raw_input('Choose one reference reflection: '))
+
+    print('REF | h k l | obs|  calc')
+    beta = np.zeros(N)
+    for i in range(N):
+        beta[i] = np.degrees(np.arccos(
+            np.dot(q[nref1], q[i]) / (np.linalg.norm(q[nref1]) * np.linalg.norm(q[i]))))
+        if i == nref1:
+            print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f}   |  {4:0.3f}|  0.0| REFERENCE'.format(
+                i, h[i][0], h[i][1], h[i][2], beta[i]))
+        else:
+            # check for possible index suggestion
+            hklA = h[nref1]
+            hklB = h[i]
+            hklhit = EquivMatch(hklA, hklB, beta[i], 1.0)
+            if np.linalg.norm(hklhit) == 0:
+                print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} |    {4:0.3f}'.format(
+                    i, h[i][0], h[i][1], h[i][2], beta[i]))
+            else:  # % there is an hkl at a matching angle
+                calcang = np.degrees(np.arccos(
+                    np.dot(hklA, hklhit[0]) / (np.linalg.norm(hklA) * np.linalg.norm(hklhit[0]))))
+                h[i] = hklhit[0]
+                print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} |    {4:0.3f} | {5:0.3f}'.format(
+                    i, h[i][0], h[i][1], h[i][2], beta[i], calcang))
+
+    nref2 = int(raw_input('Choose a second reflection to use for indexing: '))
+
+    h1 = h[nref1]
+    q1 = q[nref1]
+    q2 = q[nref2]
+    h2 = h[nref2]
+
+    UB1 = Jacobsen(h1, q1, h2, q2)
+
+    # Re-index all input reflections using this UB
+    hindx = (np.linalg.inv(UB1).dot(q.transpose())).transpose()
+    print('Reflections will be re-indexed using this UB')
+    tol = float(raw_input('Enter tolerance for accepting index: '))
+    print('REF | h k l | obs|  calc')
+    nindexed1 = 0
+    for i in range(N):   # decide if reflection is indexed to being within an integer by less then the tolerance
+        # difference with nearst integer
+        dif = np.abs(hindx[i] - np.round(hindx[i]))
+        if np.sum(dif) <= 3 * tol:  # all indices within tolerance
+            h[i] = np.round(hindx[i])
+            print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} | '.format(
+                i, hindx[i][0], hindx[i][1], hindx[i][2]))
+            nindexed1 += 1
+            ublab[i] = 1
+        else:
+            print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} | '.format(
+                i, hindx[i][0], hindx[i][1], hindx[i][2]))
+            ublab[i] = 2
+    print('{0:0.0f} reflections indexed!'.format(nindexed1))
+    nsub = N - nindexed1
+
+    if nsub < 2:
+        print('not enough remaining reflections to index second diamond :(')
+    else:
+        k = np.where(ublab == 2)
+        hsub = np.array(h[k])   # a list of unindexed h
+        qsub = np.array(q[k])   # and their q - vectors
+        d = np.array(d)
+        dsub = d[k]
+
+        print('Now find UB for second diamond')
+        print('Remaining unindexed reflections:')
+        print(' REF|  h  k  l| d-spac(A)')
+        for i in range(nsub):
+            print('{0:0.0f}    {1:0.0f} {2:0.0f} {3:0.0f}     {4:0.3f}'.format(
+                i, hsub[i][0], hsub[i][1], hsub[i][2], dsub[i]))
+
+        nref1 = int(raw_input('Choose one reference reflection: '))
+
+        for i in range(nsub):
+            beta[i] = np.degrees(np.arccos(np.dot(qsub[nref1], qsub[
+                                 i]) / (np.linalg.norm(qsub[nref1]) * np.linalg.norm(qsub[i]))))
+            if i == nref1:
+                print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f}   |  {4:0.3f}|  0.0| REFERENCE'.format(i, hsub[i][0], hsub[i][1],
+                                                                                                      hsub[i][2], beta[i]))
+            else:
+                # check for possible index suggestion
+                hklA = hsub[nref1]
+                hklB = hsub[i]
+                hklhit = EquivMatch(hklA, hklB, beta[i], 1.0)
+                if np.linalg.norm(hklhit) == 0:
+                    print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} |    {4:0.3f}'.format(i, hsub[i][0], hsub[i][1], hsub[i][2],
+                                                                                         beta[i]))
+                else:  # % there is an hkl at a matching angle
+                    calcang = np.degrees(np.arccos(
+                        np.dot(hklA, hklhit[0]) / (np.linalg.norm(hklA) * np.linalg.norm(hklhit[0]))))
+                    h[i] = hklhit[0]
+                    print('{0:0.0f} |   {1:0.0f} {2:0.0f} {3:0.0f} |    {4:0.3f} | {5:0.3f}'.format(i, hsub[i][0], hsub[i][1],
+                                                                                                    hsub[i][
+                                                                                                        2], beta[i],
+                                                                                                    calcang))
+        nref2 = int(
+            raw_input('Choose a second reflection to use for indexing: '))
+
+    h1 = hsub[nref1]
+    q1 = qsub[nref1]
+    q2 = qsub[nref2]
+    h2 = hsub[nref2]
+
+    UB2 = Jacobsen(h1, q1, h2, q2)
+    print 'UB1 = ', UB1
+    print 'UB2 = ', UB2
+    return UB1, UB2
diff --git a/scripts/Engineering/EnggUtils.py b/scripts/Engineering/EnggUtils.py
index 6514f44832d1e0dd2de7a0549422b421d87a34db..a4f0070d8b31cc84122e75035b16a13464691af5 100644
--- a/scripts/Engineering/EnggUtils.py
+++ b/scripts/Engineering/EnggUtils.py
@@ -343,6 +343,7 @@ def sumSpectra(parent, ws):
     """
     alg = parent.createChildAlgorithm('SumSpectra')
     alg.setProperty('InputWorkspace', ws)
+    alg.setProperty('RemoveSpecialValues', True)
     alg.execute()
 
     return alg.getProperty('OutputWorkspace').value
diff --git a/scripts/Examples/SolidAngle_Example.py b/scripts/Examples/SolidAngle_Example.py
index ca0359a854d0b2b097f1a753d61eb399ce3f622b..c6b2bc50220d521ecc0f5cbbced38a60bbda959f 100644
--- a/scripts/Examples/SolidAngle_Example.py
+++ b/scripts/Examples/SolidAngle_Example.py
@@ -28,9 +28,9 @@ phi = detector.getPhi()
 
 print 'R = ' + str(r) + ', TwoTheta = ' + str(twoTheta)+ ', Phi = ' + str(phi)
 
-# Check if the detector is masked out and calculate the result if not
+# Check if the spectrum is masked out and calculate the result if not
 solidAngle = 0.0
-if not detector.isMasked():
+if not rawData.spectrumInfo().isMasked(0):
     sAngle = detector.solidAngle(samplePos)
 
 print "The solid angle of the spectrum located at index " + str(wsIndex) + " is: " + str(sAngle) + " steradians"
diff --git a/scripts/HFIR_4Circle_Reduction/MainWindow.ui b/scripts/HFIR_4Circle_Reduction/MainWindow.ui
index 31133931c488a937fe7ba71c7964d8c05a8ce03e..3f4c6aa6b59885cb43f09566a4c33eff1fbb64e2 100644
--- a/scripts/HFIR_4Circle_Reduction/MainWindow.ui
+++ b/scripts/HFIR_4Circle_Reduction/MainWindow.ui
@@ -637,7 +637,7 @@ p, li { white-space: pre-wrap; }
                <string>Instrument Calibration</string>
               </property>
               <layout class="QGridLayout" name="gridLayout_16">
-               <item row="0" column="7">
+               <item row="0" column="11">
                 <spacer name="horizontalSpacer_26">
                  <property name="orientation">
                   <enum>Qt::Horizontal</enum>
@@ -650,7 +650,7 @@ p, li { white-space: pre-wrap; }
                  </property>
                 </spacer>
                </item>
-               <item row="1" column="7">
+               <item row="1" column="11">
                 <spacer name="horizontalSpacer_16">
                  <property name="orientation">
                   <enum>Qt::Horizontal</enum>
@@ -664,7 +664,7 @@ p, li { white-space: pre-wrap; }
                 </spacer>
                </item>
                <item row="0" column="1">
-                <widget class="QLineEdit" name="lineEdit">
+                <widget class="QLineEdit" name="lineEdit_defaultSampleDetDistance">
                  <property name="enabled">
                   <bool>false</bool>
                  </property>
@@ -689,7 +689,7 @@ p, li { white-space: pre-wrap; }
                <item row="1" column="2">
                 <widget class="QPushButton" name="pushButton_applyCalibratedSampleDistance">
                  <property name="enabled">
-                  <bool>false</bool>
+                  <bool>true</bool>
                  </property>
                  <property name="text">
                   <string>Apply</string>
@@ -706,13 +706,6 @@ p, li { white-space: pre-wrap; }
                  </property>
                 </widget>
                </item>
-               <item row="0" column="4">
-                <widget class="QLabel" name="label_36">
-                 <property name="text">
-                  <string>Wavelength</string>
-                 </property>
-                </widget>
-               </item>
                <item row="0" column="3">
                 <spacer name="horizontalSpacer_29">
                  <property name="orientation">
@@ -732,31 +725,21 @@ p, li { white-space: pre-wrap; }
                <item row="0" column="0">
                 <widget class="QLabel" name="label_33">
                  <property name="text">
-                  <string>Standard Detector Sample Distance</string>
-                 </property>
-                </widget>
-               </item>
-               <item row="0" column="5">
-                <widget class="QLineEdit" name="lineEdit_userWaveLength">
-                 <property name="sizePolicy">
-                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-                   <horstretch>0</horstretch>
-                   <verstretch>0</verstretch>
-                  </sizepolicy>
+                  <string>Default Detector Sample Distance</string>
                  </property>
                 </widget>
                </item>
-               <item row="0" column="6">
-                <widget class="QPushButton" name="pushButton_applyUserWavelength">
+               <item row="0" column="8">
+                <widget class="QLabel" name="label_36">
                  <property name="text">
-                  <string>Apply</string>
+                  <string>Wavelength</string>
                  </property>
                 </widget>
                </item>
                <item row="1" column="4">
                 <widget class="QLabel" name="label_10">
                  <property name="text">
-                  <string>Detector Center</string>
+                  <string>Calibrated Detector Center</string>
                  </property>
                 </widget>
                </item>
@@ -770,6 +753,15 @@ p, li { white-space: pre-wrap; }
                      <verstretch>0</verstretch>
                     </sizepolicy>
                    </property>
+                   <property name="maximumSize">
+                    <size>
+                     <width>100</width>
+                     <height>16777215</height>
+                    </size>
+                   </property>
+                   <property name="toolTip">
+                    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;ROW NUMBER&lt;/span&gt; of User-specified detector center&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+                   </property>
                   </widget>
                  </item>
                  <item>
@@ -780,6 +772,15 @@ p, li { white-space: pre-wrap; }
                      <verstretch>0</verstretch>
                     </sizepolicy>
                    </property>
+                   <property name="maximumSize">
+                    <size>
+                     <width>100</width>
+                     <height>16777215</height>
+                    </size>
+                   </property>
+                   <property name="toolTip">
+                    <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;COLUMN NUMBER&lt;/span&gt; of User-specified detector center&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+                   </property>
                   </widget>
                  </item>
                 </layout>
@@ -787,13 +788,66 @@ p, li { white-space: pre-wrap; }
                <item row="1" column="6">
                 <widget class="QPushButton" name="pushButton_applyUserDetCenter">
                  <property name="enabled">
-                  <bool>false</bool>
+                  <bool>true</bool>
                  </property>
                  <property name="text">
                   <string>Apply</string>
                  </property>
                 </widget>
                </item>
+               <item row="0" column="4">
+                <widget class="QLabel" name="label_19">
+                 <property name="text">
+                  <string>Default Detector Center</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="10">
+                <widget class="QPushButton" name="pushButton_applyUserWavelength">
+                 <property name="text">
+                  <string>Apply</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="7">
+                <spacer name="horizontalSpacer_34">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Preferred</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="0" column="9">
+                <widget class="QLineEdit" name="lineEdit_userWaveLength">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string/>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="5">
+                <widget class="QLineEdit" name="lineEdit_defaultDetCenter">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>115, 128</string>
+                 </property>
+                </widget>
+               </item>
               </layout>
              </widget>
             </item>
@@ -4479,6 +4533,22 @@ p, li { white-space: pre-wrap; }
             <string>Advanced Setup</string>
            </attribute>
            <layout class="QGridLayout" name="gridLayout_27">
+            <item row="0" column="2">
+             <spacer name="horizontalSpacer_25">
+              <property name="orientation">
+               <enum>Qt::Horizontal</enum>
+              </property>
+              <property name="sizeType">
+               <enum>QSizePolicy::MinimumExpanding</enum>
+              </property>
+              <property name="sizeHint" stdset="0">
+               <size>
+                <width>40</width>
+                <height>20</height>
+               </size>
+              </property>
+             </spacer>
+            </item>
             <item row="0" column="0">
              <widget class="QGroupBox" name="groupBox_16">
               <property name="title">
@@ -4495,7 +4565,7 @@ p, li { white-space: pre-wrap; }
                <item row="4" column="3">
                 <widget class="QLabel" name="label_last3Path">
                  <property name="sizePolicy">
-                  <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                  <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
                    <horstretch>0</horstretch>
                    <verstretch>0</verstretch>
                   </sizepolicy>
@@ -4543,11 +4613,17 @@ p, li { white-space: pre-wrap; }
                <item row="1" column="3">
                 <widget class="QLabel" name="label_last1Path">
                  <property name="sizePolicy">
-                  <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                  <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
                    <horstretch>0</horstretch>
                    <verstretch>0</verstretch>
                   </sizepolicy>
                  </property>
+                 <property name="minimumSize">
+                  <size>
+                   <width>200</width>
+                   <height>0</height>
+                  </size>
+                 </property>
                  <property name="text">
                   <string>EMPTY</string>
                  </property>
@@ -4556,7 +4632,7 @@ p, li { white-space: pre-wrap; }
                <item row="2" column="3">
                 <widget class="QLabel" name="label_last2Path">
                  <property name="sizePolicy">
-                  <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                  <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
                    <horstretch>0</horstretch>
                    <verstretch>0</verstretch>
                   </sizepolicy>
@@ -4599,7 +4675,7 @@ p, li { white-space: pre-wrap; }
               </layout>
              </widget>
             </item>
-            <item row="1" column="0">
+            <item row="2" column="0">
              <spacer name="verticalSpacer_25">
               <property name="orientation">
                <enum>Qt::Vertical</enum>
@@ -4615,13 +4691,13 @@ p, li { white-space: pre-wrap; }
               </property>
              </spacer>
             </item>
-            <item row="0" column="1">
-             <spacer name="horizontalSpacer_25">
+            <item row="1" column="2">
+             <spacer name="horizontalSpacer_35">
               <property name="orientation">
                <enum>Qt::Horizontal</enum>
               </property>
               <property name="sizeType">
-               <enum>QSizePolicy::Expanding</enum>
+               <enum>QSizePolicy::MinimumExpanding</enum>
               </property>
               <property name="sizeHint" stdset="0">
                <size>
@@ -4631,6 +4707,117 @@ p, li { white-space: pre-wrap; }
               </property>
              </spacer>
             </item>
+            <item row="1" column="0">
+             <widget class="QGroupBox" name="groupBox_23">
+              <property name="title">
+               <string>Constants</string>
+              </property>
+              <layout class="QGridLayout" name="gridLayout_6">
+               <item row="2" column="2">
+                <widget class="QLineEdit" name="lineEdit_pixelSizeX">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="text">
+                  <string>0.0001984375</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="2" column="0">
+                <widget class="QLabel" name="label_21">
+                 <property name="text">
+                  <string>Pixel Size</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="0">
+                <widget class="QLabel" name="label_20">
+                 <property name="text">
+                  <string>Sample-detector Distance Tolerance</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="2">
+                <widget class="QLineEdit" name="lineEdit_sampleDetDistTol">
+                 <property name="sizePolicy">
+                  <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+                   <horstretch>0</horstretch>
+                   <verstretch>0</verstretch>
+                  </sizepolicy>
+                 </property>
+                 <property name="maximumSize">
+                  <size>
+                   <width>10000</width>
+                   <height>16777215</height>
+                  </size>
+                 </property>
+                 <property name="text">
+                  <string>0.2</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="1" column="1">
+                <spacer name="horizontalSpacer_36">
+                 <property name="orientation">
+                  <enum>Qt::Horizontal</enum>
+                 </property>
+                 <property name="sizeType">
+                  <enum>QSizePolicy::Preferred</enum>
+                 </property>
+                 <property name="sizeHint" stdset="0">
+                  <size>
+                   <width>40</width>
+                   <height>20</height>
+                  </size>
+                 </property>
+                </spacer>
+               </item>
+               <item row="2" column="3">
+                <widget class="QLineEdit" name="lineEdit_pixelSizeY">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>0.0001984375</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="2">
+                <widget class="QLineEdit" name="lineEdit_numPixelRow">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>256</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="3">
+                <widget class="QLineEdit" name="lineEdit_numPixelColumn">
+                 <property name="enabled">
+                  <bool>false</bool>
+                 </property>
+                 <property name="text">
+                  <string>256</string>
+                 </property>
+                </widget>
+               </item>
+               <item row="0" column="0">
+                <widget class="QLabel" name="label_22">
+                 <property name="text">
+                  <string>Detector Pixel Size</string>
+                 </property>
+                </widget>
+               </item>
+              </layout>
+             </widget>
+            </item>
            </layout>
           </widget>
          </widget>
diff --git a/scripts/HFIR_4Circle_Reduction/NTableWidget.py b/scripts/HFIR_4Circle_Reduction/NTableWidget.py
index 13fe655c7bad77eff1ab34a1e382e32fd838796b..e8ffda0c330e0a777e2784aa40da0dbca955ec60 100644
--- a/scripts/HFIR_4Circle_Reduction/NTableWidget.py
+++ b/scripts/HFIR_4Circle_Reduction/NTableWidget.py
@@ -419,7 +419,6 @@ class NTableWidget(QtGui.QTableWidget):
         self.remove_all_rows()
 
         # add rows back
-        print '[DB-BAT] Sort by column %d. Keys = ' % column_index, key_list, 'sort_order = ', sort_order
         for key_value in key_list:
             self.append_row(row_content_dict[key_value])
         # END-FOR
diff --git a/scripts/HFIR_4Circle_Reduction/absorption.py b/scripts/HFIR_4Circle_Reduction/absorption.py
index a8bf6f3201af90ae2d47fc953699abe12b4891cd..78c87c9b36853cbfc937aa56cf8b7c405123b190 100644
--- a/scripts/HFIR_4Circle_Reduction/absorption.py
+++ b/scripts/HFIR_4Circle_Reduction/absorption.py
@@ -273,8 +273,6 @@ def calculate_b_matrix(lattice):
     b_matrix[2, 1] = 0
     b_matrix[2, 2] = 1 / lattice.get_c()
 
-    #  print '[DB...TEST] B matrix: determination = ', numpy.linalg.det(b_matrix), '\n', b_matrix
-
     return b_matrix
 
 
@@ -286,8 +284,6 @@ def calculate_upphi(omg0, theta2ave, chiave, phiave):
     up_phi[1] = m_sin(theta2ave*0.5+omg0)*m_cos(chiave)*m_sin(phiave)-m_cos(theta2ave*0.5+omg0)*m_cos(phiave)
     up_phi[2] = m_sin(theta2ave*0.5+omg0)*m_sin(chiave)
 
-    print '[DB...TEST] UP PHI = ', up_phi, '|UP PHI| = ', numpy.dot(up_phi, up_phi)
-
     return up_phi
 
 
@@ -299,8 +295,6 @@ def calculate_usphi(omg0, theta2ave, chiave, phiave):
     us_phi[1] = m_sin(theta2ave*0.5-omg0)*m_cos(chiave)*m_sin(phiave)+m_cos(theta2ave*0.5-omg0)*m_cos(phiave)
     us_phi[2] = m_sin(theta2ave*0.5-omg0)*m_sin(chiave)
 
-    print '[DB...TEST] US PHI = ', us_phi, '|US PHI| = ', numpy.dot(us_phi, us_phi)
-
     return us_phi
 
 
@@ -316,9 +310,6 @@ def calculate_absorption_correction_spice(exp_number, scan_number, lattice, ub_m
     phiave = get_average_spice_table(exp_number, scan_number, 'phi') # sum(phi(:))/length(phi);
     omg0 = theta2ave * 0.5
 
-    print '[DB...TEST] Exp = %d Scan = %d:\n2theta = %f, chi = %f, phi = %f, omega = %f' \
-          '' % (exp_number, scan_number, theta2ave, chiave, phiave, omg0)
-
     upphi = calculate_upphi(omg0, theta2ave, chiave, phiave)
     usphi = calculate_usphi(omg0, theta2ave, chiave, phiave)
 
@@ -421,9 +412,6 @@ def calculate_absorption_correction_2(exp_number, scan_number, spice_ub_matrix):
     phiave = get_average_spice_table(exp_number, scan_number, 'phi')  # sum(phi(:))/length(phi);
     avg_omega = get_average_omega(exp_number, scan_number)
 
-    print '[DB...TEST] Exp = %d Scan = %d:\n2theta = %f, chi = %f, phi = %f, omega = %s' % (
-        exp_number, scan_number, theta2ave, chiave, phiave, str(avg_omega))
-
     up_phi = calculate_upphi(avg_omega, theta2ave, chiave, phiave)
     us_phi = calculate_usphi(avg_omega, theta2ave, chiave, phiave)
 
diff --git a/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py b/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py
index 9e90b25bf88760bae3d7f9098d1335547f32a462..32a8c46649cb4b8b9520316aedae1b917f8ab2c5 100644
--- a/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py
+++ b/scripts/HFIR_4Circle_Reduction/fourcircle_utility.py
@@ -660,8 +660,6 @@ def round_hkl_1(hkl):
     :param hkl:
     :return:
     """
-    print type(hkl)
-
     mi_h = round(hkl[0])
     mi_k = round(hkl[1])
     mi_l = round(hkl[2])
diff --git a/scripts/HFIR_4Circle_Reduction/fputility.py b/scripts/HFIR_4Circle_Reduction/fputility.py
index 86e6ead192465a9cdabecd305d647166808ec7cc..e893e95e190d50d7d1dbdf2ea2acdc533f200951 100644
--- a/scripts/HFIR_4Circle_Reduction/fputility.py
+++ b/scripts/HFIR_4Circle_Reduction/fputility.py
@@ -197,8 +197,6 @@ def write_scd_fullprof_kvector(user_header, wave_length, k_vector_dict, peak_dic
     # END-IF
 
     # peak intensities
-    print '[DB...BAT] Number of peaks to output: ', len(peak_dict_list)
-
     for i_peak, peak_dict in enumerate(peak_dict_list):
         # check
         assert isinstance(peak_dict, dict), '%d-th peak must be a dictionary but not %s.' % (i_peak,
diff --git a/scripts/HFIR_4Circle_Reduction/guiutility.py b/scripts/HFIR_4Circle_Reduction/guiutility.py
index 55371451d3db810cfe7e2bdc09582e7751d2bac0..3c7dea5d4b332044c74c543439eadc036b81806f 100644
--- a/scripts/HFIR_4Circle_Reduction/guiutility.py
+++ b/scripts/HFIR_4Circle_Reduction/guiutility.py
@@ -424,7 +424,7 @@ def show_message(parent=None, message='show message here!'):
     show message
     :param parent:
     :param message:
-    :return:
+    :return: True for accepting.  False for rejecting or cancelling
     """
     dialog = DisplayDialog(parent)
     dialog.show_message(message)
diff --git a/scripts/HFIR_4Circle_Reduction/hfctables.py b/scripts/HFIR_4Circle_Reduction/hfctables.py
index 36f01147e3e28197a5270f52151cc3326334d97e..4269976ed3b050608d85c7fa7908e6444c4dd3de 100644
--- a/scripts/HFIR_4Circle_Reduction/hfctables.py
+++ b/scripts/HFIR_4Circle_Reduction/hfctables.py
@@ -1087,11 +1087,9 @@ class ScanSurveyTable(tableBase.NTableWidget):
             # check with filters: original order is counts, scan, Pt., ...
             scan_number = sum_item[1]
             if scan_number < start_scan or scan_number > end_scan:
-                # print 'Scan %d is out of range.' % scan_number
                 continue
             counts = sum_item[0]
             if counts < min_counts or counts > max_counts:
-                # print 'Scan %d Counts %f is out of range.' % (scan_number, counts)
                 continue
 
             # modify for appending to table
diff --git a/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py
index cbdcd45faa357e3accccffbbbe3443c29faee552..83115051cad2cfe50bfaa7b031a88466ee7ff105 100644
--- a/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py
+++ b/scripts/HFIR_4Circle_Reduction/mplgraphicsview.py
@@ -197,8 +197,6 @@ class IndicatorManager(object):
 
         for line_key in self._lineManager.keys():
 
-            print '[MplGraph DB] Exam indicator key %s' % str(self._lineManager[line_key])
-
             if x is not None and y is not None:
                 # 2 way
                 raise NotImplementedError('ASAP')
@@ -222,7 +220,6 @@ class IndicatorManager(object):
         :return:
         """
         if line_id is not None:
-            print '[DB] Get line style. ID = %s' % str(line_id)
             style = '--'
         else:
             style = '--'
@@ -306,8 +303,6 @@ class IndicatorManager(object):
         :param dy:
         :return:
         """
-        # print self._lineManager[my_id][0]
-
         if self._indicatorTypeDict[my_id] == 0:
             # horizontal
             self._lineManager[my_id][1] += dy
@@ -797,7 +792,6 @@ class MplGraphicsView(QtGui.QWidget):
         # process marker if it has information
         if marker.count(' (') > 0:
             marker = marker.split(' (')[0]
-        # print "[DB] Print line %d: marker = %s, color = %s" % (self._myLineMarkerColorIndex, marker, color)
 
         # update the index
         self._myLineMarkerColorIndex += 1
@@ -973,7 +967,6 @@ class Qt4MplCanvas(FigureCanvas):
         """
         if self.axes2 is None:
             self.axes2 = self.axes.twinx()
-            # print self.par1, type(self.par1)
 
         # Hold previous data
         self.axes2.hold(True)
@@ -1303,9 +1296,6 @@ class Qt4MplCanvas(FigureCanvas):
 
         handles, labels = self.axes.get_legend_handles_labels()
         self.axes.legend(handles, labels, loc=location)
-        # print handles
-        # print labels
-        #self.axes.legend(self._myLegendHandlers, self._myLegentLabels)
 
         return
 
diff --git a/scripts/HFIR_4Circle_Reduction/mplgraphicsview3d.py b/scripts/HFIR_4Circle_Reduction/mplgraphicsview3d.py
index 6d8f0af9cd4c4bcb97112071dd8629a991f37e99..da1b11b1872f77403bf9f25f08c06b7a7a9e7b87 100644
--- a/scripts/HFIR_4Circle_Reduction/mplgraphicsview3d.py
+++ b/scripts/HFIR_4Circle_Reduction/mplgraphicsview3d.py
@@ -53,7 +53,6 @@ class MplPlot3dCanvas(FigureCanvas):
         Clear all the figures from canvas
         :return:
         """
-        print '[DB-INFO] There are %d plots in current plot list.' % len(self._currPlotList)
         for plt in self._currPlotList:
             # del plt
             self._myAxes.collections.remove(plt)
diff --git a/scripts/HFIR_4Circle_Reduction/multi_threads_helpers.py b/scripts/HFIR_4Circle_Reduction/multi_threads_helpers.py
index 70bb3b8a311b78017d32e2931f8e63b13de357c9..7bc322f9e753afe495ab9c611587a7018b788509 100644
--- a/scripts/HFIR_4Circle_Reduction/multi_threads_helpers.py
+++ b/scripts/HFIR_4Circle_Reduction/multi_threads_helpers.py
@@ -178,12 +178,8 @@ class IntegratePeaksThread(QThread):
             assert isinstance(scan_tup, tuple) and len(scan_tup) == 3
             scan_number, pt_number_list, merged = scan_tup
 
-            print '[DB...BAT] IntegratePeakThread: Scan %d' % scan_number
-
             # emit signal for run start (mode 0)
             mode = int(0)
-            print '[DB...BAT] IntegratePeakThread: Sent out signal (1): %d, %d, %f' % (self._expNumber, scan_number,
-                                                                                       float(index))
             self.peakMergeSignal.emit(self._expNumber, scan_number, float(index), [0., 0., 0.], mode)
 
             # merge if not merged
@@ -214,7 +210,7 @@ class IntegratePeaksThread(QThread):
                 # self._mainWindow.ui.tableWidget_mergeScans.set_status(scan_number, 'Merged')
             else:
                 # merged
-                print '[DB...BAT] Scan %s is merged (in thread)!' % scan_number
+                pass
             # END-IF
 
             # calculate peak center
@@ -245,9 +241,6 @@ class IntegratePeaksThread(QThread):
                                                                           self._selectedMaskName)
 
             # integrate peak
-            print '[DB...BAD] Normalization: %s; Use Mask = %s, Mask Workspace = %s.' % (
-                self._normalizeType, str(self._maskDetector), self._selectedMaskName
-            )
             try:
                 status, ret_obj = self._mainWindow.controller.integrate_scan_peaks(exp=self._expNumber,
                                                                                    scan=scan_number,
@@ -258,9 +251,8 @@ class IntegratePeaksThread(QThread):
                                                                                    normalization=self._normalizeType,
                                                                                    mask_ws_name=self._selectedMaskName)
             except ValueError as val_err:
-                print '[DB] Unable to integrate scan %d due to %s.' % (scan_number, str(val_err))
                 status = False
-                ret_obj = '%s.' % str(val_err)
+                ret_obj = 'Unable to integrate scan {0} due to {1}.'.format(scan_number, str(val_err))
 
             # handle integration error
             if status:
@@ -284,8 +276,6 @@ class IntegratePeaksThread(QThread):
             mode = 1
             # center_i
             self.peakMergeSignal.emit(self._expNumber, scan_number, float(intensity_i), list(peak_centre), mode)
-            print '[DB...BAT] IntegratePeakThread: Sent out signal (2): %d, %d, %f' % (self._expNumber, scan_number,
-                                                                                       float(intensity_i))
         # END-FOR
 
         # terminate the process
diff --git a/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py b/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py
index af2e7ab1c536edb78aa8404f67eff5b3e0316bc3..8af4c2f98cd67567c65b6e9a8d1879f5400a09d7 100644
--- a/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py
+++ b/scripts/HFIR_4Circle_Reduction/peakprocesshelper.py
@@ -293,8 +293,6 @@ class PeakProcessRecord(object):
         """
         assert isinstance(pt_intensity_dict, dict)
 
-        print '[DB...BAT] Pt intensity dict keys: ', pt_intensity_dict.keys()
-
         self._ptIntensityDict = pt_intensity_dict
 
         return
diff --git a/scripts/HFIR_4Circle_Reduction/project_manager.py b/scripts/HFIR_4Circle_Reduction/project_manager.py
index 38f1dcd15dda3bf67237817a9283e80b372c89f0..0d2463d4ed5d5a709458d7e20b4d1d7e8f742f72 100644
--- a/scripts/HFIR_4Circle_Reduction/project_manager.py
+++ b/scripts/HFIR_4Circle_Reduction/project_manager.py
@@ -73,12 +73,15 @@ class ProjectManager(object):
         :param overwrite: if specified, then any existing files with same name will be rewritten
         :return:
         """
+        # create workspace directory
         self.create_workspace_directory()
 
+        print '[INFO] Saving {0} MDEventWorkspaces to {1}.'.format(len(self._wsList), self._wsDir)
+
         # save MDs
         for ws_name in self._wsList:
             md_file_name = os.path.join(self._wsDir, ws_name + '.nxs')
-            if overwrite or os.path.exists(md_file_name):
+            if overwrite or not os.path.exists(md_file_name):
                 mantidsimple.SaveMD(InputWorkspace=ws_name, Filename=md_file_name)
 
         with open(self._projectPath, 'w') as pickle_file:
diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py
index 2cc1b0dc377c77a6da691730385343c9de0c2849..f3c4afd44e3514186432b1160048e7e785205d97 100644
--- a/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py
+++ b/scripts/HFIR_4Circle_Reduction/reduce4circleControl.py
@@ -56,6 +56,16 @@ class CWSCDReductionControl(object):
         # Some set up
         self._expNumber = None
 
+        # instrument default constants
+        self._defaultDetectorSampleDistance = None
+        # geometry of pixel
+        self._defaultPixelSizeX = None
+        self._defaultPixelSizeY = None
+        # user-defined wave length
+        self._userWavelengthDict = dict()
+        # default peak center
+        self._defaultDetectorCenter = None
+
         # Container for MDEventWorkspace for each Pt.
         self._myMDWsList = list()
         # Container for loaded workspaces
@@ -92,6 +102,8 @@ class CWSCDReductionControl(object):
 
         # A dictionary to manage all loaded and processed MDEventWorkspaces
         # self._expDataDict = {}
+        self._detSampleDistanceDict = dict()
+        self._detCenterDict = dict()
 
         # register startup
         mantid.UsageService.registerFeatureUsage("Interface","4-Circle Reduction",False)
@@ -182,57 +194,9 @@ class CWSCDReductionControl(object):
         sin_theta = q * wavelength/(4*math.pi)
         theta = math.asin(sin_theta)
         corrected_intensity = peak_intensity * math.sin(2*theta) * step_omega
-        print '[DB] Lorentz correction: I * sin(2*theta) * delta(omega) = %.5f * sin(2*%.5f) * %.5f =' \
-              ' %.5f; q = %.5f.' % (peak_intensity, theta*180/math.pi, step_omega, corrected_intensity, q)
 
         return corrected_intensity
 
-    # def calculate_peak_center(self, exp_number, scan_number, pt_numbers=None):
-    #     """
-    #     Calculate center of peak by weighting the peak centers of multiple Pt (slice from 3D peak)
-    #     :param exp_number:
-    #     :param scan_number:
-    #     :param pt_numbers:
-    #     :return: 2-tuple: boolean, peak center (3-tuple of float)
-    #     """
-    #     # Check & set pt. numbers
-    #     assert isinstance(exp_number, int), 'Experiment number %s must be an integer but not %s.' \
-    #                                         '' % (str(exp_number), str(type(exp_number)))
-    #     assert isinstance(scan_number, int), 'Scan number %s must be an integer but not %s.' \
-    #                                          '' % (str(scan_number), str(type(scan_number)))
-    #     if pt_numbers is None:
-    #         status, pt_number_list = self.get_pt_numbers(exp_number, scan_number)
-    #         assert status
-    #     else:
-    #         pt_number_list = pt_numbers
-    #     assert isinstance(pt_number_list, list) and len(pt_number_list) > 0
-    #
-    #     # Check whether the MDEventWorkspace used to find peaks exists
-    #     if self.has_merged_data(exp_number, scan_number, pt_number_list):
-    #         pass
-    #     else:
-    #         return False, 'Exp %d Scan %d: data must be merged already.' % (exp_number, scan_number)
-    #
-    #     # Find peak in Q-space
-    #     merged_ws_name = get_merged_md_name(self._instrumentName, exp_number, scan_number, pt_number_list)
-    #     peak_ws_name = get_peak_ws_name(exp_number, scan_number, pt_number_list)
-    #     mantidsimple.FindPeaksMD(InputWorkspace=merged_ws_name,
-    #                              MaxPeaks=10,
-    #                              PeakDistanceThreshold=5.,
-    #                              DensityThresholdFactor=0.1,
-    #                              OutputWorkspace=peak_ws_name)
-    #     assert AnalysisDataService.doesExist(peak_ws_name), 'Output PeaksWorkspace %s cannot be found.' \
-    #                                                         '' % peak_ws_name
-    #
-    #     # calculate the peaks with weight
-    #     process_record = PeakProcessRecord(exp_number, scan_number, peak_ws_name)
-    #     process_record.calculate_peak_center()
-    #     peak_center = process_record.get_peak_centre()
-    #     # set the merged peak information to data structure
-    #     self._myPeakInfoDict[(exp_number, scan_number)] = process_record
-    #
-    #     return True, peak_center
-
     def find_peak(self, exp_number, scan_number, pt_number_list=None):
         """ Find 1 peak in sample Q space for UB matrix
         :param exp_number:
@@ -501,7 +465,11 @@ class CWSCDReductionControl(object):
         if pt_number is None:
             # no pt number, then check SPICE file
             spice_file_name = get_spice_file_name(self._instrumentName, exp_number, scan_number)
-            file_name = os.path.join(self._dataDir, spice_file_name)
+            try:
+                file_name = os.path.join(self._dataDir, spice_file_name)
+            except AttributeError:
+                raise AttributeError('Unable to create SPICE file name from directory %s and file name %s.'
+                                     '' % (self._dataDir, spice_file_name))
         else:
             # pt number given, then check
             xml_file_name = get_det_xml_file_name(self._instrumentName, exp_number, scan_number,
@@ -548,14 +516,18 @@ class CWSCDReductionControl(object):
 
         return self._myUBMatrixDict[exp_number]
 
-    @staticmethod
-    def get_wave_length(exp_number, scan_number_list):
+    def get_wave_length(self, exp_number, scan_number_list):
         """
         Get the wavelength.
         Exception: RuntimeError if there are more than 1 wavelength found with all given scan numbers
+        :param exp_number:
         :param scan_number_list:
         :return:
         """
+        # check whether there is use wave length
+        if exp_number in self._userWavelengthDict:
+            return self._userWavelengthDict[exp_number]
+
         # get the SPICE workspace
         wave_length_set = set()
 
@@ -656,7 +628,6 @@ class CWSCDReductionControl(object):
 
         # get ub matrix
         ub_matrix = self.get_ub_matrix(exp_number)
-        print '[DB...BAT] UB matrix is of type ', type(ub_matrix)
 
         for scan_number in scan_number_list:
             peak_dict = dict()
@@ -782,7 +753,7 @@ class CWSCDReductionControl(object):
         array2d = numpy.ndarray(shape=(DET_X_SIZE, DET_Y_SIZE), dtype='float')
         for i in xrange(DET_X_SIZE):
             for j in xrange(DET_Y_SIZE):
-                array2d[i][j] = raw_ws.readY(i * DET_X_SIZE + j)[0]
+                array2d[i][j] = raw_ws.readY(j * DET_X_SIZE + i)[0]
 
         # Flip the 2D array to look detector from sample
         array2d = numpy.flipud(array2d)
@@ -1305,7 +1276,7 @@ class CWSCDReductionControl(object):
             final_peak_center[i] = sum_peak_center[i] * (1./sum_bin_counts)
         #final_peak_center = sum_peak_center * (1./sum_bin_counts)
 
-        print 'Avg peak center = ', final_peak_center, 'Total counts = ', sum_bin_counts
+        print '[INFO] Avg peak center = ', final_peak_center, 'Total counts = ', sum_bin_counts
 
         # Integrate peaks
         total_intensity = 0.
@@ -1434,7 +1405,6 @@ class CWSCDReductionControl(object):
         # Default for exp_no
         if exp_no is None:
             exp_no = self._expNumber
-        print '[DB...BAD] Load Spice Scan File Exp Number = %d, Stored Exp. Number = %d' % (exp_no, self._expNumber)
 
         # Check whether the workspace has been loaded
         assert isinstance(exp_no, int)
@@ -1675,6 +1645,9 @@ class CWSCDReductionControl(object):
             # - construct a configuration with 1 scan and multiple Pts.
             scan_info_table_name = get_merge_pt_info_ws_name(exp_no, scan_no)
             try:
+                # collect HB3A exp info only need corrected detector position to build virtual instrument.
+                # so it is not necessary to specify the detector center now as virtual instrument
+                # is abandoned due to speed issue.
                 mantidsimple.CollectHB3AExperimentInfo(ExperimentNumber=exp_no,
                                                        ScanList='%d' % scan_no,
                                                        PtLists=pt_list_str,
@@ -1692,10 +1665,37 @@ class CWSCDReductionControl(object):
 
             # create MD workspace in Q-sample
             try:
-                mantidsimple.ConvertCWSDExpToMomentum(InputWorkspace=scan_info_table_name,
-                                                      CreateVirtualInstrument=False,
-                                                      OutputWorkspace=out_q_name,
-                                                      Directory=self._dataDir)
+                # set up the basic algorithm parameters
+                alg_args = dict()
+                alg_args['InputWorkspace'] = scan_info_table_name
+                alg_args['CreateVirtualInstrument'] = False
+                alg_args['OutputWorkspace'] = out_q_name
+                alg_args['Directory'] = self._dataDir
+
+                # Add Detector Center and Detector Distance!!!  - Trace up how to calculate shifts!
+                # calculate the sample-detector distance shift if it is defined
+                if exp_no in self._detSampleDistanceDict:
+                    alg_args['DetectorSampleDistanceShift'] = self._detSampleDistanceDict[exp_no] - \
+                                                              self._defaultDetectorSampleDistance
+                # calculate the shift of detector center
+                if exp_no in self._detCenterDict:
+                    user_center_row, user_center_col = self._detCenterDict[exp_no]
+                    delta_row = user_center_row - self._defaultDetectorCenter[0]
+                    delta_col = user_center_col - self._defaultDetectorCenter[1]
+                    # use LoadSpiceXML2DDet's unit test as a template
+                    shift_x = float(delta_col) * self._defaultPixelSizeX
+                    shift_y = float(delta_row) * self._defaultPixelSizeY * -1.
+                    # set to argument
+                    alg_args['DetectorCenterXShift'] = shift_x
+                    alg_args['DetectorCenterYShift'] = shift_y
+
+                # set up the user-defined wave length
+                if exp_no in self._userWavelengthDict:
+                    alg_args['UserDefinedWavelength'] = self._userWavelengthDict[exp_no]
+
+                # call:
+                mantidsimple.ConvertCWSDExpToMomentum(**alg_args)
+
                 self._myMDWsList.append(out_q_name)
             except RuntimeError as e:
                 err_msg += 'Unable to convert scan %d data to Q-sample MDEvents due to %s' % (scan_no, str(e))
@@ -1777,6 +1777,74 @@ class CWSCDReductionControl(object):
 
         return
 
+    def set_detector_center(self, exp_number, center_row, center_col, default=False):
+        """
+        Set detector center
+        :param exp_number:
+        :param center_row:
+        :param center_col:
+        :param default:
+        :return:
+        """
+        # check
+        assert isinstance(exp_number, int) and exp_number > 0, 'Experiment number must be integer'
+        assert center_row is None or (isinstance(center_row, int) and center_row >= 0), \
+            'Center row number must either None or non-negative integer.'
+        assert center_col is None or (isinstance(center_col, int) and center_col >= 0), \
+            'Center column number must be either Noe or non-negative integer.'
+
+        if default:
+            self._defaultDetectorCenter = (center_row, center_col)
+        else:
+            self._detCenterDict[exp_number] = (center_row, center_col)
+
+        return
+
+    def set_detector_sample_distance(self, exp_number, sample_det_distance):
+        """
+        set instrument's detector - sample distance
+        :param exp_number:
+        :param sample_det_distance:
+        :return:
+        """
+        # check
+        assert isinstance(exp_number, int) and exp_number > 0, 'Experiment number must be integer'
+        assert isinstance(sample_det_distance, float) and sample_det_distance > 0, \
+            'Sample - detector distance must be a positive float.'
+
+        # set
+        self._detSampleDistanceDict[exp_number] = sample_det_distance
+
+        return
+
+    def set_default_detector_sample_distance(self, default_det_sample_distance):
+        """
+        set default detector-sample distance
+        :param default_det_sample_distance:
+        :return:
+        """
+        assert isinstance(default_det_sample_distance, float) and default_det_sample_distance > 0,\
+            'Wrong %s' % str(default_det_sample_distance)
+
+        self._defaultDetectorSampleDistance = default_det_sample_distance
+
+        return
+
+    def set_default_pixel_size(self, pixel_x_size, pixel_y_size):
+        """
+        set default pixel size
+        :param pixel_x_size:
+        :param pixel_y_size:
+        :return:
+        """
+        assert isinstance(pixel_x_size, float) and pixel_x_size > 0, 'Pixel size-X %s is bad!' % str(pixel_x_size)
+        assert isinstance(pixel_y_size, float) and pixel_y_size > 0, 'Pixel size-Y %s is bad!' % str(pixel_y_size)
+
+        self._defaultPixelSizeX = pixel_x_size
+        self._defaultPixelSizeY = pixel_y_size
+
+        return
+
     def set_server_url(self, server_url, check_link=True):
         """
         Set URL for server to download the data
@@ -1847,8 +1915,8 @@ class CWSCDReductionControl(object):
             except OSError as os_err:
                 return False, str(os_err)
 
-        # Check whether the target is writable
-        if os.access(local_dir, os.W_OK) is False:
+        # Check whether the target is writable: if and only if the data directory is not from data server
+        if not local_dir.startswith('/HFIR/HB3A/') and os.access(local_dir, os.W_OK) is False:
             return False, 'Specified local data directory %s is not writable.' % local_dir
 
         # Successful
@@ -1874,6 +1942,23 @@ class CWSCDReductionControl(object):
         # Set up
         self._myUBMatrixDict[exp_number] = ub_matrix
 
+        return
+
+    def set_user_wave_length(self, exp_number, wave_length):
+        """
+        set the user wave length for future operation
+        :param exp_number:
+        :param wave_length:
+        :return:
+        """
+        assert isinstance(exp_number, int)
+        assert isinstance(wave_length, float) and wave_length > 0, 'Wave length %s must be a positive float but ' \
+                                                                   'not %s.' % (str(wave_length), type(wave_length))
+
+        self._userWavelengthDict[exp_number] = wave_length
+
+        return
+
     def set_working_directory(self, work_dir):
         """
         Set up the directory for working result
@@ -2390,9 +2475,8 @@ class CWSCDReductionControl(object):
                 try:
                     mantidsimple.DownloadFile(Address=spice_file_url, Filename=spice_file_name)
                 except RuntimeError as download_error:
-                    print 'Unable to download scan %d from %s due to %s.' % (scan_number,
-                                                                             spice_file_url,
-                                                                             str(download_error))
+                    print '[ERROR] Unable to download scan %d from %s due to %s.' % (scan_number,spice_file_url,
+                                                                                     str(download_error))
                     break
             else:
                 spice_file_name = get_spice_file_name(self._instrumentName, exp_number, scan_number)
@@ -2460,7 +2544,6 @@ class CWSCDReductionControl(object):
                                       q_range, max_tsample])
 
             except RuntimeError as e:
-                print e
                 return False, None, str(e)
             except ValueError as e:
                 # Unable to import a SPICE file without necessary information
@@ -2468,7 +2551,7 @@ class CWSCDReductionControl(object):
         # END-FOR (scan_number)
 
         if error_message != '':
-            print 'Error!\n%s' % error_message
+            print '[Error]\n%s' % error_message
 
         self._scanSummaryList = scan_sum_list
 
diff --git a/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py
index 57f3b54c0b0b7e077f8053ecdfec712b9953590d..d7769b0f6341425c8216137d0b25f03bc80ddf83 100644
--- a/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py
+++ b/scripts/HFIR_4Circle_Reduction/reduce4circleGUI.py
@@ -97,6 +97,12 @@ class MainWindow(QtGui.QMainWindow):
                      self.do_download_spice_data)
         self.connect(self.ui.comboBox_mode, QtCore.SIGNAL('currentIndexChanged(int)'),
                      self.do_change_data_access_mode)
+        self.connect(self.ui.pushButton_applyCalibratedSampleDistance, QtCore.SIGNAL('clicked()'),
+                     self.do_set_user_detector_distance)
+        self.connect(self.ui.pushButton_applyUserDetCenter, QtCore.SIGNAL('clicked()'),
+                     self.do_set_user_detector_center)
+        self.connect(self.ui.pushButton_applyUserWavelength, QtCore.SIGNAL('clicked()'),
+                     self.do_set_user_wave_length)
 
         # Tab 'View Raw Data'
         self.connect(self.ui.pushButton_setScanInfo, QtCore.SIGNAL('clicked()'),
@@ -278,16 +284,6 @@ class MainWindow(QtGui.QMainWindow):
         self.connect(self.ui.pushButton_loadLastNthProject, QtCore.SIGNAL('clicked()'),
                      self.do_load_nth_project)
 
-        # TODO/NOW/ISSUE - Implement
-        """
-        lineEdit_userDetSampleDistance, pushButton_applyCalibratedSampleDistance,
-        add more to --> lineEdit_infoDetSampleDistance
-        pushButton_applyUserWavelength: add more to --> lineEdit_infoWavelength
-
-        lineEdit_detCenterPixHorizontal, lineEdit_detCenterPixVertical,
-        pushButton_applyUserDetCenter, lineEdit_infoDetCenter
-        """
-
         # Validator ... (NEXT)
 
         # Declaration of class variable
@@ -469,8 +465,14 @@ class MainWindow(QtGui.QMainWindow):
         project_file_name = str(QtGui.QFileDialog.getSaveFileName(self, 'Specify Project File', os.getcwd()))
         # NEXT ISSUE - consider to allow incremental project saving technique
         if os.path.exists(project_file_name):
-            self.pop_one_button_dialog('Project file %s does exist. Choose another name.' % project_file_name)
-            return
+            yes = gutil.show_message(self, 'Project file %s does exist. This is supposed to be '
+                                           'an incremental save.' % project_file_name)
+            if yes:
+                print '[INFO] Save project in incremental way.'
+            else:
+                print '[INFO] Saving activity is cancelled.'
+        else:
+            print '[INFO] Saving current project to %s.' % project_file_name
 
         # gather some useful information
         ui_dict = dict()
@@ -510,22 +512,6 @@ class MainWindow(QtGui.QMainWindow):
 
         self.load_project(project_file_name)
 
-        # # load project
-        # ui_dict = self._myControl.load_project(project_file_name)
-        #
-        # # set the UI parameters to GUI
-        # try:
-        #     self.ui.lineEdit_localSpiceDir.setText(ui_dict['local spice dir'])
-        #     self.ui.lineEdit_workDir.setText(ui_dict['work dir'])
-        #     self.ui.lineEdit_surveyStartPt.setText(ui_dict['survey start'])
-        #     self.ui.lineEdit_surveyEndPt.setText(ui_dict['survey stop'])
-        #
-        #     # now try to call some actions
-        #     self.do_apply_setup()
-        #     self.do_set_experiment()
-        # except KeyError:
-        #     print '[Error] Some field cannot be found.'
-
         return
 
     def load_project(self, project_file_name):
@@ -588,9 +574,10 @@ class MainWindow(QtGui.QMainWindow):
         :param QCloseEvent:
         :return:
         """
-        print '[QCloseEvent=]', str(QCloseEvent)
         self.menu_quit()
 
+        return
+
     def do_accept_ub(self):
         """ Accept the calculated UB matrix and thus put to controller
         """
@@ -735,7 +722,9 @@ class MainWindow(QtGui.QMainWindow):
         data_server = str(self.ui.lineEdit_url.text()).strip()
 
         # set to my controller
-        self._myControl.set_local_data_dir(local_data_dir)
+        status, err_msg = self._myControl.set_local_data_dir(local_data_dir)
+        if not status:
+            raise RuntimeError(err_msg)
         self._myControl.set_working_directory(working_dir)
         self._myControl.set_server_url(data_server, check_link=False)
 
@@ -982,7 +971,6 @@ class MainWindow(QtGui.QMainWindow):
         convert merged workspace in Q-sample frame to HKL frame
         :return:
         """
-        # TODO/NOW/ - TEST: Convert to HKL
         # get experiment number
         exp_number = int(str(self.ui.lineEdit_exp.text()))
 
@@ -1414,8 +1402,6 @@ class MainWindow(QtGui.QMainWindow):
         if len(row_number_list) == 0:
             self.pop_one_button_dialog('No scan is selected for scan')
             return
-        else:
-            print '[DB...BAT] IntegratePeaks: selected rows: ', row_number_list
 
         # get experiment number
         status, ret_obj = gutil.parse_integers_editors(self.ui.lineEdit_exp, allow_blank=False)
@@ -1877,8 +1863,6 @@ class MainWindow(QtGui.QMainWindow):
         Merge several scans to a single MDWorkspace and give suggestion for re-binning
         :return:
         """
-        # TODO/NOW/ISSUE - Test this!
-
         # find the selected scans
         selected_rows = self.ui.tableWidget_mergeScans.get_selected_rows(True)
         if len(selected_rows) < 2:
@@ -1969,7 +1953,6 @@ class MainWindow(QtGui.QMainWindow):
             else:
                 merge_status = 'Failed. Reason: %s' % ret_tup
                 merged_name = 'x'
-                print merge_status
 
             # update table
             self.ui.tableWidget_mergeScans.set_status(row_number, merge_status)
@@ -2069,9 +2052,8 @@ class MainWindow(QtGui.QMainWindow):
 
         dlg = refineubfftsetup.RefineUBFFTSetupDialog(self)
         if dlg.exec_():
-            min_d, max_d, tolerance = dlg.get_values()
-            print '[DB...BAT]', min_d, max_d, tolerance
             # Do stuff with values
+            min_d, max_d, tolerance = dlg.get_values()
         else:
             # case for cancel
             return
@@ -2377,26 +2359,57 @@ class MainWindow(QtGui.QMainWindow):
         :return:
         """
         status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp])
-        if status is True:
+        if status:
+            # new experiment number
             exp_number = ret_obj[0]
+            # current experiment to be replaced: warning
             curr_exp_number = self._myControl.get_experiment()
             if curr_exp_number is not None and exp_number != curr_exp_number:
                 self.pop_one_button_dialog('Changing experiment to %d.  Clean previous experiment %d\'s result'
                                            ' in Mantid manually.' % (exp_number, curr_exp_number))
+            # set the new experiment number
             self._myControl.set_exp_number(exp_number)
             self.ui.lineEdit_exp.setStyleSheet('color: black')
-
             self.setWindowTitle('%s: Experiment %d' % (self._baseTitle, exp_number))
 
-            # TODO/NOW/ISSUE - if the current data directory is empty or as /HFIR/HB3A/, reset data directory
+            # try to set the default
+            default_data_dir = '/HFIR/HB3A/exp%d/Datafiles' % exp_number
+            if os.path.exists(default_data_dir):
+                self.ui.lineEdit_localSpiceDir.setText(default_data_dir)
 
         else:
             err_msg = ret_obj
             self.pop_one_button_dialog('Unable to set experiment as %s' % err_msg)
             self.ui.lineEdit_exp.setStyleSheet('color: red')
+            return
 
         self.ui.tabWidget.setCurrentIndex(0)
 
+        # set the instrument geometry constants
+        status, ret_obj = gutil.parse_float_editors([self.ui.lineEdit_defaultSampleDetDistance,
+                                                     self.ui.lineEdit_pixelSizeX,
+                                                     self.ui.lineEdit_pixelSizeY],
+                                                    allow_blank=False)
+        if status:
+            default_det_sample_distance, pixel_x_size, pixel_y_size = ret_obj
+            self._myControl.set_default_detector_sample_distance(default_det_sample_distance)
+            self._myControl.set_default_pixel_size(pixel_x_size, pixel_y_size)
+        else:
+            self.pop_one_button_dialog('[ERROR] Unable to parse default instrument geometry constants '
+                                       'due to %s.' % str(ret_obj))
+            return
+
+        # set the detector center
+        det_center_str = str(self.ui.lineEdit_defaultDetCenter.text())
+        try:
+            terms = det_center_str.split(',')
+            center_row = int(terms[0])
+            center_col = int(terms[1])
+            self._myControl.set_detector_center(exp_number, center_row, center_col, default=True)
+        except (IndexError, ValueError) as error:
+            self.pop_one_button_dialog('[ERROR] Unable to parse default detector center %s due to %s.'
+                                       '' % (det_center_str, str(error)))
+
         return
 
     def do_set_ub_tab_hkl_to_integers(self):
@@ -2463,7 +2476,7 @@ class MainWindow(QtGui.QMainWindow):
                 try:
                     ub_matrix = self._myControl.get_ub_matrix(exp_number)
                 except KeyError as key_err:
-                    print 'Error to get UB matrix: %s' % str(key_err)
+                    print '[Error] unable to get UB matrix: %s' % str(key_err)
                     self.pop_one_button_dialog('Unable to get UB matrix.\nCheck whether UB matrix is set.')
                     return
                 index_status, ret_tup = self._myControl.index_peak(ub_matrix, scan_i, allow_magnetic=True)
@@ -2494,19 +2507,20 @@ class MainWindow(QtGui.QMainWindow):
     def do_setup_dir_default(self):
         """
         Set up default directory for storing data and working
+        If directory /HFIR/HB3A exists, it means that the user can access HFIR archive server
         :return:
         """
         home_dir = os.path.expanduser('~')
 
-        # TODO/NOW/ISSUE - make this one work for server-based
-        # example: os.path.exists('/HFIR/HB3A/exp322') won't take long time to find out the server is off.
-
         # Data cache directory
-        data_cache_dir = os.path.join(home_dir, 'Temp/HB3ATest')
-        self.ui.lineEdit_localSpiceDir.setText(data_cache_dir)
-        self.ui.lineEdit_localSrcDir.setText(data_cache_dir)
+        project_cache_dir = os.path.join(home_dir, 'Temp/HB3ATest')
+        if os.path.exists('/HFIR/HB3A/'):
+            self.ui.lineEdit_localSrcDir.setText('/HFIR/HB3A/')
+        else:
+            self.ui.lineEdit_localSpiceDir.setText(project_cache_dir)
 
-        work_dir = os.path.join(data_cache_dir, 'Workspace')
+        # working directory
+        work_dir = os.path.join(project_cache_dir, 'Workspace')
         self.ui.lineEdit_workDir.setText(work_dir)
 
         return
@@ -2546,6 +2560,84 @@ class MainWindow(QtGui.QMainWindow):
 
         return ub_matrix
 
+    def do_set_user_detector_distance(self):
+        """
+        Set up the user-defined detector distance for loading instrument with data
+        :return:
+        """
+        user_det_distance_str = str(self.ui.lineEdit_userDetSampleDistance.text()).strip()
+        if len(user_det_distance_str) == 0:
+            return
+
+        # convert to float
+        try:
+            user_det_distance = float(user_det_distance_str)
+        except ValueError:
+            self.pop_one_button_dialog('User detector-sample distance %s must be a float.' % user_det_distance_str)
+            return
+
+        # check distance value because it cannot be too far
+        default_det_distance = float(str(self.ui.lineEdit_defaultSampleDetDistance.text()))
+        distance_tol = float(str(self.ui.lineEdit_sampleDetDistTol.text()))
+        if abs((user_det_distance - default_det_distance) / default_det_distance) > distance_tol:
+            self.pop_one_button_dialog('User specified sample-detector distance is not reasonable.')
+            return
+
+        # set to controller
+        exp_number = int(str(self.ui.lineEdit_exp.text()))
+        self._myControl.set_detector_sample_distance(exp_number, user_det_distance)
+
+        # update the GUI for information
+        self.ui.lineEdit_infoDetSampleDistance.setText('%.5f' % user_det_distance)
+
+        return
+
+    def do_set_user_wave_length(self):
+        """
+
+        :return:
+        """
+        try:
+            exp_number = int(str(self.ui.lineEdit_exp.text()))
+            user_lambda = float(str(self.ui.lineEdit_userWaveLength.text()))
+        except ValueError:
+            self.pop_one_button_dialog('Unable to set user wave length with value %s.'
+                                       '' % str(self.ui.lineEdit_infoWavelength.text()))
+            return
+
+        self._myControl.set_user_wave_length(exp_number, user_lambda)
+
+        # set back to GUI
+        self.ui.lineEdit_infoWavelength.setText('%.5f' % user_lambda)
+
+        return
+
+    def do_set_user_detector_center(self):
+        """
+        set the user-defined detector center
+        :return:
+        """
+        # get information
+        status, ret_obj = gutil.parse_integers_editors([self.ui.lineEdit_exp,
+                                                        self.ui.lineEdit_detCenterPixHorizontal,
+                                                        self.ui.lineEdit_detCenterPixVertical],
+                                                       allow_blank=True)
+
+        if not status:
+            self.pop_one_button_dialog(str(ret_obj))
+            return
+
+        assert isinstance(ret_obj, list) and len(ret_obj) == 3, 'Error!'
+        exp_number, user_center_row, user_center_col = ret_obj
+        assert isinstance(exp_number, int), 'Experiment number must be set up.'
+
+        self._myControl.set_detector_center(exp_number, user_center_row, user_center_col)
+
+        # apply to the GUI
+        self.ui.lineEdit_infoDetCenter.setText('%d, %d' % (user_center_row, user_center_col))
+
+        return
+
     def do_show_spice_file(self):
         """
         Show SPICE file in a window
@@ -2717,8 +2809,6 @@ class MainWindow(QtGui.QMainWindow):
         else:
             raise RuntimeError('None radio button is selected for UB')
 
-        print '[DB...BAT] UB to set: ', ub_matrix
-
         # set to in-use UB matrix and control
         self.ui.tableWidget_ubInUse.set_from_matrix(ub_matrix)
 
@@ -2807,17 +2897,11 @@ class MainWindow(QtGui.QMainWindow):
         assert len(ret_obj) == 5
         md_file_name, weight_peak_centers, weight_peak_intensities, avg_peak_centre, avg_peak_intensity = ret_obj
 
-        print 'Write file to %s' % md_file_name
-        for i_peak in xrange(len(weight_peak_centers)):
-            peak_i = weight_peak_centers[i_peak]
-            print '%f, %f, %f' % (peak_i[0], peak_i[1], peak_i[2])
-        print
-        print avg_peak_centre
-
         # Plot
         if self._my3DWindow is None:
             self._my3DWindow = plot3dwindow.Plot3DWindow(self)
 
+        print '[INFO] Write file to %s' % md_file_name
         self._my3DWindow.add_plot_by_file(md_file_name)
         self._my3DWindow.add_plot_by_array(weight_peak_centers, weight_peak_intensities)
         self._my3DWindow.add_plot_by_array(avg_peak_centre, avg_peak_intensity)
@@ -3405,8 +3489,6 @@ class MainWindow(QtGui.QMainWindow):
 
             # gather values for updating
             intensity = sig_value
-            print '[DB...BAT] UpdatePeakIntegrationValue: Row %d: peak center %s of type %s.' \
-                  '' % (row_number, str(peak_centre), type(peak_centre))
 
             # check intensity value
             is_error = False
@@ -3494,8 +3576,6 @@ class MainWindow(QtGui.QMainWindow):
         except RuntimeError as run_err:
             self.pop_one_button_dialog(str(run_err))
             return
-        else:
-            print '[DB...BAT] UpdateMergeInformation: Row = ', row_number
 
         # set intensity, state to table
         if mode == 0:
diff --git a/scripts/Imaging/IMAT/__init__.py b/scripts/Imaging/IMAT/__init__.py
index 7fd49397e233ebf3616d56d32aa2fa68f3ec76db..763e55451a6e0fe542b5d75bbbaec0802e4b8cd1 100644
--- a/scripts/Imaging/IMAT/__init__.py
+++ b/scripts/Imaging/IMAT/__init__.py
@@ -1,3 +1,4 @@
+from __future__ import (absolute_import, division, print_function)
 # Copyright &copy; 2015 ISIS Rutherford Appleton Laboratory, NScD
 # Oak Ridge National Laboratory & European Spallation Source
 #
diff --git a/scripts/Imaging/IMAT/tomo_reconstruct.py b/scripts/Imaging/IMAT/tomo_reconstruct.py
index 875d4e66bc2d9f156854df4bb0a9fba82ea7ffbd..b75233db360511ffd909038f388f4e6f40224b03 100644
--- a/scripts/Imaging/IMAT/tomo_reconstruct.py
+++ b/scripts/Imaging/IMAT/tomo_reconstruct.py
@@ -1,3 +1,4 @@
+from __future__ import (absolute_import, division, print_function)
 # Copyright &copy; 2014,2015 ISIS Rutherford Appleton Laboratory, NScD
 # Oak Ridge National Laboratory & European Spallation Source
 #
@@ -267,6 +268,7 @@ def grab_postproc_options(args):
 def main_tomo_rec():
     # several dependencies (numpy, scipy) are too out-of-date in standard Python 2.6
     # distributions, as found for example on rhel6
+
     vers = sys.version_info
     if vers < (2,7,0):
         raise RuntimeError("Not running this test as it requires Python >= 2.7. Version found: {0}".
@@ -274,7 +276,7 @@ def main_tomo_rec():
 
     import inspect
 
-    import IMAT.tomorec.io as tomoio
+    import tomorec.io as tomoio
 
     arg_parser = setup_cmd_options()
     args = arg_parser.parse_args()
diff --git a/scripts/Imaging/IMAT/tomorec/__init__.py b/scripts/Imaging/IMAT/tomorec/__init__.py
index a21419b4aa431c480cd4c282be31431af89824cb..a96358ca9182fababaa97b11b15930b8149590ce 100644
--- a/scripts/Imaging/IMAT/tomorec/__init__.py
+++ b/scripts/Imaging/IMAT/tomorec/__init__.py
@@ -44,7 +44,6 @@ except ImportError as exc:
     raise ImportError(IMPORT_ERR_MSG.format("'tool_imports' (for third party "
                                             "tools such as Tomopy and Astra)",
                                             exc))
-
 try:
     from . import reconstruction_command
 except ImportError as exc:
diff --git a/scripts/Imaging/IMAT/tomorec/io.py b/scripts/Imaging/IMAT/tomorec/io.py
index 716950383951a9e089a9bf245422e4507ba834dc..1af5b750ab68badeaa5706142ba56a55dcef4886 100644
--- a/scripts/Imaging/IMAT/tomorec/io.py
+++ b/scripts/Imaging/IMAT/tomorec/io.py
@@ -1,3 +1,4 @@
+from __future__ import (absolute_import, division, print_function)
 # Copyright &copy; 2014-2015 ISIS Rutherford Appleton Laboratory, NScD
 # Oak Ridge National Laboratory & European Spallation Source
 #
@@ -115,7 +116,7 @@ def write_image(img_data, min_pix, max_pix, filename, img_format=None, dtype=Non
 
         too_verbose = False
         if too_verbose:
-            print "pix min: {0}, max: {1}, scale_factor: {2}".format(min_pix, max_pix, scale_factor)
+            print("pix min: {0}, max: {1}, scale_factor: {2}".format(min_pix, max_pix, scale_factor))
         img_data = scale_factor * (old_img_data - min_pix)
         img_data = img_data.astype(dtype=dtype)
 
@@ -186,8 +187,8 @@ def avg_image_files(path, base_path, file_extension=None, agg_method='average'):
         try:
             hdu = pyfits.open(ifile)
         except IOError as exc:
-            print "Got I/O exception trying to open and load {0}: {1}. Ignoring and going on.".format(
-                ifile, str(exc))
+            print("Got I/O exception trying to open and load {0}: {1}. Ignoring and going on.".format(
+                ifile, str(exc)))
             continue
 
         accum = _agg_img(accum, hdu[0].data, agg_method=agg_method)
@@ -370,7 +371,7 @@ def read_stack_of_images(sample_path, flat_field_path=None, dark_field_path=None
     sample_path = os.path.expanduser(sample_path)
 
     if verbose:
-        print "Loading stack of images from {0}".format(sample_path)
+        print("Loading stack of images from {0}".format(sample_path))
 
     if not file_prefix:
         file_prefix = ''
@@ -383,7 +384,7 @@ def read_stack_of_images(sample_path, flat_field_path=None, dark_field_path=None
     files_match.sort(key=_alphanum_key_split)
 
     if verbose:
-        print "Found {0} image files in {1}".format(len(files_match), sample_path)
+        print("Found {0} image files in {1}".format(len(files_match), sample_path))
 
     # It is assumed that all images have the same size and properties as the first.
     try:
@@ -460,7 +461,7 @@ def save_recon_netcdf(recon_data, output_dir, filename='tomo_recon_vol.nc'):
     try:
         from scipy.io import netcdf_file
     except ImportError as exc:
-        print " WARNING: could not save NetCDF file. Import error: {0}".format(exc)
+        print(" WARNING: could not save NetCDF file. Import error: {0}".format(exc))
 
     xsize = recon_data.shape[0]
     ysize = recon_data.shape[1]
@@ -471,11 +472,11 @@ def save_recon_netcdf(recon_data, output_dir, filename='tomo_recon_vol.nc'):
     ncfile.createDimension('x', xsize)
     ncfile.createDimension('y', ysize)
     ncfile.createDimension('z', zsize)
-    print " Creating netCDF volume data variable"
+    print(" Creating netCDF volume data variable")
     dtype = 'int16'
     data = ncfile.createVariable('data', np.dtype(dtype).char, ('x','y','z'))
-    print " Data shape: {0}".format(data.shape)
-    print " Loading/assigning data..."
+    print(" Data shape: {0}".format(data.shape))
+    print(" Loading/assigning data...")
 
     # handle differences in pixel type
     save_data = recon_data
@@ -489,7 +490,7 @@ def save_recon_netcdf(recon_data, output_dir, filename='tomo_recon_vol.nc'):
         save_data = save_data.astype(dtype=dtype)
 
     data[:, :, :] = save_data[0:xsize, 0:ysize, 0:zsize]
-    print " Closing netCDF file: {0}".format(nc_path)
+    print(" Closing netCDF file: {0}".format(nc_path))
     ncfile.close()
 
 
diff --git a/scripts/Imaging/IMAT/tomorec/reconstruction_command.py b/scripts/Imaging/IMAT/tomorec/reconstruction_command.py
index 7fbe76a3036e9bd46e5673ffe5e4e20e0473547d..c03ff568de3249b1f3c8f051b841be71468dc029 100644
--- a/scripts/Imaging/IMAT/tomorec/reconstruction_command.py
+++ b/scripts/Imaging/IMAT/tomorec/reconstruction_command.py
@@ -1,3 +1,4 @@
+from __future__ import (absolute_import, division, print_function)
 # Copyright &copy; 2014,2015 ISIS Rutherford Appleton Laboratory, NScD
 # Oak Ridge National Laboratory & European Spallation Source
 #
@@ -82,7 +83,7 @@ class ReconstructionCommand(object):
 
         data, white, dark = self.read_in_stack(cfg.preproc_cfg.input_dir, cfg.preproc_cfg.in_img_format,
                                                cfg.preproc_cfg.input_dir_flat, cfg.preproc_cfg.input_dir_dark)
-        print "Shape of raw data: {0}, dtype: {1}".format(data.shape, data.dtype)
+        print("Shape of raw data: {0}, dtype: {1}".format(data.shape, data.dtype))
 
         # These imports will raise appropriate exceptions in case of error
         import tomorec.tool_imports as tti
@@ -92,7 +93,7 @@ class ReconstructionCommand(object):
             tti.import_tomo_tool('tomopy')
 
         preproc_data = self.apply_all_preproc(data, cfg.preproc_cfg, white, dark)
-        print "Shape of pre-processed data: {0}, dtype: {1}".format(preproc_data.shape, data.dtype)
+        print("Shape of pre-processed data: {0}, dtype: {1}".format(preproc_data.shape, data.dtype))
 
         # Save pre-proc images
         self.save_preproc_images(cfg.postproc_cfg.output_dir, preproc_data, cfg.preproc_cfg)
@@ -113,7 +114,7 @@ class ReconstructionCommand(object):
         self.gen_readme_summary_end(readme_fullpath, (data, preproc_data, recon_data), tstart,
                                     t_recon_end - t_recon_start)
 
-        print "Finished reconstruction."
+        print("Finished reconstruction.")
 
     def gen_readme_summary_begin(self, filename, cfg, cmd_line):
         """
@@ -246,10 +247,10 @@ class ReconstructionCommand(object):
         """
         self._check_data_stack(data)
 
-        print " * Beginning pre-processing with pixel data type:", data.dtype
+        print(" * Beginning pre-processing with pixel data type:", data.dtype)
         if 'float64' == data.dtype:
             data = data.astype(dtype='float32')
-            print " * Note: pixel data type changed to:", data.dtype
+            print(" * Note: pixel data type changed to:", data.dtype)
 
         data, white, dark = self.rotate_stack(data, cfg, white, dark)
         if self.crop_before_normaliz:
@@ -291,7 +292,7 @@ class ReconstructionCommand(object):
         self._check_data_stack(imgs_angles)
 
         if not preproc_cfg.line_projection:
-            print " * Note: not applying line projection."
+            print(" * Note: not applying line projection.")
             return imgs_angles
 
         imgs_angles = imgs_angles.astype('float32')
@@ -321,22 +322,22 @@ class ReconstructionCommand(object):
             import prep as iprep
             if 'wavelet-fourier' == cfg.stripe_removal_method.lower():
                 time1 = time.time()
-                print " * Removing stripes/ring artifacts using the method '{0}'".format(cfg.stripe_removal_method)
+                print(" * Removing stripes/ring artifacts using the method '{0}'".format(cfg.stripe_removal_method))
                 #preproc_data = tomopy.prep.stripe.remove_stripe_fw(preproc_data)
                 preproc_data = iprep.filters.remove_stripes_ring_artifacts(preproc_data, 'wavelet-fourier')
                 time2 = time.time()
-                print " * Removed stripes/ring artifacts. Time elapsed: {0:.3f}".format(time2 - time1)
+                print(" * Removed stripes/ring artifacts. Time elapsed: {0:.3f}".format(time2 - time1))
             elif 'titarenko' == cfg.stripe_removal_method.lower():
                 time1 = time.time()
-                print " * Removing stripes/ring artifacts, using the method '{0}'".format(cfg.stripe_removal_method)
+                print(" * Removing stripes/ring artifacts, using the method '{0}'".format(cfg.stripe_removal_method))
                 preproc_data = tomopy.prep.stripe.remove_stripe_ti(preproc_data)
                 time2 = time.time()
-                print " * Removed stripes/ring artifacts, Time elapsed: {0:.3f}".format(time2 - time1)
+                print(" * Removed stripes/ring artifacts, Time elapsed: {0:.3f}".format(time2 - time1))
             else:
                 print(" * WARNING: stripe removal method '{0}' is unknown. Not applying it.".
                       format(cfg.stripe_removal_method))
         else:
-            print " * Note: not applying stripe removal."
+            print(" * Note: not applying stripe removal.")
 
         # Experimental options, disabled and not present in the config objects for now
         # These and related algorithms needs more evaluation/benchmarking
@@ -392,7 +393,7 @@ class ReconstructionCommand(object):
             air_sums = np.true_divide(air_sums, np.amax(air_sums))
             too_verbose = True
             if too_verbose:
-                print " Air region sums (relative to maximum): ", air_sums
+                print(" Air region sums (relative to maximum): ", air_sums)
 
             for idx in range(0, data.shape[0]):
                 data[idx, :, :] = np.true_divide(data[idx, :, :], air_sums[idx])
@@ -403,7 +404,7 @@ class ReconstructionCommand(object):
                   format(avg, np.max(air_sums)/avg, np.min(air_sums)/avg))
 
         else:
-            print " * Note: not normalizing by air region"
+            print(" * Note: not normalizing by air region")
 
         return data
 
@@ -429,7 +430,7 @@ class ReconstructionCommand(object):
                 print("Error in crop (region of interest) parameter (expecting a list with four integers. "
                       "Got: {0}. Error details: ".format(cfg.crop_coords), exc)
         else:
-            print " * Note: not applying cropping to region of interest."
+            print(" * Note: not applying cropping to region of interest.")
 
         return data
 
@@ -451,7 +452,7 @@ class ReconstructionCommand(object):
                              "configuration")
 
         if not cfg.normalize_flat_dark:
-            print " * Note: not applying normalization by flat/dark images."
+            print(" * Note: not applying normalization by flat/dark images.")
             return data
 
         if isinstance(norm_flat_img, np.ndarray):
@@ -478,7 +479,7 @@ class ReconstructionCommand(object):
                 data[idx, :, :] = np.true_divide(data[idx, :, :] - norm_dark_img, norm_divide)
             # true_divide produces float64, we assume that precision not needed (definitely not
             # for 16-bit depth output images as we usually have).
-            print " * Finished normalization by flat/dark images with pixel data type: {0}.".format(data.dtype)
+            print(" * Finished normalization by flat/dark images with pixel data type: {0}.".format(data.dtype))
         else:
             print(" * Note: cannot apply normalization by flat/dark images because no valid flat image has been "
                   "provided in the inputs. Flat image given: {0}".format(norm_flat_img))
@@ -502,29 +503,29 @@ class ReconstructionCommand(object):
 
         # Apply cut-off for the normalization?
         if cfg.cut_off_level and cfg.cut_off_level:
-            print "* Applying cut-off with level: {0}".format(cfg.cut_off_level)
+            print("* Applying cut-off with level: {0}".format(cfg.cut_off_level))
             dmin = np.amin(data)
             dmax = np.amax(data)
             rel_cut_off = dmin + cfg.cut_off_level * (dmax - dmin)
             data[data < rel_cut_off] = dmin
-            print " * Finished cut-off stepa, with pixel data type: {0}".format(data.dtype)
+            print(" * Finished cut-off stepa, with pixel data type: {0}".format(data.dtype))
         else:
-            print " * Note: not applying cut-off."
+            print(" * Note: not applying cut-off.")
 
         if cfg.mcp_corrections:
-            print " * MCP corrections not implemented in this version"
+            print(" * MCP corrections not implemented in this version")
 
         if cfg.scale_down:
-            print " * Scale down not implemented in this version"
+            print(" * Scale down not implemented in this version")
 
         if cfg.median_filter_size and cfg.median_filter_size > 1:
             for idx in range(0, data.shape[0]):
                 data[idx] = scipy.ndimage.median_filter(data[idx], cfg.median_filter_size, mode='mirror')
                 #, mode='nearest')
-            print (" * Finished noise filter / median, with pixel data type: {0}, filter size/width: {1}.".
-                   format(data.dtype, cfg.median_filter_size))
+            print(" * Finished noise filter / median, with pixel data type: {0}, filter size/width: {1}.".
+                  format(data.dtype, cfg.median_filter_size))
         else:
-            print " * Note: not applying noise filter /median."
+            print(" * Note: not applying noise filter /median.")
 
         return data
 
@@ -543,7 +544,7 @@ class ReconstructionCommand(object):
             raise ValueError("Cannot rotate images without a valid pre-processing configuration")
 
         if not cfg.rotation or cfg.rotation < 0:
-            print " * Note: not rotating the input images."
+            print(" * Note: not rotating the input images.")
             return data, white, dark
 
         data = self._rotate_imgs(data, cfg)
@@ -552,8 +553,8 @@ class ReconstructionCommand(object):
         if dark:
             dark = self._rotate_imgs(dark, cfg)
 
-        print (" * Finished rotation step ({0} degrees clockwise), with pixel data type: {1}".
-               format(cfg.rotation * 90, data.dtype))
+        print(" * Finished rotation step ({0} degrees clockwise), with pixel data type: {1}".
+              format(cfg.rotation * 90, data.dtype))
 
         return (data, white, dark)
 
@@ -606,21 +607,29 @@ class ReconstructionCommand(object):
             return self.run_reconstruct_3d_astra_simple(proj_data, proj_angles, alg_cfg, preproc_cfg.cor)
 
         for slice_idx in [int(proj_data.shape[0]/2)]: # examples to check: [30, 130, 230, 330, 430]:
-            print " > Finding center with tomopy find_center, slice index: {0}.".format(slice_idx)
+            print(" > Finding center with tomopy find_center, slice index: {0}.".format(slice_idx))
             import tomorec.tool_imports as tti
             try:
                 tomopy = tti.import_tomo_tool('tomopy')
-                print "proj_data: ", proj_data.shape
-                print "proj_angles: ", proj_angles.shape
-                tomopy_cor = tomopy.find_center(tomo=proj_data, theta=proj_angles, ind=slice_idx, emission=False)
+                print("proj_data: ", proj_data.shape)
+                print("proj_angles: ", proj_angles.shape)
+                # Temporary fix to support newer tomopy reconstructions,
+                # this does not guarantee that their output will be correct,
+                # but only patches the removal of the emission keyword and allows the recon to run
+                if(int(tomopy.__version__[0]) < 1):
+                    # for tomopy versions 0.x.x
+                    tomopy_cor = tomopy.find_center(tomo=proj_data, theta=proj_angles, ind=slice_idx, emission=False)
+                else:
+                    # for tomopy versions 1.x.x
+                    tomopy_cor = tomopy.find_center(tomo=proj_data, theta=proj_angles, ind=slice_idx)
                 if not preproc_cfg.cor:
                     preproc_cfg.cor = tomopy_cor
-                print " > Center of rotation found by tomopy.find_center:  {0}".format(tomopy_cor)
+                print(" > Center of rotation found by tomopy.find_center:  {0}".format(tomopy_cor))
             except ImportError as exc:
                 print(" * WARNING: could not import tomopy so could not use the tomopy method to find the center "
                       "of rotation. Details: {0}".format(exc))
 
-        print "Using center of rotation: {0}".format(preproc_cfg.cor)
+        print("Using center of rotation: {0}".format(preproc_cfg.cor))
         start = time.time()
         if 'tomopy' == alg_cfg.tool and 'gridrec' != alg_cfg.algorithm and 'fbp' != alg_cfg.algorithm:
             if not alg_cfg.num_iter:
@@ -640,7 +649,7 @@ class ReconstructionCommand(object):
             rec = tomopy.recon(tomo=proj_data, theta=proj_angles, center=preproc_cfg.cor,
                                algorithm=alg_cfg.algorithm)
         tnow = time.time()
-        print "Reconstructed 3D volume. Time elapsed in reconstruction algorithm: {0:.3f}".format(tnow - start)
+        print("Reconstructed 3D volume. Time elapsed in reconstruction algorithm: {0:.3f}".format(tnow - start))
 
         return rec
 
@@ -708,7 +717,7 @@ class ReconstructionCommand(object):
 
         nSinos = get_max_frames(algorithm=algorithm)
         iterations = alg_cfg.num_iter
-        print " astra recon - doing {0} iterations".format(iterations)
+        print(" astra recon - doing {0} iterations".format(iterations))
 
         # swaps outermost dimensions so it is sinogram layout
         sinogram = proj_data
@@ -796,26 +805,26 @@ class ReconstructionCommand(object):
 
         if cfg.circular_mask:
             recon_data = iprep.filters.circular_mask(recon_data, ratio=cfg.circular_mask)
-            print " * Applied circular mask on reconstructed volume"
+            print(" * Applied circular mask on reconstructed volume")
         else:
-            print " * Note: not applied circular mask on reconstructed volume"
+            print(" * Note: not applied circular mask on reconstructed volume")
 
         if cfg.cut_off_level and cfg.cut_off_level > 0.0:
-            print "=== applying cut-off: {0}".format(cfg.cut_off)
+            print("=== applying cut-off: {0}".format(cfg.cut_off))
             dmin = np.amin(recon_data)
             dmax = np.amax(recon_data)
             rel_cut_off = dmin + cfg.cut_off * (dmax - dmin)
             recon_data[recon_data < rel_cut_off] = dmin
 
         if cfg.gaussian_filter_par:
-            print " * Gaussian filter not implemented"
+            print(" * Gaussian filter not implemented")
 
         if cfg.median_filter_size and cfg.median_filter_size > 1:
             recon_data = scipy.ndimage.median_filter(recon_data, cfg.median_filter_size)
-            print (" * Applied median_filter on reconstructed volume, with filtersize: {0}".
-                   format(cfg.median_filter_size))
+            print(" * Applied median_filter on reconstructed volume, with filtersize: {0}".
+                  format(cfg.median_filter_size))
         else:
-            print " * Note: not applied median_filter on reconstructed volume"
+            print(" * Note: not applied median_filter on reconstructed volume")
 
         if cfg.median_filter3d_size and cfg.median_filter3d_size > 1:
             kernel_size=3
@@ -824,7 +833,7 @@ class ReconstructionCommand(object):
             print(" * Applied N-dimensional median filter on reconstructed volume, with filter size: {0} ".
                   format(kernel_size))
         else:
-            print " * Note: not applied N-dimensional median filter on reconstructed volume"
+            print(" * Note: not applied N-dimensional median filter on reconstructed volume")
 
     def read_in_stack(self, sample_path, img_format, flat_field_path=None, dark_field_path=None):
         """
@@ -872,7 +881,7 @@ class ReconstructionCommand(object):
         # output_dir = 'output_recon_tomopy'
         output_dir = cfg.postproc_cfg.output_dir
         out_recon_dir = os.path.join(output_dir, 'reconstructed')
-        print "* Saving slices of the reconstructed volume in: {0}".format(out_recon_dir)
+        print("* Saving slices of the reconstructed volume in: {0}".format(out_recon_dir))
         tomoio.save_recon_as_vertical_slices(recon_data, out_recon_dir,
                                              name_prefix=self._OUT_SLICES_FILENAME_PREFIX,
                                              img_format=cfg.preproc_cfg.out_img_format)
@@ -881,13 +890,13 @@ class ReconstructionCommand(object):
         save_horiz_slices = False
         if save_horiz_slices:
             out_horiz_dir = os.path.join(output_dir, 'horiz_slices')
-            print "* Saving horizontal slices in: {0}".format(out_horiz_dir)
+            print("* Saving horizontal slices in: {0}".format(out_horiz_dir))
             tomoio.save_recon_as_horizontal_slices(recon_data, out_horiz_dir,
                                                    name_prefix=self._OUT_HORIZ_SLICES_SUBDIR,
                                                    img_format=cfg.preproc_cfg.out_img_format)
 
         if save_netcdf_vol:
-            print "* Saving reconstructed volume as NetCDF"
+            print("* Saving reconstructed volume as NetCDF")
             tomoio.save_recon_netcdf(recon_data, output_dir)
 
     def save_preproc_images(self, output_dir, preproc_data, preproc_cfg, out_dtype='uint16'):
@@ -900,13 +909,13 @@ class ReconstructionCommand(object):
         @param out_dtype :: dtype used for the pixel type/depth in the output image files
         """
 
-        print " * Pre-processed images (preproc_data) dtype:", preproc_data.dtype
+        print(" * Pre-processed images (preproc_data) dtype:", preproc_data.dtype)
         min_pix = np.amin(preproc_data)
         max_pix = np.amax(preproc_data)
-        print "   with min_pix: {0}, max_pix: {1}".format(min_pix, max_pix)
+        print("   with min_pix: {0}, max_pix: {1}".format(min_pix, max_pix))
         if preproc_cfg.save_preproc_imgs:
             preproc_dir = os.path.join(output_dir, self._PREPROC_IMGS_SUBDIR_NAME)
-            print "* Saving pre-processed images into: {0}".format(preproc_dir)
+            print("* Saving pre-processed images into: {0}".format(preproc_dir))
             tomoio.make_dirs_if_needed(preproc_dir)
             for idx in range(0, preproc_data.shape[0]):
                 # rescale_intensity has issues with float64=>int16
@@ -914,7 +923,7 @@ class ReconstructionCommand(object):
                                    os.path.join(preproc_dir, 'out_preproc_proj_image' + str(idx).zfill(6)),
                                    img_format=preproc_cfg.out_img_format, dtype=out_dtype)
         else:
-            print "* NOTE: not saving pre-processed images..."
+            print("* NOTE: not saving pre-processed images...")
 
     def _check_data_stack(self, data):
         if not isinstance(data, np.ndarray):
diff --git a/scripts/Imaging/IMAT/tomorec/tool_imports.py b/scripts/Imaging/IMAT/tomorec/tool_imports.py
index 5896d1c87cd853b9032f95acf537f8d70359a65d..066d8c266abe392b3b37d46aa4e986d496096a59 100644
--- a/scripts/Imaging/IMAT/tomorec/tool_imports.py
+++ b/scripts/Imaging/IMAT/tomorec/tool_imports.py
@@ -1,3 +1,4 @@
+from __future__ import (absolute_import, division, print_function)
 # Copyright &copy; 2014-2015 ISIS Rutherford Appleton Laboratory, NScD
 # Oak Ridge National Laboratory & European Spallation Source
 #
@@ -48,11 +49,11 @@ def _import_tool_astra():
     MIN_ASTRA_VERSION = 106
     vers = astra.astra.version()
     if isinstance(vers, int) and vers >= MIN_ASTRA_VERSION:
-        print "Imported astra successfully. Version: {0}".format(astra.astra.version())
+        print("Imported astra successfully. Version: {0}".format(astra.astra.version()))
     else:
         raise RuntimeError("Could not find the required version of astra. Found version: {0}".format(vers))
 
-    print "Astra using cuda: {0}". format(astra.astra.use_cuda())
+    print("Astra using cuda: {0}". format(astra.astra.use_cuda()))
     return astra
 
 
diff --git a/scripts/Inelastic/CrystalField/fitting.py b/scripts/Inelastic/CrystalField/fitting.py
index ed377f7a9dda626b42b4cc9294e7f25e4ccf9f59..b554440d681f7014f64173eea2d4f75cd8de1e92 100644
--- a/scripts/Inelastic/CrystalField/fitting.py
+++ b/scripts/Inelastic/CrystalField/fitting.py
@@ -1,7 +1,7 @@
 from __future__ import (absolute_import, division, print_function)
 import numpy as np
 import re
-from mantid.kernel import ConfigService
+import warnings
 
 # RegEx pattern matching a composite function parameter name, eg f2.Sigma.
 FN_PATTERN = re.compile('f(\\d+)\\.(.+)')
@@ -104,9 +104,6 @@ class CrystalField(object):
                         FWHM: A default value for the full width at half maximum of the peaks.
                         Temperature: A temperature "of the spectrum" in Kelvin
         """
-        # This is to make sure that Lorentzians get evaluated properly
-        ConfigService.setString('curvefitting.peakRadius', str(100))
-
         from .function import PeaksFunction
         self._ion = Ion
         self._symmetry = Symmetry
@@ -117,7 +114,7 @@ class CrystalField(object):
         self._fieldConstraints = []
         self._temperature = None
         self._FWHM = None
-        self._intensityScaling = 1.0
+        self._intensityScaling = None
         self._resolutionModel = None
         self._fwhmVariation = None
         self._fixAllPeaks = False
@@ -185,8 +182,10 @@ class CrystalField(object):
         temperature = self._getTemperature(i)
         out = 'name=CrystalFieldSpectrum,Ion=%s,Symmetry=%s,Temperature=%s' % (self._ion, self._symmetry, temperature)
         out += ',ToleranceEnergy=%s,ToleranceIntensity=%s' % (self._toleranceEnergy, self._toleranceIntensity)
-        out += ',FixAllPeaks=%s' % self._fixAllPeaks
+        out += ',FixAllPeaks=%s' % (1 if self._fixAllPeaks else 0)
         out += ',PeakShape=%s' % self.getPeak(i).name
+        if self._intensityScaling is not None:
+            out += ',IntensityScaling=%s' % self._intensityScaling
         if self._FWHM is not None:
             out += ',FWHM=%s' % self._getFWHM(i)
         if len(self._fieldParameters) > 0:
@@ -224,11 +223,11 @@ class CrystalField(object):
             out += ',constraints=(%s)' % constraints
         return out
 
-    # pylint: disable=too-many-public-branches
-    def makeMultiSpectrumFunction(self):
-        """Form a definition string for the CrystalFieldMultiSpectrum function"""
-        out = 'name=CrystalFieldMultiSpectrum,Ion=%s,Symmetry=%s' % (self._ion, self._symmetry)
-        out += ',ToleranceEnergy=%s,ToleranceIntensity=%s' % (self._toleranceEnergy, self._toleranceIntensity)
+    def _makeMultiAttributes(self):
+        """
+        Make the main attribute part of the function string for makeMultiSpectrumFunction()
+        """
+        out = ',ToleranceEnergy=%s,ToleranceIntensity=%s' % (self._toleranceEnergy, self._toleranceIntensity)
         out += ',PeakShape=%s' % self.getPeak().name
         out += ',FixAllPeaks=%s' % self._fixAllPeaks
         if self.background is not None:
@@ -236,24 +235,16 @@ class CrystalField(object):
         out += ',Temperatures=(%s)' % ','.join(map(str, self._temperature))
         if self._FWHM is not None:
             out += ',FWHMs=(%s)' % ','.join(map(str, self._FWHM))
-        out += ',%s' % ','.join(['%s=%s' % item for item in self._fieldParameters.items()])
+        if self._intensityScaling is not None:
+            for i in range(len(self._intensityScaling)):
+                out += ',IntensityScaling%s=%s' % (i, self._intensityScaling[i])
+        return out
 
-        tieList = []
-        constraintsList = []
-        if self.background is not None:
-            i = 0
-            for background in self.background:
-                prefix = 'f%s.f0.' % i
-                bgOut = background.paramString(prefix)
-                if len(bgOut) > 0:
-                    out += ',%s' % bgOut
-                tieOut = background.tiesString(prefix)
-                if len(tieOut) > 0:
-                    tieList.append(tieOut)
-                constraintsOut = background.constraintsString(prefix)
-                if len(constraintsOut) > 0:
-                    constraintsList.append(constraintsOut)
-                i += 1
+    def _makeMultiResolutionModel(self):
+        """
+        Make the resolution model part of the function string for makeMultiSpectrumFunction()
+        """
+        out = ''
         if self._resolutionModel is not None:
             i = 0
             for model in self._resolutionModel.model:
@@ -261,6 +252,13 @@ class CrystalField(object):
                 i += 1
             if self._fwhmVariation is not None:
                 out += ',FWHMVariation=%s' % self._fwhmVariation
+        return out
+
+    def _makeMultiPeaks(self):
+        """
+        Make the peaks part of the function string for makeMultiSpectrumFunction()
+        """
+        out = ''
         i = 0
         for peaks in self.peaks:
             parOut = peaks.paramString('f%s.' % i, 1)
@@ -273,6 +271,34 @@ class CrystalField(object):
             if len(constraintsOut) > 0:
                 out += ',%s' % constraintsOut
             i += 1
+        return out
+
+    # pylint: disable=too-many-public-branches
+    def makeMultiSpectrumFunction(self):
+        """Form a definition string for the CrystalFieldMultiSpectrum function"""
+        out = 'name=CrystalFieldMultiSpectrum,Ion=%s,Symmetry=%s' % (self._ion, self._symmetry)
+        out += self._makeMultiAttributes()
+        out += ',%s' % ','.join(['%s=%s' % item for item in self._fieldParameters.items()])
+
+        tieList = []
+        constraintsList = []
+        if self.background is not None:
+            i = 0
+            for background in self.background:
+                prefix = 'f%s.f0.' % i
+                bgOut = background.paramString(prefix)
+                if len(bgOut) > 0:
+                    out += ',%s' % bgOut
+                tieOut = background.tiesString(prefix)
+                if len(tieOut) > 0:
+                    tieList.append(tieOut)
+                constraintsOut = background.constraintsString(prefix)
+                if len(constraintsOut) > 0:
+                    constraintsList.append(constraintsOut)
+                i += 1
+        out += self._makeMultiResolutionModel()
+        out += self._makeMultiPeaks()
+
         ties = self.getFieldTies()
         if len(ties) > 0:
             tieList.append(ties)
@@ -381,7 +407,7 @@ class CrystalField(object):
 
     @Temperature.setter
     def Temperature(self, value):
-        self._temperature= value
+        self._temperature = value
         self._dirty_peaks = True
         self._dirty_spectra = True
 
@@ -421,6 +447,10 @@ class CrystalField(object):
     def FixAllPeaks(self, value):
         self._fixAllPeaks = value
 
+    @property
+    def NumberOfSpectra(self):
+        return len(self._temperature)
+
     def ties(self, **kwargs):
         """Set ties on the field parameters.
 
@@ -677,7 +707,19 @@ class CrystalField(object):
         return x_min, x_max
 
     def __add__(self, other):
-        return CrystalFieldMulti(self, other)
+        if isinstance(other, CrystalFieldMulti):
+            return other.__radd__(self)
+        return CrystalFieldMulti(CrystalFieldSite(self, 1.0), other)
+
+    def __mul__(self, factor):
+        ffactor = float(factor)
+        if ffactor == 0.0:
+            msg = 'Intensity scaling factor for %s(%s) is set to zero ' % (self.Ion, self.Symmetry)
+            warnings.warn(msg, SyntaxWarning)
+        return CrystalFieldSite(self, ffactor)
+
+    def __rmul__(self, factor):
+        return self.__mul__(factor)
 
     def _getTemperature(self, i):
         """Get temperature value for i-th spectrum."""
@@ -689,7 +731,7 @@ class CrystalField(object):
             return float(self._temperature)
         else:
             nTemp = len(self._temperature)
-            if i >= -nTemp and i < nTemp:
+            if -nTemp <= i < nTemp:
                 return float(self._temperature[i])
             else:
                 raise RuntimeError('Cannot evaluate spectrum %s. Only %s temperatures are given.' % (i, nTemp))
@@ -765,28 +807,56 @@ class CrystalField(object):
         return hasattr(self._temperature, '__len__')
 
 
+class CrystalFieldSite(object):
+    """
+    A helper class for the multi-site algebra. It is a result of the '*' operation between a CrystalField
+    and a number. Multiplication sets the abundance for the site and which the returned object holds.
+    """
+    def __init__(self, crystalField, abundance):
+        self.crystalField = crystalField
+        self.abundance = abundance
+
+    def __add__(self, other):
+        if isinstance(other, CrystalField):
+            return CrystalFieldMulti(self, CrystalFieldSite(other, 1))
+        elif isinstance(other, CrystalFieldSite):
+            return CrystalFieldMulti(self, other)
+        elif isinstance(other, CrystalFieldMulti):
+            return other.__radd__(self)
+        raise TypeError('Unsupported operand type(s) for +: CrystalFieldSite and %s' % other.__class__.__name__)
+
+
 class CrystalFieldMulti(object):
     """CrystalFieldMulti represents crystal field of multiple ions."""
 
     def __init__(self, *args):
-        if isinstance(args, tuple):
-            self.args = args
-        else:
-            self.args = (self.args,)
+        self.sites = []
+        self.abundances = []
+        for arg in args:
+            if isinstance(arg, CrystalField):
+                self.sites.append(arg)
+                self.abundances.append(1.0)
+            elif isinstance(arg, CrystalFieldSite):
+                self.sites.append(arg.crystalField)
+                self.abundances.append(arg.abundance)
+            else:
+                raise RuntimeError('Cannot include an object of type %s into a CrystalFieldMulti' % type(arg))
         self._ties = {}
 
     def makeSpectrumFunction(self):
-        fun = ';'.join([a.makeSpectrumFunction() for a in self.args])
+        fun = ';'.join([a.makeSpectrumFunction() for a in self.sites])
+        fun += self._makeIntensityScalingTies()
         ties = self.getTies()
         if len(ties) > 0:
-            fun += ',ties=(%s)' % ties
+            fun += ';ties=(%s)' % ties
         return fun
 
     def makeMultiSpectrumFunction(self):
-        fun = ';'.join([a.makeMultiSpectrumFunction() for a in self.args])
+        fun = ';'.join([a.makeMultiSpectrumFunction() for a in self.sites])
+        fun += self._makeIntensityScalingTiesMulti()
         ties = self.getTies()
         if len(ties) > 0:
-            fun += ',ties=(%s)' % ties
+            fun += ';ties=(%s)' % ties
         return fun
 
     def ties(self, **kwargs):
@@ -799,50 +869,127 @@ class CrystalFieldMulti(object):
         return ','.join(ties)
 
     def getSpectrum(self, i=0, workspace=None, ws_index=0):
+        largest_abundance= max(self.abundances)
         if workspace is not None:
-            xArray, yArray = self.args[0].getSpectrum(i, workspace, ws_index)
-            for arg in self.args[1:]:
+            xArray, yArray = self.sites[0].getSpectrum(i, workspace, ws_index)
+            yArray *= self.abundances[0] / largest_abundance
+            ia = 1
+            for arg in self.sites[1:]:
                 _, yyArray = arg.getSpectrum(i, workspace, ws_index)
-                yArray += yyArray
+                yArray += yyArray * self.abundances[ia] / largest_abundance
+                ia += 1
             return xArray, yArray
         x_min = 0.0
         x_max = 0.0
-        for arg in self.args:
+        for arg in self.sites:
             xmin, xmax = arg.calc_xmin_xmax(i)
             if xmin < x_min:
                 x_min = xmin
             if xmax > x_max:
                 x_max = xmax
         xArray = np.linspace(x_min, x_max, CrystalField.default_spectrum_size)
-        _, yArray = self.args[0].getSpectrum(i, xArray, ws_index)
-        for arg in self.args[1:]:
+        _, yArray = self.sites[0].getSpectrum(i, xArray, ws_index)
+        yArray *= self.abundances[0] / largest_abundance
+        ia = 1
+        for arg in self.sites[1:]:
             _, yyArray = arg.getSpectrum(i, xArray, ws_index)
-            yArray += yyArray
+            yArray += yyArray * self.abundances[ia] / largest_abundance
+            ia += 1
         return xArray, yArray
 
     def update(self, func):
         nFunc = func.nFunctions()
-        assert nFunc == len(self.args)
+        assert nFunc == len(self.sites)
         for i in range(nFunc):
-            self.args[i].update(func[i])
+            self.sites[i].update(func[i])
 
     def update_multi(self, func):
         nFunc = func.nFunctions()
-        assert nFunc == len(self.args)
+        assert nFunc == len(self.sites)
         for i in range(nFunc):
-            self.args[i].update_multi(func[i])
+            self.sites[i].update_multi(func[i])
+
+    def _makeIntensityScalingTies(self):
+        """
+        Make a tie string that ties IntensityScaling's of the sites according to their abundances.
+        """
+        n_sites = len(self.sites)
+        if n_sites < 2:
+            return ''
+        factors = np.array(self.abundances)
+        i_largest = np.argmax(factors)
+        largest_factor = factors[i_largest]
+        tie_template = 'f%s.IntensityScaling=%s*' + 'f%s.IntensityScaling' % i_largest
+        ties = []
+        for i in range(n_sites):
+            if i != i_largest:
+                ties.append(tie_template % (i, factors[i] / largest_factor))
+        s = ';ties=(%s)' % ','.join(ties)
+        return s
+
+    def _makeIntensityScalingTiesMulti(self):
+        """
+        Make a tie string that ties IntensityScaling's of the sites according to their abundances.
+        """
+        n_sites = len(self.sites)
+        if n_sites < 2:
+            return ''
+        factors = np.array(self.abundances)
+        i_largest = np.argmax(factors)
+        largest_factor = factors[i_largest]
+        tie_template = 'f{1}.IntensityScaling{0}={2}*f%s.IntensityScaling{0}' % i_largest
+        ties = []
+        n_spectra = self.sites[0].NumberOfSpectra
+        for spec in range(n_spectra):
+            for i in range(n_sites):
+                if i != i_largest:
+                    ties.append(tie_template.format(spec, i, factors[i] / largest_factor))
+        s = ';ties=(%s)' % ','.join(ties)
+        return s
 
     def __add__(self, other):
         if isinstance(other, CrystalFieldMulti):
-            return CrystalFieldMulti(*(self.args + other.args))
+            cfm = CrystalFieldMulti()
+            cfm.sites += self.sites + other.sites
+            cfm.abundances += self.abundances + other.abundances
+            return cfm
+        elif isinstance(other, CrystalField):
+            cfm = CrystalFieldMulti()
+            cfm.sites += self.sites + [other]
+            cfm.abundances += self.abundances + [1]
+            return cfm
+        elif isinstance(other, CrystalFieldSite):
+            cfm = CrystalFieldMulti()
+            cfm.sites += self.sites + [other.crystalField]
+            cfm.abundances += self.abundances + [other.abundance]
+            return cfm
+        else:
+            raise TypeError('Cannot add %s to CrystalFieldMulti' % other.__class__.__name__)
+
+    def __radd__(self, other):
+        if isinstance(other, CrystalFieldMulti):
+            cfm = CrystalFieldMulti()
+            cfm.sites += other.sites + self.sites
+            cfm.abundances += other.abundances + self.abundances
+            return cfm
+        elif isinstance(other, CrystalField):
+            cfm = CrystalFieldMulti()
+            cfm.sites += [other] + self.sites
+            cfm.abundances += [1] + self.abundances
+            return cfm
+        elif isinstance(other, CrystalFieldSite):
+            cfm = CrystalFieldMulti()
+            cfm.sites += [other.crystalField] + self.sites
+            cfm.abundances += [other.abundance] + self.abundances
+            return cfm
         else:
-            return CrystalFieldMulti(*(self.args.append(other.args)))
+            raise TypeError('Cannot add %s to CrystalFieldMulti' % other.__class__.__name__)
 
     def __len__(self):
-        return len(self.args)
+        return len(self.sites)
 
     def __getitem__(self, item):
-        return self.args[item]
+        return self.sites[item]
 
 
 #pylint: disable=too-few-public-methods
@@ -861,6 +1008,7 @@ class CrystalFieldFit(object):
         self._output_workspace_base_name = 'fit'
         self._fit_properties = kwargs
         self._function = None
+        self._estimated_parameters = None
 
     def fit(self):
         """
@@ -872,12 +1020,61 @@ class CrystalFieldFit(object):
             return self._fit_single()
 
     def monte_carlo(self, **kwargs):
+        fix_all_peaks = self.model.FixAllPeaks
+        self.model.FixAllPeaks = True
         if isinstance(self._input_workspace, list):
             self._monte_carlo_multi(**kwargs)
         else:
             self._monte_carlo_single(**kwargs)
+        self.model.FixAllPeaks = fix_all_peaks
+
+    def estimate_parameters(self, EnergySplitting, Parameters, **kwargs):
+        from CrystalField.normalisation import split2range
+        from mantid.api import mtd
+        ranges = split2range(Ion=self.model.Ion, EnergySplitting=EnergySplitting,
+                             Parameters=Parameters)
+        constraints = [('%s<%s<%s' % (-bound, parName, bound)) for parName, bound in ranges.items()]
+        self.model.constraints(*constraints)
+        if 'Type' not in kwargs or kwargs['Type'] == 'Monte Carlo':
+            if 'OutputWorkspace' in kwargs and kwargs['OutputWorkspace'].strip() != '':
+                output_workspace = kwargs['OutputWorkspace']
+            else:
+                output_workspace = 'estimated_parameters'
+                kwargs['OutputWorkspace'] = output_workspace
+        else:
+            output_workspace = None
+        self.monte_carlo(**kwargs)
+        if output_workspace is not None:
+            self._estimated_parameters = mtd[output_workspace]
+
+    def get_number_estimates(self):
+        """
+        Get a number of parameter sets estimated with self.estimate_parameters().
+        """
+        if self._estimated_parameters is None:
+            return 0
+        else:
+            return self._estimated_parameters.columnCount() - 1
+
+    def select_estimated_parameters(self, index):
+        ne = self.get_number_estimates()
+        if ne == 0:
+            raise RuntimeError('There are no estimated parameters.')
+        if index >= ne:
+            raise RuntimeError('There are only %s sets of estimated parameters, requested set #%s' % (ne, index))
+        for row in range(self._estimated_parameters.rowCount()):
+            name = self._estimated_parameters.cell(row, 0)
+            value = self._estimated_parameters.cell(row, index)
+            self.model[name] = value
+            if self._function is not None:
+                self._function.setParameter(name, value)
 
     def _monte_carlo_single(self, **kwargs):
+        """
+        Call EstimateFitParameters algorithm in a single spectrum case.
+        Args:
+            **kwargs: Properties of the algorithm.
+        """
         from mantid.api import AlgorithmManager
         fun = self.model.makeSpectrumFunction()
         alg = AlgorithmManager.createUnmanaged('EstimateFitParameters')
@@ -892,6 +1089,11 @@ class CrystalFieldFit(object):
         self._function = function
 
     def _monte_carlo_multi(self, **kwargs):
+        """
+        Call EstimateFitParameters algorithm in a multi-spectrum case.
+        Args:
+            **kwargs: Properties of the algorithm.
+        """
         from mantid.api import AlgorithmManager
         fun = self.model.makeMultiSpectrumFunction()
         alg = AlgorithmManager.createUnmanaged('EstimateFitParameters')
diff --git a/scripts/Inelastic/CrystalField/normalisation.py b/scripts/Inelastic/CrystalField/normalisation.py
new file mode 100644
index 0000000000000000000000000000000000000000..088985ef6b951e3a4db57510836badaf376a862a
--- /dev/null
+++ b/scripts/Inelastic/CrystalField/normalisation.py
@@ -0,0 +1,212 @@
+import numpy as np
+from CrystalField.energies import energies as CFEnergy
+
+
+def _get_normalisation(nre, bnames):
+    """ Helper function to calculate the normalisation factor.
+        Defined as: ||Blm|| = sum_{Jz,Jz'} |<Jz|Blm|Jz'>|^2 / (2J+1)
+    """
+    J = [0, 5./2, 4, 9./2, 4, 5./2, 0, 7./2, 6, 15./2, 8, 15./2, 6, 7./2]
+    retval = {}
+    for bname in bnames:
+        bdict = {bname: 1}
+        ee, vv, ham = CFEnergy(nre, **bdict)
+        Omat = np.mat(ham)
+        norm = np.trace(np.real(Omat * np.conj(Omat))) / (2*J[nre]+1)
+        retval[bname] = np.sqrt(np.abs(norm)) * np.sign(norm)
+    return retval
+
+
+def _parse_args(**kwargs):
+    """ Parses input arguments for stev2norm() and norm2stev().
+    """
+    # Some definitions
+    Blms = ['B20', 'B21', 'B22', 'B40', 'B41', 'B42', 'B43', 'B44', 'B60', 'B61', 'B62', 'B63', 'B64', 'B65', 'B66']
+    Ions = ['Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb']
+    # Some Error checking
+    if 'Ion' not in kwargs.keys() and 'IonNum' not in kwargs.keys():
+        raise NameError('You must specify the ion using either the ''Ion'', ''IonNum'' keywords')
+    if 'Ion' in kwargs.keys():
+        nre = [id for id, val in enumerate(Ions) if val == kwargs['Ion']][0] + 1
+    else:
+        nre = kwargs['IonNum']
+    # Now parses the list of input crystal field parameters
+    par_names = []
+    Blm = {}
+    for pname in Blms:
+        if pname in kwargs.keys():
+            par_names.append(pname)
+            Blm[pname] = kwargs[pname]
+    if not par_names:
+        if 'B' in kwargs.keys():
+            for ind, pname in enumerate(Blms):
+                par_names.append(pname)
+                Blm[pname] = kwargs['B'][ind]
+        else:
+            raise NameError('You must specify at least one input Blm parameter')
+    return nre, par_names, Blm
+
+
+def stev2norm(**kwargs):
+    """ Calculates the "normalised" crystal field parameters of P. Fabi
+        These parameters are defined in the appendix of the FOCUS program manual,
+        http://purl.org/net/epubs/manifestation/5723 page 59.
+
+        nlm = stev2norm(Ion=ionname, B=bvec)
+        nlm = stev2norm(Ion=ionname, B20=b20val, ...)
+        nlm = stev2norm(IonNum=ionnumber, B20=b20val, ...)
+        [B20, B40] = stev2norm(IonNum=ionnumber, B20=b20val, B40=b40val, OutputTuple=True)
+
+        Note: This function only accepts keyword inputs.
+
+        Inputs:
+            ionname - name of the (tripositive) rare earth ion, e.g. 'Ce', 'Pr'.
+            ionnumber - the number index of the rare earth ion:
+                   1=Ce 2=Pr 3=Nd 4=Pm 5=Sm 6=Eu 7=Gd 8=Tb 9=Dy 10=Ho 11=Er 12=Tm 13=Yb
+            bvec - a vector of the Stevens CF parameters in order: [B20 B21 B22 B40 B41 ... etc.]
+                    This vector can also a be dictionary instead {'B20':1, 'B40':2}
+            b20val etc. - values of the Stevens CF parameters to be converted
+
+        Outputs:
+            nlm - a dictionary of the normalised crystal field parameters (default)
+            [B20, etc] - a tuple of the normalised crystal field parameters (need to set OutputTuple flag)
+
+        Note: one of the keywords: Ion and IonNum must be specified.
+
+    """
+    # Parses the input parameters
+    nre, par_names, Blm = _parse_args(**kwargs)
+    # Gets the normalisation constants
+    norm = _get_normalisation(nre, par_names)
+    # Calculates the normalised parameters.
+    Nlm = {}
+    for pname in par_names:
+        Nlm[pname] = Blm[pname] * norm[pname]
+
+    return Nlm
+
+
+def norm2stev(**kwargs):
+    """ Calculates the Stevens (conventional) crystal field parameters from "normalised" parameters
+        The normalised parameters of P. Fabi are defined in the appendix of the FOCUS program manual,
+        http://purl.org/net/epubs/manifestation/5723 page 59.
+
+        nlm = norm2stev(Ion=ionname, B=bvec)
+        nlm = norm2stev(Ion=ionname, B20=b20val, ...)
+        nlm = norm2stev(IonNum=ionnumber, B20=b20val, ...)
+        [B20, B40] = norm2stev(IonNum=ionnumber, B20=b20val, B40=b40val, OutputTuple=True)
+
+        Note: This function only accepts keyword inputs.
+
+        Inputs:
+            ionname - name of the (tripositive) rare earth ion, e.g. 'Ce', 'Pr'.
+            ionnumber - the number index of the rare earth ion:
+                   1=Ce 2=Pr 3=Nd 4=Pm 5=Sm 6=Eu 7=Gd 8=Tb 9=Dy 10=Ho 11=Er 12=Tm 13=Yb
+            bvec - a vector of the Stevens CF parameters in order: [B20 B21 B22 B40 B41 ... etc.]
+                    This vector can also a be dictionary instead {'B20':1, 'B40':2}
+            b20val etc. - values of the Stevens CF parameters to be converted
+
+        Outputs:
+            nlm - a dictionary of the normalised crystal field parameters (default)
+            [B20, etc] - a tuple of the normalised crystal field parameters (need to set OutputTuple flag)
+
+        Note: one of the keywords: Ion and IonNum must be specified.
+
+    """
+    # Parses the input parameters
+    nre, par_names, Blm = _parse_args(**kwargs)
+    # Gets the normalisation constants
+    norm = _get_normalisation(nre, par_names)
+    # Calculates the normalised parameters.
+    Nlm = {}
+    for pname in par_names:
+        Nlm[pname] = 0 if norm[pname] == 0 else Blm[pname] / norm[pname]
+
+    return Nlm
+
+
+def split2range(*args, **kwargs):
+    """ Calculates the ranges of (Stevens) crystal field parameters to give energy splittings
+        around a specified a desired energy splitting
+
+        ranges = split2range(ionname, energy_splitting, bnames)
+        ranges = split2range(Ion=ionname, EnergySplitting=energy_splitting, Parameters=bnames)
+        ranges = split2range(IonNum=ionnumber, EnergySplitting=energy_splitting, Parameters=bnames)
+        ranges = split2range(PointGroup=point_group, EnergySplitting=energy_splitting, 'B20', 'B22', ...)
+        ranges = split2range(PointGroup=point_group, EnergySplitting=energy_splitting, B20=_, B22=_, ...)
+        ranges = split2range(..., Output='dictionary')
+        constraint_string = split2range(..., Output='constraints')
+
+        Inputs:
+            ionname - name of the (tripositive) rare earth ion, e.g. 'Ce', 'Pr'.
+            ionnumber - the number index of the rare earth ion:
+                1=Ce 2=Pr 3=Nd 4=Pm 5=Sm 6=Eu 7=Gd 8=Tb 9=Dy 10=Ho 11=Er 12=Tm 13=Yb
+            energy_splitting - the desired energy splitting (difference between the energies of the
+                highest and lowest crystal field energy levels) in meV
+            bnames - a list of names of the crystal field parameters to give the range for
+            'B20', etc - the names of the parameters can be given as individual arguments or
+                keyword arguments. In the case of keyword arguments, only the key names will be used
+
+        Output:
+            ranges - a dictionary of the ranges such that sampling uniformly in |Blm|<range[bnames]
+                will produce crystal field splittings distributed normally around the input
+                energy_splitting.
+            constraint_string - a string of the form '-[range]<Blm<[range]' where [range] is the
+                calculated range for that parameter.
+            By default, the Output keyword is set to "dictionary".
+
+        Note: ionname or ionnumber must be specified.
+    """
+    argin = {}
+    argnames = ['Ion', 'EnergySplitting', 'Parameters', 'Output', 'IonNum']
+    # Set default values.
+    argin['Output'] = 'dictionary'
+    argin['Parameters'] = []
+    # Parses the non-keyword arguments
+    for ia in range(3 if len(args)>3 else len(args)):
+        argin[argnames[ia]] = args[ia]
+    # Further arguments beyond the first 3 are treated as crystal field parameter names
+    for ia in range(3, len(args)):
+        if isinstance(args[ia], basestring) and args[ia].startswith('B'):
+            argin['Parameters'].append(args[ia])
+    # Parses the keyword arguments
+    for key, value in kwargs.iteritems():
+        for ia in range(len(argnames)):
+            if key == argnames[ia]:
+                argin[key] = value
+                break
+        if key.startswith('B'):
+            argin['Parameters'].append(key)
+
+    # Error checking
+    if 'Ion' not in argin.keys() and 'IonNum' not in argin.keys():
+        raise NameError('You must specify the ion using either the ''Ion'', ''IonNum'' keywords')
+    Ions = ['Ce', 'Pr', 'Nd', 'Pm', 'Sm', 'Eu', 'Gd', 'Tb', 'Dy', 'Ho', 'Er', 'Tm', 'Yb']
+    if 'Ion' in argin.keys():
+        nre = [ id for id,val in enumerate(Ions) if val==kwargs['Ion'] ][0] + 1
+    else:
+        nre = argin['IonNum']
+    if 'EnergySplitting' not in argin.keys():
+        raise NameError('You must specify the desired energy splitting')
+    if not argin['Parameters']:
+        raise NameError('You must specify at least one crystal field parameter name')
+
+    Nlm = {}
+    for bname in set(argin['Parameters']):
+        Nlm[bname] = 1
+    Blm = norm2stev(IonNum=nre, **Nlm)
+    ee, vv, ham = CFEnergy(nre, **Blm)
+    # Factor of 2 is needed to get the Gaussian centred on the desired energy splitting.
+    splitting_factor = 2 * argin['EnergySplitting'] / (np.max(ee-np.min(ee)))
+    Nlm = {}
+    for bname in Blm.keys():
+        Nlm[bname] = splitting_factor
+    ranges = norm2stev(IonNum=nre, **Nlm)
+
+    if argin['Output'].lower() is 'constraints':
+        constr = ''
+        for bname in ranges.keys():
+            constr += '%.4g<%s<%.4g,' % (-ranges[bname], bname, ranges[bname])
+        return constr[:-1]
+    else:
+        return ranges
diff --git a/scripts/Inelastic/Direct/DirectEnergyConversion.py b/scripts/Inelastic/Direct/DirectEnergyConversion.py
index 9b57909c4356de2bdff8efb95c1136eb63303591..5b953a86c52cacb0766916ca48ba28ef283ff3aa 100644
--- a/scripts/Inelastic/Direct/DirectEnergyConversion.py
+++ b/scripts/Inelastic/Direct/DirectEnergyConversion.py
@@ -1415,13 +1415,11 @@ class DirectEnergyConversion(object):
         signal = []
         error = []
         izerc = 0
+        data_specInfo = data_ws.spectrumInfo()
         for i in range(nhist):
-            try:
-                det = data_ws.getDetector(i)
-#pylint: disable=broad-except
-            except Exception:
+            if not data_specInfo.hasDetectors(i):
                 continue
-            if det.isMasked():
+            if data_specInfo.isMasked(i):
                 continue
             sig = data_ws.readY(i)[0]
             err = data_ws.readE(i)[0]
diff --git a/scripts/Inelastic/Direct/diagnostics.py b/scripts/Inelastic/Direct/diagnostics.py
index 0916cdd231a60bab54baddc1713c8e8c2ef38b2a..3e8a38ee9ac10c2063f759797ffb804de3c144cc 100644
--- a/scripts/Inelastic/Direct/diagnostics.py
+++ b/scripts/Inelastic/Direct/diagnostics.py
@@ -454,13 +454,11 @@ def get_failed_spectra_list(diag_workspace):
         diag_workspace = mtd[diag_workspace]
 
     failed_spectra = []
+    spectrumInfo = diag_workspace.spectrumInfo()
     for i in range(diag_workspace.getNumberHistograms()):
-        try:
-            det = diag_workspace.getDetector(i)
-        except RuntimeError:
-            continue
-        if det.isMasked():
-            failed_spectra.append(diag_workspace.getSpectrum(i).getSpectrumNo())
+        if spectrumInfo.hasDetectors(i):
+            if spectrumInfo.isMasked(i):
+                failed_spectra.append(diag_workspace.getSpectrum(i).getSpectrumNo())
 
     return failed_spectra
 
diff --git a/scripts/Interface/reduction_gui/widgets/inelastic/dgs_sample_setup.py b/scripts/Interface/reduction_gui/widgets/inelastic/dgs_sample_setup.py
index fc6c562eff5eef37525ba791d1a273d96df32542..94f3b66bda7ec3da4b56b9a6b367a527f4bd533a 100644
--- a/scripts/Interface/reduction_gui/widgets/inelastic/dgs_sample_setup.py
+++ b/scripts/Interface/reduction_gui/widgets/inelastic/dgs_sample_setup.py
@@ -93,7 +93,7 @@ class SampleSetupWidget(BaseWidget):
         self._content.sample_edit = mantidqtpython.MantidQt.MantidWidgets.MWRunFiles()
         # Unfortunately, can only use live if default instrument = gui-set instrument
         if self._instrument_name == config.getInstrument().name():
-            self._content.sample_edit.setProperty("liveButton","ShowIfCanConnect")
+            self._content.sample_edit.setProperty("liveButton","Show")
         self._content.sample_edit.setProperty("multipleFiles",True)
         self._content.sample_edit.setProperty("algorithmAndProperty","Load|Filename")
         self._content.sample_edit.setProperty("label",labeltext)
diff --git a/scripts/SANS/SANSUtility.py b/scripts/SANS/SANSUtility.py
index 8b4597faf0103896f547d27b4b421e319fba1418..2fb59898a5a88e08e978069a24a68b62de61048e 100644
--- a/scripts/SANS/SANSUtility.py
+++ b/scripts/SANS/SANSUtility.py
@@ -862,15 +862,14 @@ def get_masked_det_ids(ws):
 
     @returns a list of IDs for masked detectors
     """
+    spectrumInfo = ws.spectrumInfo()
     for ws_index in range(ws.getNumberHistograms()):
-        try:
-            det = ws.getDetector(ws_index)
-        except RuntimeError:
+        if not spectrumInfo.hasDetectors(ws_index):
             # Skip the rest after finding the first spectra with no detectors,
             # which is a big speed increase for SANS2D.
             break
-        if det.isMasked():
-            yield det.getID()
+        if spectrumInfo.isMasked(ws_index):
+            yield ws.getDetector(ws_index).getID()
 
 
 def create_zero_error_free_workspace(input_workspace_name, output_workspace_name):
diff --git a/scripts/test/CrystalFieldTest.py b/scripts/test/CrystalFieldTest.py
index 57e5e4c2a022f944928b2c71eab89b0b144ac299..e8693a42bd9ed068c380ae9f205ba838830d474a 100644
--- a/scripts/test/CrystalFieldTest.py
+++ b/scripts/test/CrystalFieldTest.py
@@ -7,7 +7,7 @@ import numpy as np
 # Import mantid to setup the python paths to the bundled scripts
 import mantid
 from CrystalField.energies import energies
-from mantid.simpleapi import CalculateChiSquared
+from mantid.simpleapi import CalculateChiSquared, EvaluateFunction, mtd
 from mantid.kernel import ConfigService
 
 c_mbsr = 79.5774715459  # Conversion from barn to mb/sr
@@ -1226,7 +1226,7 @@ class CrystalFieldFitTest(unittest.TestCase):
 
         # Define a CrystalField object with parameters slightly shifted.
         cf = CrystalField('Ce', 'C2v', B20=0, B22=0, B40=0, B42=0, B44=0,
-                          Temperature=44.0, FWHM=1.0, ResolutionModel=([0, 100], [1, 1]), FWHMVariation=0)
+                          Temperature=44.0, FWHM=1.0)
 
         # Set the ties
         cf.ties(B20=0.37737)
@@ -1249,11 +1249,8 @@ class CrystalFieldFitTest(unittest.TestCase):
         ws2 = makeWorkspace(*origin.getSpectrum(1))
 
         # Define a CrystalField object with parameters slightly shifted.
-        x = [0, 50]
-        y = [1, 2]
-        rm = ResolutionModel([(x, y), (x, y)])
         cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=0, B42=0, B44=0, NPeaks=9,
-                          Temperature=[44.0, 50.0], FWHM=[1.0, 1.0], ResolutionModel=rm, FWHMVariation=0)
+                          Temperature=[44.0, 50.0], FWHM=[1.0, 1.0])
 
         # Set the ties
         cf.ties(B20=0.37737)
@@ -1265,6 +1262,247 @@ class CrystalFieldFitTest(unittest.TestCase):
         fit.fit()
         self.assertTrue(cf.chi2 < 100.0)
 
+    def test_multi_ion_intensity_scaling(self):
+        from CrystalField import CrystalField, CrystalFieldFit
+        from mantid.simpleapi import FunctionFactory
+        params = {'B20': 0.37737, 'B22': 3.9770, 'B40': -0.031787, 'B42': -0.11611, 'B44': -0.12544,
+                  'Temperature': 44.0, 'FWHM': 1.1}
+        cf1 = CrystalField('Ce', 'C2v', **params)
+        cf2 = CrystalField('Pr', 'C2v', **params)
+        cf = cf1 + cf2
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f1.IntensityScaling=1.0*f0.IntensityScaling' in s)
+
+        cf = 2*cf1 + cf2*8
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.25*f1.IntensityScaling' in s)
+
+        cf = 2 * cf1 + cf2
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f1.IntensityScaling=0.5*f0.IntensityScaling' in s)
+
+        cf3 = CrystalField('Tb', 'C2v', **params)
+        cf = 2 * cf1 + cf2 * 8 + cf3
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.25*f1.IntensityScaling' in s)
+        self.assertTrue('f2.IntensityScaling=0.125*f1.IntensityScaling' in s)
+
+        cf = 2 * cf1 + cf2 * 8 + 10 * cf3
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.2*f2.IntensityScaling' in s)
+        self.assertTrue('f1.IntensityScaling=0.8*f2.IntensityScaling' in s)
+
+        cf = 2 * cf1 + (cf2 * 8 + 10 * cf3)
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.2*f2.IntensityScaling' in s)
+        self.assertTrue('f1.IntensityScaling=0.8*f2.IntensityScaling' in s)
+
+        cf = cf1 + (cf2 * 8 + 10 * cf3)
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.1*f2.IntensityScaling' in s)
+        self.assertTrue('f1.IntensityScaling=0.8*f2.IntensityScaling' in s)
+
+        cf4 = CrystalField('Yb', 'C2v', **params)
+        cf = (2 * cf1 + cf2 * 8) + (10 * cf3 + cf4)
+        fun = FunctionFactory.createInitialized(cf.makeSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling=0.2*f2.IntensityScaling' in s)
+        self.assertTrue('f1.IntensityScaling=0.8*f2.IntensityScaling' in s)
+        self.assertTrue('f3.IntensityScaling=0.1*f2.IntensityScaling' in s)
+
+    def test_multi_ion_intensity_scaling_multi_spectrum(self):
+        from CrystalField import CrystalField, CrystalFieldFit
+        from mantid.simpleapi import FunctionFactory
+        params = {'B20': 0.37737, 'B22': 3.9770, 'B40': -0.031787, 'B42': -0.11611, 'B44': -0.12544,
+                  'Temperature': [44.0, 50.0], 'FWHM': [1.1, 1.6]}
+        cf1 = CrystalField('Ce', 'C2v', **params)
+        cf2 = CrystalField('Pr', 'C2v', **params)
+        cf = cf1 + cf2
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f1.IntensityScaling0=1.0*f0.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=1.0*f0.IntensityScaling1' in s)
+
+        cf = 2 * cf1 + cf2 * 8
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.25*f1.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.25*f1.IntensityScaling1' in s)
+
+        cf = 2 * cf1 + cf2
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f1.IntensityScaling0=0.5*f0.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=0.5*f0.IntensityScaling1' in s)
+
+        cf3 = CrystalField('Tb', 'C2v', **params)
+        cf = 2 * cf1 + cf2 * 8 + cf3
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.25*f1.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.25*f1.IntensityScaling1' in s)
+        self.assertTrue('f2.IntensityScaling0=0.125*f1.IntensityScaling0' in s)
+        self.assertTrue('f2.IntensityScaling1=0.125*f1.IntensityScaling1' in s)
+
+        cf = 2 * cf1 + cf2 * 8 + 10 * cf3
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.2*f2.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.2*f2.IntensityScaling1' in s)
+        self.assertTrue('f1.IntensityScaling0=0.8*f2.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=0.8*f2.IntensityScaling1' in s)
+
+        cf = 2 * cf1 + (cf2 * 8 + 10 * cf3)
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.2*f2.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.2*f2.IntensityScaling1' in s)
+        self.assertTrue('f1.IntensityScaling0=0.8*f2.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=0.8*f2.IntensityScaling1' in s)
+
+        cf = cf1 + (cf2 * 8 + 10 * cf3)
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.1*f2.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.1*f2.IntensityScaling1' in s)
+        self.assertTrue('f1.IntensityScaling0=0.8*f2.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=0.8*f2.IntensityScaling1' in s)
+
+        cf4 = CrystalField('Yb', 'C2v', **params)
+        cf = (2 * cf1 + cf2 * 8) + (10 * cf3 + cf4)
+        fun = FunctionFactory.createInitialized(cf.makeMultiSpectrumFunction())
+        s = str(fun)
+        self.assertTrue('f0.IntensityScaling0=0.2*f2.IntensityScaling0' in s)
+        self.assertTrue('f0.IntensityScaling1=0.2*f2.IntensityScaling1' in s)
+        self.assertTrue('f1.IntensityScaling0=0.8*f2.IntensityScaling0' in s)
+        self.assertTrue('f1.IntensityScaling1=0.8*f2.IntensityScaling1' in s)
+        self.assertTrue('f3.IntensityScaling0=0.1*f2.IntensityScaling0' in s)
+        self.assertTrue('f3.IntensityScaling1=0.1*f2.IntensityScaling1' in s)
+
+    def test_normalisation(self):
+        from CrystalField.normalisation import split2range
+        ranges = split2range(Ion='Pr', EnergySplitting=10,
+                             Parameters=['B20', 'B22', 'B40', 'B42', 'B44', 'B60', 'B62', 'B64', 'B66'])
+        self.assertAlmostEqual(ranges['B44'], 0.013099063718959822, 7)
+        self.assertAlmostEqual(ranges['B60'], 0.00010601965319487525, 7)
+        self.assertAlmostEqual(ranges['B40'], 0.0022141458870077678, 7)
+        self.assertAlmostEqual(ranges['B42'], 0.009901961430901874, 7)
+        self.assertAlmostEqual(ranges['B64'], 0.00084150490931686321, 7)
+        self.assertAlmostEqual(ranges['B22'], 0.19554806997215959, 7)
+        self.assertAlmostEqual(ranges['B20'], 0.11289973083793813, 7)
+        self.assertAlmostEqual(ranges['B66'], 0.0011394030334966495, 7)
+        self.assertAlmostEqual(ranges['B62'], 0.00076818536847364201, 7)
+
+    def test_estimate_parameters_cross_entropy(self):
+        from CrystalField.fitting import makeWorkspace
+        from CrystalField import CrystalField, CrystalFieldFit, Background, Function
+
+        # Create some crystal field data
+        origin = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544,
+                              Temperature=44.0, FWHM=1.1)
+        x, y = origin.getSpectrum()
+        ws = makeWorkspace(x, y)
+
+        # Define a CrystalField object with parameters slightly shifted.
+        cf = CrystalField('Ce', 'C2v', B20=0, B22=0, B40=0, B42=0, B44=0,
+                          Temperature=44.0, FWHM=1.0)
+
+        # Set the ties
+        cf.ties(B20=0.37737)
+        # Create a fit object
+        fit = CrystalFieldFit(cf, InputWorkspace=ws)
+        fit.estimate_parameters(50, ['B22', 'B40', 'B42', 'B44'],
+                                constraints='20<f1.PeakCentre<45,20<f2.PeakCentre<45',
+                                Type='Cross Entropy', NSamples=100)
+        # Run fit
+        fit.fit()
+        self.assertTrue(cf.chi2 < 100.0)
+
+    def test_estimate_parameters_multiple_results(self):
+        from CrystalField.fitting import makeWorkspace
+        from CrystalField import CrystalField, CrystalFieldFit, Background, Function
+
+        # Create some crystal field data
+        origin = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544,
+                              Temperature=44.0, FWHM=1.1)
+        x, y = origin.getSpectrum()
+        ws = makeWorkspace(x, y)
+
+        # Define a CrystalField object with parameters slightly shifted.
+        cf = CrystalField('Ce', 'C2v', B20=0, B22=0, B40=0, B42=0, B44=0,
+                          Temperature=44.0, FWHM=1.0)
+
+        # Set the ties
+        cf.ties(B20=0.37737)
+        # Create a fit object
+        fit = CrystalFieldFit(cf, InputWorkspace=ws)
+        fit.estimate_parameters(50, ['B22', 'B40', 'B42', 'B44'],
+                                constraints='20<f1.PeakCentre<45,20<f2.PeakCentre<45', NSamples=1000)
+        self.assertEqual(fit.get_number_estimates(), 10)
+        fit.fit()
+        self.assertTrue(cf.chi2 < 100.0)
+
+    def test_intensity_scaling_single_spectrum(self):
+        from CrystalField import CrystalField, CrystalFieldFit, Background, Function
+
+        # Define a CrystalField object with parameters slightly shifted.
+        cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544,
+                          Temperature=44.0, FWHM=1.0)
+        _, y0 = cf.getSpectrum()
+
+        cf.IntensityScaling = 2.5
+        _, y1 = cf.getSpectrum()
+
+        self.assertTrue(np.all(y1 / y0 > 2.49999999999))
+        self.assertTrue(np.all(y1 / y0 < 2.50000000001))
+
+    def test_intensity_scaling_single_spectrum_1(self):
+        from CrystalField import CrystalField, CrystalFieldFit, Background, Function
+
+        # Define a CrystalField object with parameters slightly shifted.
+        cf = CrystalField('Ce', 'C2v', IntensityScaling=2.5, B20=0.37737, B22=3.9770, B40=-0.031787,
+                          B42=-0.11611, B44=-0.12544, Temperature=44.0, FWHM=1.0)
+        _, y0 = cf.getSpectrum()
+
+        cf.IntensityScaling = 1.0
+        _, y1 = cf.getSpectrum()
+
+        self.assertTrue(np.all(y0 / y1 > 2.49999999999))
+        self.assertTrue(np.all(y0 / y1 < 2.50000000001))
+
+    def test_intensity_scaling_multi_spectrum(self):
+        from CrystalField.fitting import makeWorkspace
+        from CrystalField import CrystalField, CrystalFieldFit, Background, Function
+
+        # Define a CrystalField object with parameters slightly shifted.
+        cf = CrystalField('Ce', 'C2v', B20=0.37737, B22=3.9770, B40=-0.031787, B42=-0.11611, B44=-0.12544,
+                          Temperature=[44.0, 50.0], FWHM=[1.0, 1.2])
+        x, y0 = cf.getSpectrum(0)
+        ws0 = makeWorkspace(x, y0)
+        x, y1 = cf.getSpectrum(1)
+        ws1 = makeWorkspace(x, y1)
+
+        cf.IntensityScaling = [2.5, 1.5]
+
+        EvaluateFunction(cf.makeMultiSpectrumFunction(), InputWorkspace=ws0, InputWorkspace_1=ws1,
+                         OutputWorkspace='out')
+        out = mtd['out']
+        out0 = out[0].readY(1)
+        out1 = out[1].readY(1)
+
+        self.assertTrue(np.all(out0 / y0 > 2.49999999999))
+        self.assertTrue(np.all(out0 / y0 < 2.50000000001))
+
+        self.assertTrue(np.all(out1 / y1 > 1.49999999999))
+        self.assertTrue(np.all(out1 / y1 < 1.50000000001))
+
 
 if __name__ == "__main__":
     unittest.main()