diff --git a/Code/Mantid/Build/CMake/CommonSetup.cmake b/Code/Mantid/Build/CMake/CommonSetup.cmake
index 10625001e3b6c574ece4d422177e8ab415847cd6..d0876357e91013655141b556ee9626d421b026fb 100644
--- a/Code/Mantid/Build/CMake/CommonSetup.cmake
+++ b/Code/Mantid/Build/CMake/CommonSetup.cmake
@@ -41,7 +41,7 @@ set ( TESTING_TIMEOUT 300 CACHE INTEGER
       "Timeout in seconds for each test (default 300=5minutes)")
 
 ###########################################################################
-# Look for dependencies - bail out if any not found
+# Look for dependencies
 ###########################################################################
 
 set ( Boost_NO_BOOST_CMAKE TRUE )
@@ -60,6 +60,7 @@ include_directories ( SYSTEM ${NEXUS_INCLUDE_DIR} )
 find_package ( MuParser REQUIRED )
 
 find_package ( JsonCPP REQUIRED )
+include_directories ( SYSTEM ${JSONCPP_INCLUDE_DIR} )
 
 find_package ( Doxygen ) # optional
 
@@ -71,6 +72,14 @@ set ( CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH}/zlib123 )
 find_package ( ZLIB REQUIRED )
 set ( CMAKE_INCLUDE_PATH ${MAIN_CMAKE_INCLUDE_PATH} )
 
+if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR (APPLE AND OSX_VERSION VERSION_LESS 10.9))
+  set (HDF5_DIR "${CMAKE_MODULE_PATH}")
+  find_package ( HDF5 COMPONENTS HL REQUIRED
+    CONFIGS hdf5-config.cmake )
+else()
+  find_package ( HDF5 COMPONENTS HL REQUIRED )
+endif()
+
 find_package ( PythonInterp )
 
 if ( MSVC )
diff --git a/Code/Mantid/Build/CMake/FindJsonCPP.cmake b/Code/Mantid/Build/CMake/FindJsonCPP.cmake
index 947dda4c29f66a2347888a9e49437e84a267dece..c52d1418812beaa04c755d26d6616531f0f5fd37 100644
--- a/Code/Mantid/Build/CMake/FindJsonCPP.cmake
+++ b/Code/Mantid/Build/CMake/FindJsonCPP.cmake
@@ -9,8 +9,14 @@
 #  JSONCPP_LIBRARY_DEBUG  - library files for linking (debug version)
 #  JSONCPP_LIBRARIES      - All required libraries, including the configuration type
 
+# Using unset here is a temporary hack to force FindJson to find the correct
+# path in an incremental build. It should be removed a day or two after the
+# branch introducing this is merged.
+unset ( JSONCPP_INCLUDE_DIR CACHE )
+
 # Headers
-find_path ( JSONCPP_INCLUDE_DIR jsoncpp/json/json.h )
+find_path ( JSONCPP_INCLUDE_DIR json/reader.h
+            PATH_SUFFIXES jsoncpp )
 
 # Libraries
 find_library ( JSONCPP_LIBRARY NAMES jsoncpp ) # optimized
diff --git a/Code/Mantid/Build/CMake/FindOpenCascade.cmake b/Code/Mantid/Build/CMake/FindOpenCascade.cmake
index ed88d20d029c4108eb220b3208fb46a643592f5e..4a32f023d327ce7a4958c2581a073373e1a79d40 100644
--- a/Code/Mantid/Build/CMake/FindOpenCascade.cmake
+++ b/Code/Mantid/Build/CMake/FindOpenCascade.cmake
@@ -18,50 +18,61 @@ if ( WIN32 )
   add_definitions ( -DWNT )
 endif ( WIN32 )
 
-set ( OC_REDHAT_RPM /opt/OpenCASCADE/lib64 )
+find_path ( OPENCASCADE_LIBRARY_DIR libTKernel.so PATHS
+                /opt/OpenCASCADE/lib64
+                $ENV{CASROOT}/lib64
+                /opt/OpenCASCADE/lib
+                $ENV{CASROOT}/lib
+                /opt/OpenCASCADE/lib32
+                $ENV{CASROOT}/lib32
+)
+
 find_library ( OPENCASCADE_LIB_TKERNEL
                  NAMES TKernel
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKBO
                  NAMES TKBO
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKPRIM
                  NAMES TKPrim
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKMESH
                  NAMES TKMesh
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKBREP
                  NAMES TKBRep
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKTOPALGO
                  NAMES TKTopAlgo
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKMATH
                  NAMES TKMath
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 find_library ( OPENCASCADE_LIB_TKG2D
                  NAMES TKG2d
-                 PATHS ${OC_REDHAT_RPM}         
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 
 find_library ( OPENCASCADE_LIB_TKG3D
                  NAMES TKG3d
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 
 find_library ( OPENCASCADE_LIB_TKGEOMBASE
                  NAMES TKGeomBase
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 
 find_library ( OPENCASCADE_LIB_TKGEOMALGO
                  NAMES TKGeomAlgo
+                 PATHS ${OPENCASCADE_LIBRARY_DIR}
 )
 
 set ( OPENCASCADE_LIBRARIES
@@ -83,7 +94,7 @@ set ( OPENCASCADE_LIBRARIES
 include ( FindPackageHandleStandardArgs )
 find_package_handle_standard_args( OpenCascade DEFAULT_MSG OPENCASCADE_LIBRARIES OPENCASCADE_INCLUDE_DIR )
 
-mark_as_advanced ( OPENCASCADE_INCLUDE_DIR
+mark_as_advanced ( OPENCASCADE_INCLUDE_DIR OPENCASCADE_LIBRARY_DIR
                    OPENCASCADE_LIB_TKERNEL OPENCASCADE_LIB_TKBO 
                    OPENCASCADE_LIB_TKPRIM OPENCASCADE_LIB_TKMESH
                    OPENCASCADE_LIB_TKBREP OPENCASCADE_LIB_TKTOPALGO 
diff --git a/Code/Mantid/Build/CMake/FindQwt.cmake b/Code/Mantid/Build/CMake/FindQwt.cmake
index 389fc8a99c831c8830e6f903c65b2d3380562092..14cb76f7ba710c294a87c7b52cf61e717256b51b 100644
--- a/Code/Mantid/Build/CMake/FindQwt.cmake
+++ b/Code/Mantid/Build/CMake/FindQwt.cmake
@@ -9,7 +9,7 @@
 find_path ( QWT_INCLUDE_DIR qwt.h 
             PATHS /opt/include /usr/local/include /usr/include ${CMAKE_INCLUDE_PATH}
             PATH_SUFFIXES qwt5 qwt5-qt4 qwt-qt4 qwt )
-find_library ( QWT_LIBRARY NAMES qwt5-qt4 qwt-qt4 qwt )
+find_library ( QWT_LIBRARY NAMES qwt5-qt4 qwt-qt4 qwt5 qwt )
 find_library ( QWT_LIBRARY_DEBUG qwtd )
 
 # in REQUIRED mode: terminate if one of the above find commands failed
diff --git a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake
index 760ecee5a349f34017f6cb804bf8eee8f58b671f..9a642a4d49bb2faf4bc79f8b623b99ef2d260d6e 100644
--- a/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake
+++ b/Code/Mantid/Build/CMake/LinuxPackageScripts.cmake
@@ -26,21 +26,6 @@ set ( CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/${LIB_DIR};${CMAKE_INSTALL_PRE
 # Required for Fedora >= 18 and RHEL >= 7
 set ( CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /opt /usr/share/applications /usr/share/pixmaps )
 
-###########################################################################
-# LD_PRELOAD TCMalloc
-###########################################################################
-# User systems will only have the libraries and not the symbolic link
-# so we must set the preload to the versioned library. We will assume it is
-# in the same location as the system that the package was built on
-if ( TCMALLOC_LIBRARIES )
-  execute_process ( COMMAND readlink --no-newline --canonicalize-existing ${TCMALLOC_LIBRARIES}
-                    OUTPUT_VARIABLE TCMALLOC_PRELOAD
-                    RESULT_VARIABLE READLINK_RESULT )
-  if ( READLINK_RESULT EQUAL 1 )
-    message ( FATAL_ERROR "Unable to find real file that tcmalloc symlink, ${TCMALLOC_LIBRARIES}, points to." )
-  endif()
-endif()
-
 ###########################################################################
 # Environment scripts (profile.d)
 ###########################################################################
@@ -151,6 +136,12 @@ configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in
 # Needs to be executable
 execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/launch_mantidplot.sh"
                   OUTPUT_QUIET ERROR_QUIET )
+configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in 
+                 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython @ONLY )
+# Needs to be executable
+execute_process ( COMMAND "chmod" "+x" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/mantidpython"
+                  OUTPUT_QUIET ERROR_QUIET )
+
 # Package version
 set ( MANTIDPLOT_EXEC MantidPlot_exe )
 configure_file ( ${CMAKE_MODULE_PATH}/Packaging/launch_mantidplot.sh.in 
@@ -161,3 +152,11 @@ install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/launch_mantidplot.sh.install
           GROUP_EXECUTE GROUP_READ
           WORLD_EXECUTE WORLD_READ
 )
+configure_file ( ${CMAKE_MODULE_PATH}/Packaging/mantidpython.in 
+                 ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install @ONLY )
+install ( FILES ${CMAKE_CURRENT_BINARY_DIR}/mantidpython.install
+          DESTINATION ${BIN_DIR} RENAME mantidpython
+          PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ
+          GROUP_EXECUTE GROUP_READ
+          WORLD_EXECUTE WORLD_READ
+)
diff --git a/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in b/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in
index 33556e1b1c79e6836742bad3bab57bd42a17a49a..f26493a133120275e42f77fd51c4c9601d39ca29 100644
--- a/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in
+++ b/Code/Mantid/Build/CMake/Packaging/launch_mantidplot.sh.in
@@ -9,7 +9,7 @@ SCRIPTFILE=$(readlink -f "$0")
 INSTALLDIR=$(echo $SCRIPTFILE | sed -r -e 's|^(.*)/(.*)$|\1|g') #.* is greedy and eats up until the final slash
 
 # Define extra libraries and load paths
-LOCAL_PRELOAD=@TCMALLOC_PRELOAD@
+LOCAL_PRELOAD=`readlink --no-newline --canonicalize-existing @TCMALLOC_LIBRARIES@`
 if [ -n "${LD_PRELOAD}" ]; then
     LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD}
 fi
@@ -21,4 +21,6 @@ else
 fi
 
 # Launch
-LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt @WRAPPER_PREFIX@$INSTALLDIR/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@
+LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \
+    LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt \
+    @WRAPPER_PREFIX@$INSTALLDIR/@MANTIDPLOT_EXEC@ $*@WRAPPER_POSTFIX@
diff --git a/Code/Mantid/Build/CMake/Packaging/mantidpython.in b/Code/Mantid/Build/CMake/Packaging/mantidpython.in
new file mode 100755
index 0000000000000000000000000000000000000000..55cbe36924e81bbfc5e36caebaf5033faa3939de
--- /dev/null
+++ b/Code/Mantid/Build/CMake/Packaging/mantidpython.in
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Launch Mantidplot using any necessary LD_PRELOAD or software collection behaviour
+#
+# Script is configured by CMake
+
+# Find out where we are
+SCRIPTFILE=$(readlink -f "$0")
+INSTALLDIR=$(echo $SCRIPTFILE | sed -r -e 's|^(.*)/(.*)$|\1|g') #.* is greedy and eats up until the final slash
+IPYTHON=$(command -v ipython)
+
+# Define extra libraries and load paths
+LOCAL_PRELOAD=`readlink --no-newline --canonicalize-existing @TCMALLOC_LIBRARIES@`
+if [ -n "${LD_PRELOAD}" ]; then
+    LOCAL_PRELOAD=${LOCAL_PRELOAD}:${LD_PRELOAD}
+fi
+LOCAL_LDPATH=@EXTRA_LDPATH@:${LD_LIBRARY_PATH}
+if [ -z "${TCMALLOC_RELEASE_RATE}" ]; then
+    TCM_RELEASE=10000
+else
+    TCM_RELEASE=${TCMALLOC_RELEASE_RATE}
+fi
+
+# Define extra libraries for python
+LOCAL_PYTHONPATH=@WRAPPER_PREFIX@$INSTALLDIR
+if [ -n "${PYTHONPATH}" ]; then
+    LOCAL_PYTHONPATH=${LOCAL_PYTHONPATH}:${PYTHONPATH}
+fi
+
+# Launch
+LD_PRELOAD=${LOCAL_PRELOAD} TCMALLOC_RELEASE_RATE=${TCM_RELEASE} \
+    LD_LIBRARY_PATH=${LOCAL_LDPATH} QT_API=pyqt \
+    PYTHONPATH=${LOCAL_PYTHONPATH} \
+    ${IPYTHON} $*@WRAPPER_POSTFIX@
diff --git a/Code/Mantid/Build/Jenkins/buildscript b/Code/Mantid/Build/Jenkins/buildscript
index 40f6003fab63ebfa08448f47edca10bb313ac689..bf9df07b22372756d094a2184f3d54b6f09eda26 100755
--- a/Code/Mantid/Build/Jenkins/buildscript
+++ b/Code/Mantid/Build/Jenkins/buildscript
@@ -85,6 +85,10 @@ else
   SCL_ON_RHEL6="eval"
 fi
 
+if [[ ${NODE_LABELS} == *rhel7* ]]; then
+  ON_RHEL7=true
+fi
+
 ###############################################################################
 # Check job requirements from the name
 ###############################################################################
@@ -212,6 +216,6 @@ fi
 # Run the system tests on RHEL6 when doing a pull request build. Run
 # from a package to have at least one Linux checks it install okay
 ###############################################################################
-if [[ "${ON_RHEL6}" == true ]] && [[ ${JOB_NAME} == *pull_requests* ]]; then
+if [[ "${ON_RHEL7}" == true ]] && [[ ${JOB_NAME} == *pull_requests* ]]; then
   $SCRIPT_DIR/systemtests
 fi
diff --git a/Code/Mantid/Build/Jenkins/buildscript.bat b/Code/Mantid/Build/Jenkins/buildscript.bat
index ce0d2ca69f03e0da6f8139da31afbf0e3aa86df6..cda8a6cb7d61c4189aaa12233f29907bd068db90 100755
--- a/Code/Mantid/Build/Jenkins/buildscript.bat
+++ b/Code/Mantid/Build/Jenkins/buildscript.bat
@@ -87,7 +87,7 @@ if not "%JOB_NAME%"=="%JOB_NAME:relwithdbg=%" (
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: Update the PATH so that we can find everything
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-set PATH=%WORKSPACE%\Code\Third_Party\lib\win64;%WORKSPACE%\Code\Third_Party\lib\win64\Python27;%PARAVIEW_DIR%\bin\%BUILD_CONFIG%;%PATH%
+set PATH=%WORKSPACE%\Code\Third_Party\lib\win64;%WORKSPACE%\Code\Third_Party\lib\win64\Python27;%WORKSPACE%\Code\Third_Party\lib\win64\mingw;%PARAVIEW_DIR%\bin\%BUILD_CONFIG%;%PATH%
 
 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 :: CMake configuration
diff --git a/Code/Mantid/CMakeLists.txt b/Code/Mantid/CMakeLists.txt
index a055859f89e134e210001db843e9a22b293919e6..37e8763843f062003919fdb4f80a036305db62e8 100644
--- a/Code/Mantid/CMakeLists.txt
+++ b/Code/Mantid/CMakeLists.txt
@@ -121,6 +121,7 @@ set( DOCS_BUILDDIR ${CMAKE_BINARY_DIR}/docs )
 # Framework Build options
 set ( CXXTEST_SINGLE_LOGFILE CACHE BOOL "Switch to have the tests for each package run together")
 set ( CXXTEST_ADD_PERFORMANCE OFF CACHE BOOL "Switch to add Performance tests to the list of tests run by ctest?")
+set ( ENABLE_OPENCASCADE ON CACHE BOOL "Enable OpenCascade-based 3D visualisation")
 
 add_subdirectory ( Framework )
 
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h
index c777f47dc80897476da07fd9d12165117956a89a..f3a34da22c9ed3bdeb42ae52bb2592e1fd1f0871 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionDomain1D.h
@@ -52,6 +52,8 @@ public:
   double operator[](size_t i) const { return m_data[i]; }
   /// Get a pointer to i-th value
   const double *getPointerAt(size_t i) const { return m_data + i; }
+  /// Convert to a vector
+  std::vector<double> toVector() const;
 
 protected:
   /// Protected constructor, shouldn't be created directly. Use
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h
index 44e32826ad6fd6bf94e3b69629a17471861247bf..836f1aff61ac82dfb7d12206a193203d1ea1b6a0 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/FunctionValues.h
@@ -103,6 +103,9 @@ public:
   /// instance.
   void setFitDataFromCalculated(const FunctionValues &values);
 
+  /// Return the calculated values as a vector
+  std::vector<double> toVector() const {return m_calculated;}
+
 protected:
   /// Copy calculated values to a buffer
   /// @param to :: Pointer to the buffer
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h
index 723ce3d7a8f8da076bb032444b5b61e7d8df89eb..b02beb1fa264e356ce810fcf9a8a8dc69582a6fc 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDEventWorkspace.h
@@ -51,11 +51,6 @@ public:
   virtual void getBoxes(std::vector<API::IMDNode *> &boxes, size_t maxDepth,
                         bool leafOnly) = 0;
 
-  /// TODO: The meaning of this method have changed! Helper method that makes a
-  /// table workspace with some box data
-  // virtual Mantid::API::ITableWorkspace_sptr makeBoxTable(size_t start, size_t
-  // num) = 0;
-
   /// @return true if the workspace is file-backed
   virtual bool isFileBacked() const = 0;
 
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
index 942e14af6ee2816a927fee8c6b1fa77f55feefc3..cc7c014a382a07ff9bf27bc15cebb1f03703d5b2 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDHistoWorkspace.h
@@ -89,7 +89,7 @@ public:
   virtual double &operator[](const size_t &index) = 0;
 
   virtual void setCoordinateSystem(
-      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) = 0;
+      const Kernel::SpecialCoordinateSystem coordinateSystem) = 0;
 
   virtual boost::shared_ptr<IMDHistoWorkspace> clone() const = 0;
 
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h
index c3bebd3e4f1d700f685eace018759928faf90eb9..35203727852cbdc1dbf5deed99311f12fe2abd61 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/IMDWorkspace.h
@@ -67,8 +67,7 @@ enum MDNormalization {
  Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
 
-class MANTID_API_DLL IMDWorkspace : public Workspace,
-                                    public Mantid::API::MDGeometry {
+class MANTID_API_DLL IMDWorkspace : public Workspace, public API::MDGeometry {
 public:
   IMDWorkspace();
   IMDWorkspace(const IMDWorkspace &other);
@@ -119,11 +118,11 @@ public:
   /// Clear existing masks
   virtual void clearMDMasking() = 0;
   ///
-  virtual Mantid::Kernel::SpecialCoordinateSystem
+  virtual Kernel::SpecialCoordinateSystem
   getSpecialCoordinateSystem() const = 0;
   /// if a workspace was filebacked, this should clear file-based status, delete
   /// file-based information and close related files.
-  virtual void clearFileBacked(bool /* loadFileContentsToMemory*/){};
+  virtual void clearFileBacked(bool /* loadFileContentsToMemory*/) {}
   /// this is the method to build table workspace from any workspace. It does
   /// not have much sence and may be placed here erroneously
   virtual ITableWorkspace_sptr makeBoxTable(size_t /*start*/, size_t /* num*/) {
diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h b/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h
index 15bd48bf8b94bfb00d57f11f577d09a928e7a009..03e115047abbae8fb93df685ecc415521e1ed13b 100644
--- a/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h
+++ b/Code/Mantid/Framework/API/inc/MantidAPI/IPeaksWorkspace.h
@@ -55,10 +55,6 @@ public:
   /// Destructor
   virtual ~IPeaksWorkspace();
 
-  // boost::shared_ptr<IPeaksWorkspace> clone() = 0;
-  // void appendFile( std::string filename, Mantid::Geometry::Instrument_sptr
-  // inst) = 0;
-
   //---------------------------------------------------------------------------------------------
   /** @return the number of peaks
    */
@@ -99,14 +95,15 @@ public:
 
   //---------------------------------------------------------------------------------------------
   /** Create an instance of a Peak
-   * @param QLabFrame :: Q of the center of the peak in the lab frame, in reciprocal space
-   * @param detectorDistance :: Optional distance between the sample and the detector. Calculated if not provided.
+   * @param QLabFrame :: Q of the center of the peak in the lab frame, in
+   * reciprocal space
+   * @param detectorDistance :: Optional distance between the sample and the
+   * detector. Calculated if not provided.
    * @return a pointer to a new Peak object.
    */
   virtual IPeak *createPeak(Mantid::Kernel::V3D QLabFrame,
                             boost::optional<double> detectorDistance) const = 0;
 
-
   /**
    * Create an instance of a peak using a V3D
    * @param HKL V3D
@@ -136,16 +133,16 @@ public:
    * @param coordinateSystem : Special Q3D coordinate system to use.
    */
   virtual void setCoordinateSystem(
-      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) = 0;
-
+      const Kernel::SpecialCoordinateSystem coordinateSystem) = 0;
   //---------------------------------------------------------------------------------------------
   /**
    * Get the special coordinate system.
    * @returns special Q3D coordinate system to use being used by this
    * PeaksWorkspace object. Probably the one the workspace was generated with.
    */
-  virtual Mantid::Kernel::SpecialCoordinateSystem
+  virtual Kernel::SpecialCoordinateSystem
   getSpecialCoordinateSystem() const = 0;
+
   virtual std::vector<std::pair<std::string, std::string>>
   peakInfo(Kernel::V3D QFrame, bool labCoords) const = 0;
   virtual int peakInfoNumber(Kernel::V3D qLabFrame, bool labCoords) const = 0;
diff --git a/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp b/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp
index 14c7f2e2bc121a1c38624b97ffe303895b36a6ad..0de9abdc6c76f30ec2a3a07848f995f6d6155135 100644
--- a/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp
+++ b/Code/Mantid/Framework/API/src/FunctionDomain1D.cpp
@@ -7,6 +7,16 @@
 namespace Mantid {
 namespace API {
 
+/// Convert to a vector
+std::vector<double> FunctionDomain1D::toVector() const 
+{
+  std::vector<double> res;
+  if ( m_n > 0 ){
+    res.assign(m_data, m_data+m_n);
+  }
+  return res;
+}
+
 /**
   * Create a domain from a vector.
   * @param xvalues :: Vector with function arguments to be copied from.
diff --git a/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp
index 8b028f620da9c66aa46453d8493847d35becba75..6f63f26bff51d45929ce599e7a73e14ccf3349b4 100644
--- a/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp
+++ b/Code/Mantid/Framework/Algorithms/src/Stitch1DMany.cpp
@@ -221,9 +221,9 @@ void Stitch1DMany::exec() {
         outName += wsName;
       }
 
-      IAlgorithm_sptr stitchAlg =
-          AlgorithmManager::Instance().create("Stitch1DMany");
+      IAlgorithm_sptr stitchAlg = createChildAlgorithm("Stitch1DMany");
       stitchAlg->initialize();
+      stitchAlg->setAlwaysStoreInADS(true);
       stitchAlg->setProperty("InputWorkspaces", toProcess);
       stitchAlg->setProperty("OutputWorkspace", outName);
       stitchAlg->setProperty("StartOverlaps", m_startOverlaps);
@@ -247,9 +247,9 @@ void Stitch1DMany::exec() {
 
     const std::string groupName = this->getProperty("OutputWorkspace");
 
-    IAlgorithm_sptr groupAlg =
-        AlgorithmManager::Instance().create("GroupWorkspaces");
+    IAlgorithm_sptr groupAlg = createChildAlgorithm("GroupWorkspaces");
     groupAlg->initialize();
+    groupAlg->setAlwaysStoreInADS(true);
     groupAlg->setProperty("InputWorkspaces", toGroup);
     groupAlg->setProperty("OutputWorkspace", groupName);
     groupAlg->execute();
diff --git a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt
index 6486b1f2e157235b1fcc2275df15d22d81eef0d9..7b1cd0ed1c9c20f23301695238878afc433d8ad0 100644
--- a/Code/Mantid/Framework/CurveFitting/CMakeLists.txt
+++ b/Code/Mantid/Framework/CurveFitting/CMakeLists.txt
@@ -32,6 +32,7 @@ set ( SRC_FILES
 	src/DiffSphere.cpp
 	src/DynamicKuboToyabe.cpp
 	src/EndErfc.cpp
+	src/EstimatePeakErrors.cpp
 	src/ExpDecay.cpp
 	src/ExpDecayMuon.cpp
 	src/ExpDecayOsc.cpp
@@ -141,6 +142,7 @@ set ( INC_FILES
 	inc/MantidCurveFitting/DllConfig.h
 	inc/MantidCurveFitting/DynamicKuboToyabe.h
 	inc/MantidCurveFitting/EndErfc.h
+    inc/MantidCurveFitting/EstimatePeakErrors.h
 	inc/MantidCurveFitting/ExpDecay.h
 	inc/MantidCurveFitting/ExpDecayMuon.h
 	inc/MantidCurveFitting/ExpDecayOsc.h
@@ -245,6 +247,7 @@ set ( TEST_FILES
 	DiffSphereTest.h
 	DynamicKuboToyabeTest.h
 	EndErfcTest.h
+    EstimatePeakErrorsTest.h
 	ExpDecayMuonTest.h
 	ExpDecayOscTest.h
 	ExpDecayTest.h
diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe76f6ba7686c0a4caef39545f8478888f456def
--- /dev/null
+++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/EstimatePeakErrors.h
@@ -0,0 +1,50 @@
+#ifndef MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_
+#define MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_
+
+#include "MantidAPI/Algorithm.h"
+
+namespace Mantid {
+namespace CurveFitting {
+//---------------------------------------------------------------------------
+/**
+
+Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
+National Laboratory & European Spallation Source
+
+This file is part of Mantid.
+
+Mantid is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+Mantid is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+File change history is stored at: <https://github.com/mantidproject/mantid>
+Code Documentation is available at: <http://doxygen.mantidproject.org>
+ */
+class DLLExport EstimatePeakErrors : public API::Algorithm {
+public:
+  EstimatePeakErrors();
+
+  const std::string name() const;
+  virtual const std::string summary() const ;
+
+  int version() const;
+  const std::string category() const;
+
+private:
+  void init();
+  void exec();
+};
+
+} // namespace CurveFitting
+} // namespace Mantid
+
+#endif /* MANTID_CURVEFITTING_ESTIMATEPEAKERRORS_H_ */
diff --git a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h
index 4be954bd466e06e349884a681bcfec483d2fb3a8..98f69c7cc7ca1742cd80ed40a71c392b6f37659e 100644
--- a/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h
+++ b/Code/Mantid/Framework/CurveFitting/inc/MantidCurveFitting/GSLMatrix.h
@@ -4,6 +4,8 @@
 #include "MantidCurveFitting/DllConfig.h"
 #include "MantidCurveFitting/GSLVector.h"
 
+#include "MantidKernel/Matrix.h"
+
 #include <gsl/gsl_matrix.h>
 #include <gsl/gsl_blas.h>
 #include <gsl/gsl_linalg.h>
@@ -97,7 +99,6 @@ Code Documentation is available at: <http://doxygen.mantidproject.org>
 class MANTID_CURVEFITTING_DLL GSLMatrix {
   /// The pointer to the GSL matrix
   gsl_matrix *m_matrix;
-
 public:
   /// Constructor
   GSLMatrix() : m_matrix(NULL) {}
@@ -109,11 +110,47 @@ public:
   }
 
   /// Copy constructor
+  /// @param M :: The other matrix.
   GSLMatrix(const GSLMatrix &M) {
     m_matrix = gsl_matrix_alloc(M.size1(), M.size2());
     gsl_matrix_memcpy(m_matrix, M.gsl());
   }
 
+  /// Create a submatrix. A submatrix is a view into the parent matrix.
+  /// Lifetime of a submatrix cannot exceed the lifetime of the parent.
+  /// @param M :: The parent matrix.
+  /// @param row :: The first row in the submatrix.
+  /// @param col :: The first column in the submatrix.
+  /// @param nRows :: The number of rows in the submatrix.
+  /// @param nCols :: The number of columns in the submatrix.
+  GSLMatrix(const GSLMatrix &M, size_t row, size_t col, size_t nRows, size_t nCols) {
+    if ( row + nRows > M.size1() || col + nCols > M.size2() )
+    {
+      throw std::runtime_error("Submatrix exceeds matrix size.");
+    }
+    auto view = gsl_matrix_const_submatrix(M.gsl(), row, col, nRows, nCols);
+    m_matrix = gsl_matrix_alloc(nRows, nCols);
+    gsl_matrix_memcpy(m_matrix, &view.matrix);
+  }
+
+  /// Constructor
+  /// @param M :: A matrix to copy.
+  GSLMatrix(const Kernel::Matrix<double>& M) {
+    m_matrix = gsl_matrix_alloc(M.numRows(), M.numCols());
+    for(size_t i = 0; i < size1(); ++i)
+    for(size_t j = 0; j < size2(); ++j){
+      set(i,j, M[i][j]);
+    }
+  }
+
+  /// Create this matrix from a product of two other matrices
+  /// @param mult2 :: Matrix multiplication helper object.
+  GSLMatrix(const GSLMatrixMult2 &mult2) : m_matrix(NULL) {*this = mult2;}
+
+  /// Create this matrix from a product of three other matrices
+  /// @param mult3 :: Matrix multiplication helper object.
+  GSLMatrix(const GSLMatrixMult3 &mult3) : m_matrix(NULL) {*this = mult3;}
+
   /// Destructor.
   ~GSLMatrix() {
     if (m_matrix) {
diff --git a/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp b/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b2d70ca84b52ce3c13fe7dd625ac698e10df1997
--- /dev/null
+++ b/Code/Mantid/Framework/CurveFitting/src/EstimatePeakErrors.cpp
@@ -0,0 +1,169 @@
+#include "MantidCurveFitting/EstimatePeakErrors.h"
+#include "MantidCurveFitting/GSLMatrix.h"
+#include "MantidCurveFitting/PeakParameterFunction.h"
+
+#include "MantidAPI/CompositeFunction.h"
+#include "MantidAPI/FunctionProperty.h"
+#include "MantidAPI/IPeakFunction.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/TableRow.h"
+
+#include <boost/lexical_cast.hpp>
+
+namespace Mantid {
+namespace CurveFitting {
+using namespace API;
+using namespace Kernel;
+using namespace std;
+
+// Subscription
+DECLARE_ALGORITHM(EstimatePeakErrors);
+
+//--------------------------------------------------------------------------------------------------------
+// Public members
+//--------------------------------------------------------------------------------------------------------
+
+/// Default constructor
+EstimatePeakErrors::EstimatePeakErrors() : Algorithm() {}
+
+/// Summary of algorithms purpose
+const std::string EstimatePeakErrors::summary() const {
+  return "Calculates error estimates for peak parameters: "
+         "centre, height, FWHM and intensity.";
+}
+
+const std::string EstimatePeakErrors::name() const {
+  return "EstimatePeakErrors";
+}
+
+int EstimatePeakErrors::version() const { return 1; }
+
+const std::string EstimatePeakErrors::category() const {
+  return "Optimization";
+}
+
+//--------------------------------------------------------------------------------------------------------
+// Private members
+//--------------------------------------------------------------------------------------------------------
+namespace {
+
+/// Calculate a Jacobian of transformations from the normal function's
+/// parameters to the 4 general peak parameters: centre, height, FWHM and
+/// intensity (integral).
+/// Also calculate the values for the peak parameters.
+/// @param peak :: The function for which the Jacobian to be calculated.
+/// @param centre :: Output receiving value of peak centre.
+/// @param height :: Output receiving value of peak height.
+/// @param fwhm :: Output receiving value of peak FWHM.
+/// @param intensity :: Output receiving value of peak intensity.
+GSLMatrix makeJacobian(IPeakFunction &peak, double &centre, double &height,
+                       double &fwhm, double &intensity) {
+  GSLMatrix jacobian(4, peak.nParams());
+  centre = peak.centre();
+  height = peak.height();
+  fwhm = peak.fwhm();
+  intensity = peak.intensity();
+  for (size_t ip = 0; ip < peak.nParams(); ++ip) {
+    double p = peak.getParameter(ip);
+    double dp = 1e-9;
+    if (p != 0.0) {
+      dp *= p;
+    }
+    peak.setParameter(ip, p + dp);
+    jacobian.set(0, ip, (peak.centre() - centre) / dp);
+    jacobian.set(1, ip, (peak.height() - height) / dp);
+    jacobian.set(2, ip, (peak.fwhm() - fwhm) / dp);
+    jacobian.set(3, ip, (peak.intensity() - intensity) / dp);
+    peak.setParameter(ip, p);
+  }
+  return jacobian;
+}
+
+/// Calculate the errors for a peak and add them to the result table.
+/// @param peak :: A function for which errors are calculated.
+/// @param results :: The table with results
+/// @param covariance :: The covariance matrix for the parameters of the peak.
+/// @param prefix :: A prefix for the parameter names.
+void calculatePeakValues(IPeakFunction &peak, ITableWorkspace &results,
+                         const GSLMatrix covariance,
+                         const std::string &prefix) {
+  double centre, height, fwhm, intensity;
+  GSLMatrix J = makeJacobian(peak, centre, height, fwhm, intensity);
+  // CHECK_OUT_GSL_MATRIX("J=", J);
+
+  GSLMatrix JCJ = J * covariance * Tr(J);
+  // CHECK_OUT_GSL_MATRIX("JCJ=", JCJ);
+
+  TableRow row = results.appendRow();
+  row << prefix + "Centre" << centre << sqrt(JCJ.get(0, 0));
+  row = results.appendRow();
+  row << prefix + "Height" << height << sqrt(JCJ.get(1, 1));
+  row = results.appendRow();
+  row << prefix + "FWHM" << fwhm << sqrt(JCJ.get(2, 2));
+  row = results.appendRow();
+  row << prefix + "Intensity" << intensity << sqrt(JCJ.get(3, 3));
+}
+}
+
+/// Initialize
+void EstimatePeakErrors::init() {
+
+  declareProperty(
+      new FunctionProperty("Function"),
+      "Fitting function containing peaks. Must have a covariance matrix attached.");
+
+  declareProperty(
+      new API::WorkspaceProperty<API::ITableWorkspace>(
+          "OutputWorkspace", "", Kernel::Direction::Output),
+      "The name of the TableWorkspace with the output values and errors.");
+}
+
+/// Execute
+void EstimatePeakErrors::exec() {
+
+  IFunction_sptr function = getProperty("Function");
+
+  ITableWorkspace_sptr results =
+      WorkspaceFactory::Instance().createTable("TableWorkspace");
+  results->addColumn("str", "Parameter");
+  results->addColumn("double", "Value");
+  results->addColumn("double", "Error");
+
+  auto matrix = function->getCovarianceMatrix();
+  if ( !matrix )
+  {
+    g_log.warning() << "Function doesn't have covariance matrix." << std::endl;
+    setProperty("OutputWorkspace", results);
+    return;
+  }
+
+  IPeakFunction *peak = dynamic_cast<IPeakFunction *>(function.get());
+
+  if (peak) {
+    GSLMatrix covariance(*matrix);
+    calculatePeakValues(*peak, *results, covariance, "");
+  } else {
+    CompositeFunction *cf = dynamic_cast<CompositeFunction *>(function.get());
+    if (cf) {
+      size_t ip = 0;
+      for (size_t i = 0; i < cf->nFunctions(); ++i) {
+        IFunction *fun = cf->getFunction(i).get();
+        size_t np = fun->nParams();
+        IPeakFunction *peak = dynamic_cast<IPeakFunction *>(fun);
+        if (peak) {
+          std::string prefix = "f" + boost::lexical_cast<std::string>(i) + ".";
+          GSLMatrix covariance(*matrix, ip, ip, np, np);
+          calculatePeakValues(*peak, *results, covariance, prefix);
+        }
+        ip += np;
+      }
+    } else {
+      g_log.warning() << "Function has no peaks." << std::endl;
+    }
+  }
+
+  setProperty("OutputWorkspace", results);
+}
+
+} // namespace CurveFitting
+} // namespace Mantid
diff --git a/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h b/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..c867b424fb49b6b13607c9063a3b231724a7a546
--- /dev/null
+++ b/Code/Mantid/Framework/CurveFitting/test/EstimatePeakErrorsTest.h
@@ -0,0 +1,277 @@
+#ifndef ESTIMATEPEAKERRORSTEST_H_
+#define ESTIMATEPEAKERRORSTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidCurveFitting/EstimatePeakErrors.h"
+
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/MatrixWorkspace.h"
+#include "MantidAPI/FunctionDomain1D.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/FunctionValues.h"
+#include "MantidAPI/IFunction.h"
+#include "MantidAPI/WorkspaceFactory.h"
+
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
+using namespace Mantid;
+using namespace Mantid::API;
+using namespace Mantid::CurveFitting;
+using namespace WorkspaceCreationHelper;
+
+class EstimatePeakErrorsTest : public CxxTest::TestSuite
+{
+public:
+
+  void test_on_Gaussian()
+  {
+    auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2");
+    auto ws = createWorkspace(*fun);
+
+    auto fit = AlgorithmManager::Instance().create("Fit");
+    fit->setProperty("Function",fun);
+    fit->setProperty("InputWorkspace",ws);
+    fit->setProperty("CalcErrors",true);
+    fit->execute();
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 4 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "FWHM" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "Intensity" );
+
+    TS_ASSERT_DELTA( res->cell<double>(0,1), -0.0068, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(1,1), 1.0036, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(2,1), 4.8046, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(3,1), 5.1330, 1e-4 );
+
+    TS_ASSERT_DELTA( res->cell<double>(0,2), 0.7467, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(1,2), 0.3172, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(2,2), 1.7598, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(3,2), 1.6263, 1e-4 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+  void test_on_Gaussian_ties()
+  {
+    auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2,ties=(Sigma=2)");
+    auto ws = createWorkspace(*fun);
+
+    auto fit = AlgorithmManager::Instance().create("Fit");
+    fit->setProperty("Function",fun);
+    fit->setProperty("InputWorkspace",ws);
+    fit->setProperty("CalcErrors",true);
+    fit->execute();
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 4 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "FWHM" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "Intensity" );
+
+    TS_ASSERT_DELTA( res->cell<double>(0,1), -0.0071, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(1,1), 1.0136, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(2,1), 4.7096, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(3,1), 5.0816, 1e-4 );
+
+    TS_ASSERT_DELTA( res->cell<double>(0,2), 0.7327, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(1,2), 0.2625, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(2,2), 0.0000, 1e-14 );
+    TS_ASSERT_DELTA( res->cell<double>(3,2), 1.3164, 1e-4 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+  void test_on_Gaussian_unfitted()
+  {
+    auto fun = FunctionFactory::Instance().createInitialized("name=Gaussian,PeakCentre=0,Height=1,Sigma=2");
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 0 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+
+  void test_on_Lorentzians()
+  {
+    std::string funStr = "name=Lorentzian,Amplitude=10,PeakCentre=-4,FWHM=2;"
+      "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;"
+      "name=FlatBackground,A0=3";
+    auto fun = FunctionFactory::Instance().createInitialized(funStr);
+    auto ws = createWorkspace(*fun);
+
+    auto fit = AlgorithmManager::Instance().create("Fit");
+    fit->setProperty("Function",fun);
+    fit->setProperty("InputWorkspace",ws);
+    fit->setProperty("CalcErrors",true);
+    fit->execute();
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 8 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "f0.Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "f0.Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "f0.FWHM" );
+    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), 9.3859, 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.5969, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(3,2), 2.4468, 1e-4 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(4,0), "f1.Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(5,0), "f1.Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(6,0), "f1.FWHM" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(7,0), "f1.Intensity" );
+
+    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), 9.3838, 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.5530, 1e-4 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+  void test_on_Lorentzians_ties()
+  {
+    std::string funStr = "name=Lorentzian,Amplitude=10,FWHM=2,ties=(PeakCentre=-4);"
+      "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;"
+      "name=FlatBackground,A0=3;ties=(f1.Amplitude=f0.Amplitude)";
+    auto fun = FunctionFactory::Instance().createInitialized(funStr);
+    auto ws = createWorkspace(*fun);
+
+    auto fit = AlgorithmManager::Instance().create("Fit");
+    fit->setProperty("Function",fun);
+    fit->setProperty("InputWorkspace",ws);
+    fit->setProperty("CalcErrors",true);
+    fit->execute();
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 8 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(0,0), "f0.Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(1,0), "f0.Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(2,0), "f0.FWHM" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(3,0), "f0.Intensity" );
+
+    TS_ASSERT_DELTA( res->cell<double>(0,1), -4.0000, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(1,1), 3.1877, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(2,1), 2.0012, 1e-4 );
+    TS_ASSERT_DELTA( res->cell<double>(3,1), 9.3849, 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.2561, 1e-4 );
+
+    TS_ASSERT_EQUALS( res->cell<std::string>(4,0), "f1.Centre" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(5,0), "f1.Height" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(6,0), "f1.FWHM" );
+    TS_ASSERT_EQUALS( res->cell<std::string>(7,0), "f1.Intensity" );
+
+    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), 9.3849, 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>(7,2), 0.0000, 1e-4 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+
+  void test_no_peaks()
+  {
+    std::string funStr = "name=FlatBackground,A0=3";
+    auto fun = FunctionFactory::Instance().createInitialized(funStr);
+    auto ws = createWorkspace(*fun);
+
+    auto fit = AlgorithmManager::Instance().create("Fit");
+    fit->setProperty("Function",fun);
+    fit->setProperty("InputWorkspace",ws);
+    fit->setProperty("CalcErrors",true);
+    fit->execute();
+
+    EstimatePeakErrors alg;
+    alg.initialize();
+    alg.setProperty("Function",fun);
+    alg.setPropertyValue("OutputWorkspace","Errors");
+    alg.execute();
+
+    auto res = AnalysisDataService::Instance().retrieveWS<ITableWorkspace>("Errors");
+    TS_ASSERT_EQUALS( res->rowCount(), 0 );
+
+    AnalysisDataService::Instance().clear();
+  }
+
+private:
+
+  MatrixWorkspace_sptr createWorkspace(const IFunction& fun) const
+  {
+    size_t n = 100;
+    auto ws = WorkspaceFactory::Instance().create("Workspace2D", 1, n, n);
+    FunctionDomain1DVector x(-10,10,n);
+    FunctionValues y(x);
+    std::vector<double> e(n,1.0);
+
+    fun.function(x,y);
+    ws->setX(0,x.toVector());
+    ws->getSpectrum(0)->setData(y.toVector(),e);
+    addNoise(ws,0.1);
+    return ws;
+  }
+
+};
+
+#endif /*CHEBYSHEVTEST_H_*/
diff --git a/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h b/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h
index 9905d55c6e93a4cbd02383d4bc8eae5775e11b2f..0d652bdeb111fdc12567fddc3508b3bf2043481a 100644
--- a/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h
+++ b/Code/Mantid/Framework/CurveFitting/test/GSLMatrixTest.h
@@ -173,6 +173,33 @@ public:
     TS_ASSERT_EQUALS(m.get(1,1), 0.5);
   }
 
+  void test_subMatrix()
+  {
+    GSLMatrix m(4,4);
+    m.set(0,0,0); m.set(0,1,1); m.set(0,2,2); m.set(0,3,3);
+    m.set(1,0,10);m.set(1,1,11);m.set(1,2,12);m.set(1,3,13);
+    m.set(2,0,20);m.set(2,1,21);m.set(2,2,22);m.set(2,3,23);
+    m.set(3,0,30);m.set(3,1,31);m.set(3,2,32);m.set(3,3,33);
+
+    GSLMatrix subm(m, 1,1,2,2 );
+    TS_ASSERT_EQUALS(subm.get(0,0), 11);
+    TS_ASSERT_EQUALS(subm.get(0,1), 12);
+    TS_ASSERT_EQUALS(subm.get(1,0), 21);
+    TS_ASSERT_EQUALS(subm.get(1,1), 22);
+  }
+
+  void test_subMatrix_fail()
+  {
+    GSLMatrix m(4,4);
+    m.set(0,0,0); m.set(0,1,1); m.set(0,2,2); m.set(0,3,3);
+    m.set(1,0,10);m.set(1,1,11);m.set(1,2,12);m.set(1,3,13);
+    m.set(2,0,20);m.set(2,1,21);m.set(2,2,22);m.set(2,3,23);
+    m.set(3,0,30);m.set(3,1,31);m.set(3,2,32);m.set(3,3,33);
+
+    TS_ASSERT_THROWS(
+    GSLMatrix subm(m, 2,2,3,3 ), std::runtime_error);
+  }
+
 };
 
 #endif /*GSLMATRIXTEST_H_*/
diff --git a/Code/Mantid/Framework/DataHandling/CMakeLists.txt b/Code/Mantid/Framework/DataHandling/CMakeLists.txt
index f5fd052bfe041b80ef1d13676f1ade6293aa1aab..af53459069106a5d60fb422bba839acda00fc1a5 100644
--- a/Code/Mantid/Framework/DataHandling/CMakeLists.txt
+++ b/Code/Mantid/Framework/DataHandling/CMakeLists.txt
@@ -465,22 +465,9 @@ endif ()
 # Add to the 'Framework' group in VS
 set_property ( TARGET DataHandling PROPERTY FOLDER "MantidFramework" )
 
-IF (${CMAKE_SYSTEM_NAME} MATCHES "Windows" OR OSX_VERSION VERSION_LESS 10.9)
-	SET (HDF5_DIR "${CMAKE_MODULE_PATH}")
-	find_package ( HDF5 COMPONENTS HL REQUIRED
-				        CONFIGS hdf5-config.cmake )
-ELSE()
-	find_package ( HDF5 COMPONENTS HL REQUIRED )
-ENDIF()
-
-#message (STATUS "HDF5_INCLUDE_DIRS:" ${HDF5_INCLUDE_DIRS})
-#message (STATUS "HDF5_LIBRARIES:" ${HDF5_LIBRARIES})
-
 include_directories ( inc ../Nexus/inc ${HDF5_INCLUDE_DIRS})
-#include_directories ( inc ../Nexus/inc)
 
 target_link_libraries ( DataHandling ${MANTIDLIBS} Nexus ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES})
-#target_link_libraries ( DataHandling ${MANTIDLIBS} Nexus)
 
 # Add the unit tests directory
 add_subdirectory ( test )
diff --git a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp
index 045818331a7eb791ecdb78026e61c278714b5cf7..b8688ae24b9853e727e69c9603c32b3130602e95 100644
--- a/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/DownloadInstrument.cpp
@@ -25,7 +25,7 @@
 #endif
 
 // jsoncpp
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 // std
 #include <fstream>
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp b/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp
index 8eca6314f4b8fc7b1a5b7ca47f970f23723098fc..ffbfaac2167ddb04529f38f1f3adc817d96fd47e 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadNexusProcessed.cpp
@@ -37,6 +37,8 @@
 #include "MantidDataObjects/PeakShapeSphericalFactory.h"
 #include "MantidDataObjects/PeakShapeEllipsoidFactory.h"
 
+#include <nexus/NeXusException.hpp>
+
 namespace Mantid {
 namespace DataHandling {
 
@@ -714,7 +716,8 @@ LoadNexusProcessed::loadEventEntry(NXData &wksp_cls, NXDouble &xbins,
   boost::shared_array<int64_t> indices = indices_data.sharedBuffer();
   // Create all the event lists
   PARALLEL_FOR_NO_WSP_CHECK()
-  for (int64_t j = 0; j < static_cast<int64_t>(m_filtered_spec_idxs.size()); j++) {
+  for (int64_t j = 0; j < static_cast<int64_t>(m_filtered_spec_idxs.size());
+       j++) {
     PARALLEL_START_INTERUPT_REGION
     size_t wi = m_filtered_spec_idxs[j] - 1;
     int64_t index_start = indices[wi];
@@ -754,8 +757,8 @@ LoadNexusProcessed::loadEventEntry(NXData &wksp_cls, NXDouble &xbins,
       }
     }
 
-    progress(progressStart + progressRange *
-             (1.0 / static_cast<double>(numspec)));
+    progress(progressStart +
+             progressRange * (1.0 / static_cast<double>(numspec)));
     PARALLEL_END_INTERUPT_REGION
   }
   PARALLEL_CHECK_INTERUPT_REGION
@@ -1005,8 +1008,8 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
 
   // Get information from all but data group
   std::string parameterStr;
-  // Hop to the right point
-  m_cppFile->openPath(entry.path());
+  // Hop to the right point /mantid_workspace_1
+  m_cppFile->openPath(entry.path()); // This is
   try {
     // This loads logs, sample, and instrument.
     peakWS->loadExperimentInfoNexus(m_cppFile, parameterStr);
@@ -1015,7 +1018,30 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
     g_log.information(e.what());
   }
 
-  // std::vector<API::IPeak*> p;
+  // Coordinates - Older versions did not have the separate field but used a log
+  // value
+  uint32_t loadCoord(0);
+  m_cppFile->openGroup("peaks_workspace", "NXentry");
+  try {
+    m_cppFile->readData("coordinate_system", loadCoord);
+    peakWS->setCoordinateSystem(
+        static_cast<Kernel::SpecialCoordinateSystem>(loadCoord));
+  } catch (::NeXus::Exception &) {
+    // Check for a log value
+    auto logs = peakWS->logs();
+    if (logs->hasProperty("CoordinateSystem")) {
+      auto *prop = dynamic_cast<PropertyWithValue<int> *>(
+          logs->getProperty("CoordinateSystem"));
+      if (prop) {
+        int value((*prop)());
+        peakWS->setCoordinateSystem(
+            static_cast<Kernel::SpecialCoordinateSystem>(value));
+      }
+    }
+  }
+  // peaks_workspace
+  m_cppFile->closeGroup();
+
   for (int r = 0; r < numberPeaks; r++) {
     Kernel::V3D v3d;
     v3d[2] = 1.0;
@@ -1137,9 +1163,12 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
       // Read shape information
       using namespace Mantid::DataObjects;
 
-      PeakShapeFactory_sptr peakFactoryEllipsoid = boost::make_shared<PeakShapeEllipsoidFactory>();
-      PeakShapeFactory_sptr peakFactorySphere = boost::make_shared<PeakShapeSphericalFactory>();
-      PeakShapeFactory_sptr peakFactoryNone = boost::make_shared<PeakNoShapeFactory>();
+      PeakShapeFactory_sptr peakFactoryEllipsoid =
+          boost::make_shared<PeakShapeEllipsoidFactory>();
+      PeakShapeFactory_sptr peakFactorySphere =
+          boost::make_shared<PeakShapeSphericalFactory>();
+      PeakShapeFactory_sptr peakFactoryNone =
+          boost::make_shared<PeakNoShapeFactory>();
 
       peakFactoryEllipsoid->setSuccessor(peakFactorySphere);
       peakFactorySphere->setSuccessor(peakFactoryNone);
@@ -1157,16 +1186,16 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
         boost::trim_right(shapeJSON);
 
         // Make the shape
-        Mantid::Geometry::PeakShape* peakShape = peakFactoryEllipsoid->create(shapeJSON);
+        Mantid::Geometry::PeakShape *peakShape =
+            peakFactoryEllipsoid->create(shapeJSON);
 
         // Set the shape
         peakWS->getPeak(i).setPeakShape(peakShape);
-
       }
     }
   }
 
-return boost::static_pointer_cast<API::Workspace>(peakWS);
+  return boost::static_pointer_cast<API::Workspace>(peakWS);
 }
 
 //-------------------------------------------------------------------------------------------------
@@ -1179,18 +1208,15 @@ return boost::static_pointer_cast<API::Workspace>(peakWS);
  * @param progressRange progress made after loading an entry
  * @param mtd_entry Nexus entry for "mantid_workspace_..."
  * @param xlength bins in the "X" axis (xbins)
- * @param workspaceType Takes values like "Workspace2D", "RebinnedOutput", etc.
+ * @param workspaceType Takes values like "Workspace2D", "RebinnedOutput",
+ *etc.
  *
  * @return workspace object containing loaded data
  */
-API::MatrixWorkspace_sptr
-LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
-                                      NXDouble &xbins,
-                                      const double &progressStart,
-                                      const double &progressRange,
-                                      const NXEntry &mtd_entry,
-                                      const int xlength,
-                                      std::string &workspaceType) {
+API::MatrixWorkspace_sptr LoadNexusProcessed::loadNonEventEntry(
+    NXData &wksp_cls, NXDouble &xbins, const double &progressStart,
+    const double &progressRange, const NXEntry &mtd_entry, const int xlength,
+    std::string &workspaceType) {
   // Filter the list of spectra to process, applying min/max/list options
   NXDataSetTyped<double> data = wksp_cls.openDoubleData();
   int64_t nchannels = data.dim1();
@@ -1212,8 +1238,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
 
   API::MatrixWorkspace_sptr local_workspace =
       boost::dynamic_pointer_cast<API::MatrixWorkspace>(
-         WorkspaceFactory::Instance().create(workspaceType, total_specs, xlength,
-                                             nchannels));
+          WorkspaceFactory::Instance().create(workspaceType, total_specs,
+                                              xlength, nchannels));
   try {
     local_workspace->setTitle(mtd_entry.getString("title"));
   } catch (std::runtime_error &) {
@@ -1264,16 +1290,16 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
 
         for (; hist_index < read_stop;) {
           progress(progressBegin +
-                   progressScaler * static_cast<double>(hist_index) /
-                   static_cast<double>(read_stop),
+                       progressScaler * static_cast<double>(hist_index) /
+                           static_cast<double>(read_stop),
                    "Reading workspace data...");
           loadBlock(data, errors, fracarea, hasFracArea, blocksize, nchannels,
                     hist_index, wsIndex, local_workspace);
         }
         int64_t finalblock = m_spec_max - 1 - read_stop;
         if (finalblock > 0) {
-          loadBlock(data, errors, fracarea, hasFracArea, finalblock,
-                    nchannels, hist_index, wsIndex, local_workspace);
+          loadBlock(data, errors, fracarea, hasFracArea, finalblock, nchannels,
+                    hist_index, wsIndex, local_workspace);
         }
       }
       // if spectrum list property is set read each spectrum separately by
@@ -1283,8 +1309,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
         for (; itr != m_spec_list.end(); ++itr) {
           int64_t specIndex = (*itr) - 1;
           progress(progressBegin +
-                   progressScaler * static_cast<double>(specIndex) /
-                   static_cast<double>(m_spec_list.size()),
+                       progressScaler * static_cast<double>(specIndex) /
+                           static_cast<double>(m_spec_list.size()),
                    "Reading workspace data...");
           loadBlock(data, errors, fracarea, hasFracArea,
                     static_cast<int64_t>(1), nchannels, specIndex, wsIndex,
@@ -1294,8 +1320,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
     } else {
       for (; hist_index < read_stop;) {
         progress(progressBegin +
-                 progressScaler * static_cast<double>(hist_index) /
-                 static_cast<double>(read_stop),
+                     progressScaler * static_cast<double>(hist_index) /
+                         static_cast<double>(read_stop),
                  "Reading workspace data...");
         loadBlock(data, errors, fracarea, hasFracArea, blocksize, nchannels,
                   hist_index, wsIndex, local_workspace);
@@ -1322,8 +1348,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
 
         for (; hist_index < read_stop;) {
           progress(progressBegin +
-                   progressScaler * static_cast<double>(hist_index) /
-                   static_cast<double>(read_stop),
+                       progressScaler * static_cast<double>(hist_index) /
+                           static_cast<double>(read_stop),
                    "Reading workspace data...");
           loadBlock(data, errors, fracarea, hasFracArea, xbins, blocksize,
                     nchannels, hist_index, wsIndex, local_workspace);
@@ -1340,8 +1366,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
         for (; itr != m_spec_list.end(); ++itr) {
           int64_t specIndex = (*itr) - 1;
           progress(progressBegin +
-                   progressScaler * static_cast<double>(specIndex) /
-                   static_cast<double>(read_stop),
+                       progressScaler * static_cast<double>(specIndex) /
+                           static_cast<double>(read_stop),
                    "Reading workspace data...");
           loadBlock(data, errors, fracarea, hasFracArea, xbins, 1, nchannels,
                     specIndex, wsIndex, local_workspace);
@@ -1350,8 +1376,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
     } else {
       for (; hist_index < read_stop;) {
         progress(progressBegin +
-                 progressScaler * static_cast<double>(hist_index) /
-                 static_cast<double>(read_stop),
+                     progressScaler * static_cast<double>(hist_index) /
+                         static_cast<double>(read_stop),
                  "Reading workspace data...");
         loadBlock(data, errors, fracarea, hasFracArea, xbins, blocksize,
                   nchannels, hist_index, wsIndex, local_workspace);
@@ -1372,7 +1398,8 @@ LoadNexusProcessed::loadNonEventEntry(NXData &wksp_cls,
  *
  * @param root :: The opened root node
  * @param entry_name :: The entry name
- * @param progressStart :: The percentage value to start the progress reporting
+ * @param progressStart :: The percentage value to start the progress
+ *reporting
  * for this entry
  * @param progressRange :: The percentage range that the progress reporting
  * should cover
@@ -1457,7 +1484,8 @@ API::Workspace_sptr LoadNexusProcessed::loadEntry(NXRoot &root,
       label->setLabel(ax.attributes("caption"), ax.attributes("label"));
     }
 
-    // If this doesn't throw then it is a numeric access so grab the data so we
+    // If this doesn't throw then it is a numeric access so grab the data so
+    // we
     // can set it later
     axis2.load();
     if (static_cast<size_t>(axis2.size()) == nspectra + 1)
@@ -1593,7 +1621,8 @@ void LoadNexusProcessed::readInstrumentGroup(
 
 //-------------------------------------------------------------------------------------------------
 /**
- * Loads the information contained in non-Spectra (ie, Text or Numeric) axis in
+ * Loads the information contained in non-Spectra (ie, Text or Numeric) axis
+ * in
  * the Nexus
  * file into the workspace.
  * @param local_workspace :: pointer to workspace object
@@ -1713,7 +1742,8 @@ void LoadNexusProcessed::getWordsInString(const std::string &words4,
 
 //-------------------------------------------------------------------------------------------------
 /**
- * Read the bin masking information from the mantid_workspace_i/workspace group.
+ * Read the bin masking information from the mantid_workspace_i/workspace
+ * group.
  * @param wksp_cls :: The data group
  * @param local_workspace :: The workspace to read into
  */
@@ -1742,7 +1772,8 @@ LoadNexusProcessed::readBinMasking(NXData &wksp_cls,
 }
 
 /**
- * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given
+ * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a
+ * given
  * blocksize. This assumes that the
  * xbins have alread been cached
  * @param data :: The NXDataSet object of y values
@@ -1797,7 +1828,8 @@ void LoadNexusProcessed::loadBlock(NXDataSetTyped<double> &data,
 }
 
 /**
- * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given
+ * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a
+ * given
  * blocksize. This assumes that the
  * xbins have alread been cached
  * @param data :: The NXDataSet object of y values
@@ -1855,7 +1887,8 @@ void LoadNexusProcessed::loadBlock(NXDataSetTyped<double> &data,
 }
 
 /**
- * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a given
+ * Perform a call to nxgetslab, via the NexusClasses wrapped methods for a
+ * given
  * blocksize. The xbins are read along with
  * each call to the data/error loading
  * @param data :: The NXDataSet object of y values
@@ -1993,7 +2026,7 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra,
       if (gen_filtered_list) {
         m_filtered_spec_idxs.resize(total_specs);
         size_t j = 0;
-        for(int64_t si = m_spec_min; si < m_spec_max; si++, j++)
+        for (int64_t si = m_spec_min; si < m_spec_max; si++, j++)
           m_filtered_spec_idxs[j] = si;
       }
     } else {
@@ -2018,8 +2051,7 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra,
         // example: min: 2, max: 8, list: 3,4,5,10,12;
         //          result: 2,3,...,7,8,10,12
         m_filtered_spec_idxs.insert(m_filtered_spec_idxs.end(),
-                                  m_spec_list.begin(),
-                                  m_spec_list.end());
+                                    m_spec_list.begin(), m_spec_list.end());
       }
     }
   } else {
@@ -2029,8 +2061,8 @@ LoadNexusProcessed::calculateWorkspaceSize(const std::size_t numberofspectra,
 
     if (gen_filtered_list) {
       m_filtered_spec_idxs.resize(total_specs, 0);
-      for(int64_t j = 0; j < total_specs; j++)
-        m_filtered_spec_idxs[j] = m_spec_min+j;
+      for (int64_t j = 0; j < total_specs; j++)
+        m_filtered_spec_idxs[j] = m_spec_min + j;
     }
   }
   return total_specs;
diff --git a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp
index 55c0d34ca3a5f0f9a6a94a44071c7f7f7706e7fa..879dbb975bc098b5d2bee65f0eb49c26a7f2b51f 100644
--- a/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp
+++ b/Code/Mantid/Framework/DataHandling/src/LoadSpiceAscii.cpp
@@ -129,8 +129,16 @@ void LoadSpiceAscii::init() {
                   "Otherwise, any log name is not listed will be treated as "
                   "string property.");
 
-  declareProperty(new ArrayProperty<std::string>("DateAndTimeLog"),
-                  "Name and format for date and time");
+  // date: MM/DD/YYYY,time: HH:MM:SS AM is the standard SPICE date time log name
+  // and format
+  std::vector<std::string> defaultlogformat(4);
+  defaultlogformat[0] = "date";
+  defaultlogformat[1] = "MM/DD/YYYY";
+  defaultlogformat[2] = "time";
+  defaultlogformat[3] = "HH:MM:SS AM";
+  declareProperty(
+      new ArrayProperty<std::string>("DateAndTimeLog", defaultlogformat),
+      "Name and format for date and time");
 
   // Output
   declareProperty(new WorkspaceProperty<ITableWorkspace>("OutputWorkspace", "",
@@ -461,8 +469,10 @@ void LoadSpiceAscii::setupRunStartTime(
         runinfows->run().hasProperty(timelogname))) {
     std::stringstream errss;
     errss << "Unable to locate user specified date and time sample logs "
-          << datelogname << " and " << timelogname << ".";
-    throw std::runtime_error(errss.str());
+          << datelogname << " and " << timelogname << "."
+          << "run_start will not be set up.";
+    g_log.error(errss.str());
+    return;
   }
 
   const std::string &rawdatestring =
diff --git a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
index 0f5665b673813c0435671360a77bbb627e4b3591..c2b5c23bab104197643cb04a67f4b2669f9b40c1 100644
--- a/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
+++ b/Code/Mantid/Framework/DataHandling/test/LoadNexusProcessedTest.h
@@ -2,26 +2,34 @@
 #define LOADNEXUSPROCESSEDTEST_H_
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/FileFinder.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/WorkspaceGroup.h"
-#include "MantidDataHandling/LoadInstrument.h"
 #include "MantidDataObjects/EventWorkspace.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidDataObjects/Peak.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/IDTypes.h"
 #include "MantidGeometry/Instrument.h"
+#include "MantidGeometry/Instrument/InstrumentDefinitionParser.h"
 #include "MantidDataHandling/LoadNexusProcessed.h"
 #include "MantidDataHandling/SaveNexusProcessed.h"
 #include "MantidDataHandling/Load.h"
+#include "MantidDataHandling/LoadInstrument.h"
+#include "MantidTestHelpers/WorkspaceCreationHelper.h"
+
 #include "SaveNexusProcessedTest.h"
+
+#include <boost/lexical_cast.hpp>
+
 #include <cxxtest/TestSuite.h>
-#include <iostream>
+
+#include <hdf5.h>
+
 #include <Poco/File.h>
-#include <boost/lexical_cast.hpp>
-#include "MantidGeometry/IDTypes.h"
-#include "MantidTestHelpers/WorkspaceCreationHelper.h"
-#include "MantidDataObjects/PeakShapeSpherical.h"
-#include "MantidDataObjects/Peak.h"
-#include "MantidDataObjects/PeaksWorkspace.h"
 
+using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
 using namespace Mantid::DataObjects;
 using namespace Mantid::API;
@@ -813,9 +821,111 @@ public:
       Workspace_sptr ws = loadAlg.getProperty("OutputWorkspace");
       auto peakWS = boost::dynamic_pointer_cast<Mantid::DataObjects::PeaksWorkspace>(ws);
       TS_ASSERT(peakWS);
+  }
 
+  void test_coordinates_saved_and_loaded_on_peaks_workspace()
+  {
+    auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace();
+    // Loading a peaks workspace without a instrument from an IDF doesn't work ...
+    const std::string filename = FileFinder::Instance().getFullPath(
+          "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
+    InstrumentDefinitionParser parser;
+    parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
+    auto instrument = parser.parseXML(NULL);
+    peaksTestWS->populateInstrumentParameters();
+    peaksTestWS->setInstrument(instrument);
+
+    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
+    peaksTestWS->setCoordinateSystem(appliedCoordinateSystem);
+
+    SaveNexusProcessed saveAlg;
+    saveAlg.setChild(true);
+    saveAlg.initialize();
+    saveAlg.setProperty("InputWorkspace", peaksTestWS);
+    saveAlg.setPropertyValue("Filename", "LoadAndSaveNexusProcessedCoordinateSystem.nxs");
+    saveAlg.execute();
+    std::string filePath = saveAlg.getPropertyValue("Filename");
+
+    LoadNexusProcessed loadAlg;
+    loadAlg.setChild(true);
+    loadAlg.initialize();
+    loadAlg.setPropertyValue("Filename", filePath);
+    loadAlg.setPropertyValue("OutputWorkspace", "__unused");
+    loadAlg.execute();
+    
+    Mantid::API::Workspace_sptr loadedWS = loadAlg.getProperty("OutputWorkspace");
+    auto loadedPeaksWS =
+        boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS);
+    Poco::File testFile(filePath);
+    if(testFile.exists())
+    {
+      testFile.remove();
+    }
+    
+    TS_ASSERT_EQUALS(appliedCoordinateSystem, loadedPeaksWS->getSpecialCoordinateSystem());
+  }
+
+  // backwards compatability check
+  void test_coordinates_saved_and_loaded_on_peaks_workspace_from_expt_info()
+  {
+    auto peaksTestWS = WorkspaceCreationHelper::createPeaksWorkspace();
+    // Loading a peaks workspace without a instrument from an IDF doesn't work ...
+    const std::string filename = FileFinder::Instance().getFullPath(
+          "IDFs_for_UNIT_TESTING/MINITOPAZ_Definition.xml");
+    InstrumentDefinitionParser parser;
+    parser.initialize(filename, "MINITOPAZ", Strings::loadFile(filename));
+    auto instrument = parser.parseXML(NULL);
+    peaksTestWS->populateInstrumentParameters();
+    peaksTestWS->setInstrument(instrument);
+
+    // simulate old-style file with "CoordinateSystem" log
+    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
+    peaksTestWS->logs()->addProperty("CoordinateSystem",
+                                     static_cast<int>(appliedCoordinateSystem));
+
+    SaveNexusProcessed saveAlg;
+    saveAlg.setChild(true);
+    saveAlg.initialize();
+    saveAlg.setProperty("InputWorkspace", peaksTestWS);
+    saveAlg.setPropertyValue("Filename", "LoadAndSaveNexusProcessedCoordinateSystemOldFormat.nxs");
+    saveAlg.execute();
+    std::string filePath = saveAlg.getPropertyValue("Filename");
+
+    // Remove the coordinate_system entry so it falls back on the log. NeXus
+    // can't do this so use the HDF5 API directly
+    auto fid = H5Fopen(filePath.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+    auto mantid_id = H5Gopen(fid, "mantid_workspace_1", H5P_DEFAULT);
+    auto peaks_id = H5Gopen(mantid_id, "peaks_workspace", H5P_DEFAULT);
+    if (peaks_id > 0) {
+      H5Ldelete(peaks_id, "coordinate_system", H5P_DEFAULT);
+      H5Gclose(peaks_id);
+      H5Gclose(mantid_id);
+    } else {
+      TS_FAIL("Cannot unlink coordinate_system group. Test file has unexpected "
+              "structure.");
+    }
+    H5Fclose(fid);
+    
+    LoadNexusProcessed loadAlg;
+    loadAlg.setChild(true);
+    loadAlg.initialize();
+    loadAlg.setPropertyValue("Filename", filePath);
+    loadAlg.setPropertyValue("OutputWorkspace", "__unused");
+    loadAlg.execute();
+    
+    Mantid::API::Workspace_sptr loadedWS = loadAlg.getProperty("OutputWorkspace");
+    auto loadedPeaksWS =
+        boost::dynamic_pointer_cast<Mantid::API::IPeaksWorkspace>(loadedWS);
+    Poco::File testFile(filePath);
+    if(testFile.exists())
+    {
+      testFile.remove();
+    }
+    
+    TS_ASSERT_EQUALS(appliedCoordinateSystem, loadedPeaksWS->getSpecialCoordinateSystem());
   }
 
+  
   void testTableWorkspace_vectorColumn()
   {
     // Create a table we will save
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
index f9d769181bc3ca0142218e0b93ddbec352d43707..67c05c5c1ab64e1a02b121ead5e3e2c5edf65b09 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeakShapeEllipsoid.h
@@ -3,6 +3,7 @@
 
 #include "MantidKernel/System.h"
 #include "MantidKernel/V3D.h"
+#include "MantidKernel/Matrix.h"
 #include "MantidDataObjects/PeakShapeBase.h"
 
 
@@ -56,7 +57,9 @@ namespace DataObjects
     std::vector<double> abcRadiiBackgroundOuter() const;
     /// Get ellipsoid directions
     std::vector<Mantid::Kernel::V3D> directions() const;
-    
+    /// Get ellipsoid directions in a specified frame
+    std::vector<Kernel::V3D> getDirectionInSpecificFrame(Kernel::Matrix<double>& invertedGoniometerMatrix) const;
+
     /// PeakShape interface
     std::string toJSON() const;
     /// Clone ellipsoid
diff --git a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
index 4c4efe464c89031e206768176af300b50e34cb9d..4a4d217689ee12fc645cb24bd3e2d469a5c101b1 100644
--- a/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
+++ b/Code/Mantid/Framework/DataObjects/inc/MantidDataObjects/PeaksWorkspace.h
@@ -109,11 +109,11 @@ public:
   const Peak &getPeak(int peakNum) const;
 
   API::IPeak *createPeak(Kernel::V3D QFrame,
-                         boost::optional<double> detectorDistance = boost::optional<double>()) const;
+                         boost::optional<double> detectorDistance =
+                             boost::optional<double>()) const;
   std::vector<std::pair<std::string, std::string>>
   peakInfo(Kernel::V3D qFrame, bool labCoords) const;
 
-
   Peak *createPeakHKL(Kernel::V3D HKL) const;
 
   int peakInfoNumber(Kernel::V3D qFrame, bool labCoords) const;
@@ -129,12 +129,11 @@ public:
   API::ITableWorkspace_sptr createDetectorTable() const;
 
   /// Set the special coordinate system.
-  virtual void setCoordinateSystem(
-      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem);
+  virtual void
+  setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem);
 
   /// Get the special coordinate system.
-  virtual Mantid::Kernel::SpecialCoordinateSystem
-  getSpecialCoordinateSystem() const;
+  Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const;
 
   // ====================================== ITableWorkspace Methods
   // ==================================
@@ -183,15 +182,6 @@ public:
   void saveNexus(::NeXus::File *file) const;
 
 private:
-  /** Vector of Peak contained within. */
-  std::vector<Peak> peaks;
-
-  /** Column shared pointers. */
-  std::vector<boost::shared_ptr<Mantid::DataObjects::PeakColumn>> columns;
-
-  /** Column names */
-  std::vector<std::string> columnNames;
-
   /// Initialize the table structure
   void initColumns();
   /// Adds a new PeakColumn of the given type
@@ -275,6 +265,18 @@ private:
   // ====================================== End ITableWorkspace Methods
   // ==================================
 
+  /** Vector of Peak contained within. */
+  std::vector<Peak> peaks;
+
+  /** Column shared pointers. */
+  std::vector<boost::shared_ptr<Mantid::DataObjects::PeakColumn>> columns;
+
+  /** Column names */
+  std::vector<std::string> columnNames;
+  
+  /// Coordinates
+  Kernel::SpecialCoordinateSystem m_coordSystem;
+
   // adapter for logs() function, which create reference to this class itself
   // and does not allow to delete the shared pointers,
   // returned by logs() function when they go out of scope
diff --git a/Code/Mantid/Framework/DataObjects/src/NoShape.cpp b/Code/Mantid/Framework/DataObjects/src/NoShape.cpp
index 7250ffebbaa9525a0f42427b26ad21178e953d63..eb4a249bed5d37b8c28eeab81d30a7f0da7ced48 100644
--- a/Code/Mantid/Framework/DataObjects/src/NoShape.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/NoShape.cpp
@@ -1,6 +1,6 @@
 #include "MantidDataObjects/NoShape.h"
 #include <stdexcept>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 namespace Mantid {
 namespace DataObjects {
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp
index c42c6efbe7eaee9d7462da99f285e810d0045314..559757ebadf122bd1038a61e130513257071dd36 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeBase.cpp
@@ -1,6 +1,6 @@
 #include "MantidDataObjects/PeakShapeBase.h"
 #include "MantidKernel/SpecialCoordinateSystem.h"
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 namespace Mantid {
 namespace DataObjects {
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp
index 6a3db09207e54cfe6fb588fe46bef90ba774808e..c3e0a131080c6fc17678ceddc1ad63deb7738ae3 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoid.cpp
@@ -1,6 +1,6 @@
 #include "MantidDataObjects/PeakShapeEllipsoid.h"
 #include "MantidKernel/cow_ptr.h"
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 namespace Mantid {
 namespace DataObjects {
@@ -72,6 +72,22 @@ std::vector<Kernel::V3D> PeakShapeEllipsoid::directions() const {
   return m_directions;
 }
 
+std::vector<Kernel::V3D> PeakShapeEllipsoid::getDirectionInSpecificFrame(Kernel::Matrix<double>& invertedGoniometerMatrix) const{
+  std::vector<Kernel::V3D> directionsInFrame;
+
+  if ((invertedGoniometerMatrix.numCols() != m_directions.size())||
+      (invertedGoniometerMatrix.numRows() != m_directions.size())){
+    throw std::invalid_argument("The inverted goniometer matrix is not compatible with the direction vector");
+  }
+
+  for (std::vector<Kernel::V3D>::const_iterator it = m_directions.begin(); it != m_directions.end(); ++it){
+    directionsInFrame.push_back(invertedGoniometerMatrix*(*it));
+    Mantid::Kernel::V3D d = invertedGoniometerMatrix*(*it);
+  }
+
+  return directionsInFrame;
+}
+
 std::string PeakShapeEllipsoid::toJSON() const {
   Json::Value root;
   PeakShapeBase::buildCommon(root);
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp
index 2d487feee536c2734b76bbf9b4dfcdb8cd5b338c..da25c4df97fa3b296311838393d3b3b06ccaaf8e 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeEllipsoidFactory.cpp
@@ -2,7 +2,7 @@
 #include "MantidDataObjects/PeakShapeEllipsoid.h"
 #include "MantidKernel/SpecialCoordinateSystem.h"
 
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 #include <stdexcept>
 
 using namespace Mantid::Kernel;
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp
index b3403dbee16e637a4cae399e3f61bfd8c63dc185..9bad26ff086ce04bb970a54ea82042a9709879c2 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSpherical.cpp
@@ -1,6 +1,6 @@
 #include "MantidDataObjects/PeakShapeSpherical.h"
 #include <stdexcept>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 namespace Mantid {
 namespace DataObjects {
diff --git a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp
index 90793d60166075eba1960af7ad7ad57eb56ca87c..0c62e5a145d6a5341ba794e6820e4788d0dcb603 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeakShapeSphericalFactory.cpp
@@ -1,7 +1,7 @@
 #include "MantidDataObjects/PeakShapeSphericalFactory.h"
 #include "MantidDataObjects/PeakShapeSpherical.h"
 #include "MantidKernel/SpecialCoordinateSystem.h"
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 #include <MantidKernel/VMD.h>
 
 namespace Mantid {
diff --git a/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp b/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp
index 83aabf18e3fdf7604ed698c848e8a0013651d7c5..4259cce7f869d452a9504fa74e32f7b87a851561 100644
--- a/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp
+++ b/Code/Mantid/Framework/DataObjects/src/PeaksWorkspace.cpp
@@ -38,15 +38,16 @@ namespace DataObjects {
 /// Register the workspace as a type
 DECLARE_WORKSPACE(PeaksWorkspace);
 
-//  Kernel::Logger& PeaksWorkspace::g_log =
-//  Kernel::Logger::get("PeaksWorkspace");
-
 //---------------------------------------------------------------------------------------------
 /** Constructor. Create a table with all the required columns.
  *
  * @return PeaksWorkspace object
  */
-PeaksWorkspace::PeaksWorkspace() : IPeaksWorkspace() { initColumns(); }
+PeaksWorkspace::PeaksWorkspace()
+    : IPeaksWorkspace(), peaks(), columns(), columnNames(),
+      m_coordSystem(None) {
+  initColumns();
+}
 
 //---------------------------------------------------------------------------------------------
 /** Virtual constructor. Clone method to duplicate the peaks workspace.
@@ -65,7 +66,8 @@ PeaksWorkspace *PeaksWorkspace::clone() const {
  * @return
  */
 PeaksWorkspace::PeaksWorkspace(const PeaksWorkspace &other)
-    : IPeaksWorkspace(other), peaks(other.peaks) {
+    : IPeaksWorkspace(other), peaks(other.peaks), columns(), columnNames(),
+      m_coordSystem(other.m_coordSystem) {
   initColumns();
 }
 
@@ -199,11 +201,13 @@ const Peak &PeaksWorkspace::getPeak(const int peakNum) const {
 //---------------------------------------------------------------------------------------------
 /** Creates an instance of a Peak BUT DOES NOT ADD IT TO THE WORKSPACE
  * @param QLabFrame :: Q of the center of the peak, in reciprocal space
- * @param detectorDistance :: optional distance between the sample and the detector. You do NOT need to explicitly provide this distance.
+ * @param detectorDistance :: optional distance between the sample and the
+ * detector. You do NOT need to explicitly provide this distance.
  * @return a pointer to a new Peak object.
  */
-API::IPeak *PeaksWorkspace::createPeak(Kernel::V3D QLabFrame,
-                                       boost::optional<double> detectorDistance) const {
+API::IPeak *
+PeaksWorkspace::createPeak(Kernel::V3D QLabFrame,
+                           boost::optional<double> detectorDistance) const {
   return new Peak(this->getInstrument(), QLabFrame, detectorDistance);
 }
 
@@ -395,31 +399,33 @@ PeaksWorkspace::peakInfo(Kernel::V3D qFrame, bool labCoords) const {
  * @param HKL : reciprocal lattice vector coefficients
  * @return Fully formed peak.
  */
-Peak *PeaksWorkspace::createPeakHKL(V3D HKL) const
-{
-    /*
-     The following allows us to add peaks where we have a single UB to work from.
-     */
+Peak *PeaksWorkspace::createPeakHKL(V3D HKL) const {
+  /*
+   The following allows us to add peaks where we have a single UB to work from.
+   */
 
-    Geometry::OrientedLattice lattice = this->sample().getOrientedLattice();
-    Geometry::Goniometer  goniometer = this->run().getGoniometer();
+  Geometry::OrientedLattice lattice = this->sample().getOrientedLattice();
+  Geometry::Goniometer goniometer = this->run().getGoniometer();
 
-    // Calculate qLab from q HKL. As per Busing and Levy 1967, q_lab_frame = 2pi * Goniometer * UB * HKL
-    V3D qLabFrame = goniometer.getR() * lattice.getUB() * HKL * 2 * M_PI;
+  // Calculate qLab from q HKL. As per Busing and Levy 1967, q_lab_frame = 2pi *
+  // Goniometer * UB * HKL
+  V3D qLabFrame = goniometer.getR() * lattice.getUB() * HKL * 2 * M_PI;
 
-    // create a peak using the qLab frame
-    auto peak = new Peak(this->getInstrument(), qLabFrame); // This should calculate the detector positions too.
+  // create a peak using the qLab frame
+  auto peak =
+      new Peak(this->getInstrument(),
+               qLabFrame); // This should calculate the detector positions too.
 
-    // We need to set HKL separately to keep things consistent.
-    peak->setHKL(HKL[0], HKL[1], HKL[2]);
+  // We need to set HKL separately to keep things consistent.
+  peak->setHKL(HKL[0], HKL[1], HKL[2]);
 
-    // Set the goniometer
-    peak->setGoniometerMatrix(goniometer.getR());
+  // Set the goniometer
+  peak->setGoniometerMatrix(goniometer.getR());
 
-    // Take the run number from this
-    peak->setRunNumber(this->getRunNumber());
+  // Take the run number from this
+  peak->setRunNumber(this->getRunNumber());
 
-    return peak;
+  return peak;
 }
 
 /**
@@ -652,9 +658,8 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
     }
     const std::string shapeJSON = p.getPeakShape().toJSON();
     shapes[i] = shapeJSON;
-    if(shapeJSON.size() > maxShapeJSONLength)
-    {
-        maxShapeJSONLength = shapeJSON.size();
+    if (shapeJSON.size() > maxShapeJSONLength) {
+      maxShapeJSONLength = shapeJSON.size();
     }
   }
 
@@ -665,6 +670,9 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
   file->makeGroup("peaks_workspace", "NXentry",
                   true); // For when peaksWorkspace can be loaded
 
+  // Coordinate system
+  file->writeData("coordinate_system", static_cast<uint32_t>(m_coordSystem));
+  
   // Detectors column
   file->writeData("column_1", detectorID);
   file->openData("column_1");
@@ -801,7 +809,8 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
     std::string rowStr = shapes[ii];
     for (size_t ic = 0; ic < rowStr.size(); ic++)
       toNexus[ii * maxShapeJSONLength + ic] = rowStr[ic];
-    for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxShapeJSONLength); ic++)
+    for (size_t ic = rowStr.size();
+         ic < static_cast<size_t>(maxShapeJSONLength); ic++)
       toNexus[ii * maxShapeJSONLength + ic] = ' ';
   }
 
@@ -813,7 +822,6 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
   file->putAttr("interpret_as", specifyString);
   file->closeData();
 
-
   // QLab & QSample are calculated and do not need to be saved
 
   file->closeGroup(); // end of peaks workpace
@@ -824,25 +832,16 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
  * @param coordinateSystem : Option to set.
  */
 void PeaksWorkspace::setCoordinateSystem(
-    const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) {
-  this->mutableRun().addProperty("CoordinateSystem", (int)coordinateSystem,
-                                 true);
+    const Kernel::SpecialCoordinateSystem coordinateSystem) {
+  m_coordSystem = coordinateSystem;
 }
 
 /**
  * @return the special Q3D coordinate system.
  */
-Mantid::Kernel::SpecialCoordinateSystem
+Kernel::SpecialCoordinateSystem
 PeaksWorkspace::getSpecialCoordinateSystem() const {
-  Mantid::Kernel::SpecialCoordinateSystem result = None;
-  try {
-    Property *prop = this->run().getProperty("CoordinateSystem");
-    PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop);
-    int temp = *p;
-    result = (SpecialCoordinateSystem)temp;
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-  }
-  return result;
+  return m_coordSystem;
 }
 
 // prevent shared pointer from deleting this
diff --git a/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h b/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h
index e005dd877aefe1e2cbc71e9f361f2f1647bca32a..113c6969021f165bd380b5587512b79c196b7933 100644
--- a/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/NoShapeTest.h
@@ -6,7 +6,7 @@
 #endif
 
 #include <cxxtest/TestSuite.h>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 #include "MantidDataObjects/NoShape.h"
 #include "MantidKernel/V3D.h"
 #include "MantidKernel/SpecialCoordinateSystem.h"
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h
index 217290bdb610a6d329f6f3f715b1b20df4892714..1912779723d4e8d2e910b31812e228ede8d3cbc0 100644
--- a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidFactoryTest.h
@@ -7,7 +7,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 #include <boost/assign/list_of.hpp>
 
 #include "MantidDataObjects/PeakShapeEllipsoid.h"
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h
index d844798a82551f8d9cebfdf09ac6948152d7ce88..74438548220d15fc4571f497ea4e1ab05565d6ff 100644
--- a/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeEllipsoidTest.h
@@ -6,9 +6,10 @@
 #include "MantidDataObjects/PeakShapeEllipsoid.h"
 #include "MantidKernel/cow_ptr.h"
 #include "MantidKernel/V3D.h"
+#include "MantidKernel/Matrix.h"
 #include <vector>
 #include <boost/assign/list_of.hpp>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 using Mantid::DataObjects::PeakShapeEllipsoid;
 using Mantid::Kernel::SpecialCoordinateSystem;
@@ -173,8 +174,88 @@ public:
 
   }
 
+  
+  void test_directionsInSpecificFrameThrowsForMatrixWithInvalidDimensions(){
+    auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+                          .convert_to_container<std::vector<V3D>>();
+    const MantidVec abcRadii = list_of(2)(3)(4);
+    const MantidVec abcInnerRadii = list_of(5)(6)(7);
+    const MantidVec abcOuterRadii = list_of(8)(9)(10);
+    const SpecialCoordinateSystem frame = Mantid::Kernel::QLab;
+    const std::string algorithmName = "foo";
+    const int algorithmVersion = 3;
+
+    // Construct it.
+    PeakShapeEllipsoid a(directions, abcRadii, abcInnerRadii, abcOuterRadii,
+                         frame, algorithmName, algorithmVersion);
+    Mantid::Kernel::Matrix<double> matrix(3,2);
+    std::vector<double> column1;
+    column1.push_back(1.0);
+    column1.push_back(1.0);
+    column1.push_back(1.0);
+    std::vector<double> column2;
+    column2.push_back(1.0);
+    column2.push_back(1.0);
+    column2.push_back(1.0);
+
+    matrix.setColumn(0, column1);
+    matrix.setColumn(1, column2);
+    
+    TSM_ASSERT_THROWS("Should throw, bad goniometer matrix",
+                       a.getDirectionInSpecificFrame(matrix) , std::invalid_argument &);
+  }
 
+  void test_directionsInSepcificFrame(){
+    auto directions = list_of(V3D(1, 0, 0))(V3D(0, 1, 0))(V3D(0, 0, 1))
+                          .convert_to_container<std::vector<V3D>>();
+    const MantidVec abcRadii = list_of(2)(3)(4);
+    const MantidVec abcInnerRadii = list_of(5)(6)(7);
+    const MantidVec abcOuterRadii = list_of(8)(9)(10);
+    const SpecialCoordinateSystem frame = Mantid::Kernel::QLab;
+    const std::string algorithmName = "foo";
+    const int algorithmVersion = 3;
+
+    // Construct it.
+    PeakShapeEllipsoid a(directions, abcRadii, abcInnerRadii, abcOuterRadii,
+                         frame, algorithmName, algorithmVersion);
 
+    // 90 degree rotation around the z axis
+    Mantid::Kernel::Matrix<double> matrix(3,3);
+    std::vector<double> column1;
+    column1.push_back(0.0);
+    column1.push_back(1.0);
+    column1.push_back(0.0);
+    std::vector<double> column2;
+    column2.push_back(-1.0);
+    column2.push_back(0.0);
+    column2.push_back(0.0);
+
+    std::vector<double> column3;
+    column3.push_back(0.0);
+    column3.push_back(0.0);
+    column3.push_back(1.0);
+
+    matrix.setColumn(0, column1);
+    matrix.setColumn(1, column2);
+    matrix.setColumn(2, column3);
+    
+    std::vector<Mantid::Kernel::V3D> directionInNewFrame(3);
+    TSM_ASSERT_THROWS_NOTHING("Should throw nothing, valid goniometer matrix",
+                       directionInNewFrame = a.getDirectionInSpecificFrame(matrix));
+
+    const double delta = 1e-6;
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][0], 0.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][1], 1.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[0][2], 0.0, delta);
+
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][0], -1.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][1], 0.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[1][2],  0.0, delta);
+
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][0], 0.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][1], 0.0, delta);
+    TSM_ASSERT_DELTA("Should be rotated", directionInNewFrame[2][2], 1.0, delta);
+  }
 };
 
 #endif /* MANTID_DATAOBJECTS_PEAKSHAPEELLIPSOIDTEST_H_ */
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h
index 6b7a809f17bd450ad0d346d9e24def6d9e0b0a7d..9ecc33fbdf7cb56df988edfa7e6edf34069d136e 100644
--- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalFactoryTest.h
@@ -7,7 +7,7 @@
 
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 #include "MantidDataObjects/PeakShapeSphericalFactory.h"
 #include "MantidDataObjects/PeakShapeSpherical.h"
diff --git a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h
index 7001da81978bc669081756ff856e2d0b8ab74ddc..f6b990bd0ebdee6f97b83cb9f30f35051b502ec6 100644
--- a/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h
+++ b/Code/Mantid/Framework/DataObjects/test/PeakShapeSphericalTest.h
@@ -6,7 +6,7 @@
 #endif
 
 #include <cxxtest/TestSuite.h>
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 
 #include "MantidDataObjects/PeakShapeSpherical.h"
 #include "MantidKernel/V3D.h"
diff --git a/Code/Mantid/Framework/Geometry/CMakeLists.txt b/Code/Mantid/Framework/Geometry/CMakeLists.txt
index cac42359c3d50c3b32fd96d2867bac1ca95687ea..00426282450bf274d76e8d6a0a785f1755835512 100644
--- a/Code/Mantid/Framework/Geometry/CMakeLists.txt
+++ b/Code/Mantid/Framework/Geometry/CMakeLists.txt
@@ -350,12 +350,11 @@ if ( NOT OPENGL_FOUND )
 endif ()
 
 # ===================== Open Cascade ===================
-if (NOT NO_OPENCASCADE)
+if (ENABLE_OPENCASCADE)
   find_package ( OpenCascade REQUIRED )
   include_directories ( system ${OPENCASCADE_INCLUDE_DIR} )
   set (SRC_FILES ${SRC_FILES} ${OPENCASCADE_SRC} )
-else ()
-  add_definitions ( -DNO_OPENCASCADE )
+  add_definitions ( -DENABLE_OPENCASCADE )
 endif ()
 
 # A few defines needed for OpenCascade on the Mac
diff --git a/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp b/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp
index 01493f328c7124728787400ba1e875dc7cff1f9e..dcb1b8b6c9a8e46d585e4a5f0393472ff7fe03b9 100644
--- a/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp
+++ b/Code/Mantid/Framework/Geometry/src/Rendering/CacheGeometryGenerator.cpp
@@ -31,7 +31,7 @@ void CacheGeometryGenerator::Generate() {
   if (mNoOfVertices <=
       0) // There are no triangles defined to use OpenCascade handler
   {
-#ifndef NO_OPENCASCADE
+#ifdef ENABLE_OPENCASCADE
     OCGeometryHandler h(Obj);
     mNoOfVertices = h.NumberOfPoints();
     mNoOfTriangles = h.NumberOfTriangles();
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h
index f29c7b254576573bb455279ca1a55833e22722e4..6f563faea76bc1aea63fd2d4aab427a164ad9a00 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Unit.h
@@ -616,11 +616,17 @@ protected:
 class MANTID_KERNEL_DLL Degrees : public Empty {
 public:
   Degrees();
-  const std::string unitID() const { return ""; }
-  virtual const std::string caption() const { return "Scattering angle"; }
+  const std::string unitID() const; /// < Degrees
+  const std::string caption() const { return "Scattering angle"; }
   const UnitLabel label() const;
 
-  virtual Unit *clone() const { return new Degrees(*this); }
+  virtual void init();
+  virtual Unit *clone() const;
+
+  virtual double singleToTOF(const double x) const;
+  virtual double singleFromTOF(const double tof) const;
+  virtual double conversionTOFMin() const;
+  virtual double conversionTOFMax() const;
 
 private:
   UnitLabel m_label;
diff --git a/Code/Mantid/Framework/Kernel/src/Unit.cpp b/Code/Mantid/Framework/Kernel/src/Unit.cpp
index c9e0c0ead29fe50920ca69fdf962033676d407f7..82e3541bc80de599ae9ec455ff2105f9c17faf2f 100644
--- a/Code/Mantid/Framework/Kernel/src/Unit.cpp
+++ b/Code/Mantid/Framework/Kernel/src/Unit.cpp
@@ -1122,10 +1122,36 @@ Unit *Time::clone() const { return new Time(*this); }
  * Degrees prints degrees as a label
  */
 
+DECLARE_UNIT(Degrees)
+
 Degrees::Degrees() : Empty(), m_label("degrees") {}
 
 const UnitLabel Degrees::label() const { return m_label; }
 
+void Degrees::init() {}
+
+double Degrees::singleToTOF(const double x) const {
+  UNUSED_ARG(x);
+  throw std::runtime_error("Degrees is not allowed to be convert to TOF. ");
+  return 0.0;
+}
+
+double Degrees::singleFromTOF(const double tof) const {
+  UNUSED_ARG(tof);
+  throw std::runtime_error("Degrees is not allwed to be converted from TOF. ");
+  return 0.0;
+}
+
+double Degrees::conversionTOFMax() const {
+  return std::numeric_limits<double>::quiet_NaN();
+}
+
+double Degrees::conversionTOFMin() const {
+  return std::numeric_limits<double>::quiet_NaN();
+}
+
+Unit *Degrees::clone() const { return new Degrees(*this); }
+
 } // namespace Units
 
 } // namespace Kernel
diff --git a/Code/Mantid/Framework/Kernel/test/UnitTest.h b/Code/Mantid/Framework/Kernel/test/UnitTest.h
index 6439181b2c1e141354443e7179ffda7c5ee1e2b4..cfa80847cb10dd05449934c00c7d56ab6a62cf47 100644
--- a/Code/Mantid/Framework/Kernel/test/UnitTest.h
+++ b/Code/Mantid/Framework/Kernel/test/UnitTest.h
@@ -1325,6 +1325,11 @@ public:
 
   }
 
+  /// Test unit Degress
+  void testDegress() {
+    TS_ASSERT_EQUALS(degrees.caption(), "Scattering angle");
+    TS_ASSERT_EQUALS(degrees.unitID(), "Degrees");
+  }
 
 private:
   Units::Label label;
@@ -1340,6 +1345,7 @@ private:
   Units::Momentum k_i;
   Units::SpinEchoLength delta;
   Units::SpinEchoTime tau;
+  Units::Degrees degrees;
 };
 
 #endif /*UNITTEST_H_*/
diff --git a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt
index 13401374db1e4699ab34141640a4a60ea6f00973..0149fe5d792415c7768d8ef9de8415a151bde08a 100644
--- a/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/MDAlgorithms/CMakeLists.txt
@@ -271,9 +271,8 @@ endif ()
 # Add to the 'Framework' group in VS
 set_property ( TARGET MDAlgorithms PROPERTY FOLDER "MantidFramework" )
 
-include_directories ( inc ../MDEvents/inc)
-
-target_link_libraries ( MDAlgorithms ${MANTIDLIBS} MDEvents)
+include_directories ( inc ../MDEvents/inc )
+target_link_libraries ( MDAlgorithms ${MANTIDLIBS} MDEvents )
 
 # Add the unit tests directory
 add_subdirectory ( test )
diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h
index 453b48e6095125680b48c8d677128a77710d03c4..b2176621470c9e43f527728f7521b7c4c7174148 100644
--- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h
+++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/ConvertCWPDMDToSpectra.h
@@ -108,8 +108,12 @@ public:
 
   /// Summary of algorithms purpose
   virtual const std::string summary() const {
-    return "Binning the constant wavelength powder diffracton data stored in "
-           "MDWorkspaces to single spectrum.";
+    return "Convert constant wavelength (CW) powder diffraction (PD) data in "
+           "MDEventWorksapces "
+           " to a single-spectrum MatrixWorkspace, i.e., binning the "
+           "diffraction data "
+           " to single spectrum according to neutron's scattering angle, "
+           "d-spacing or Q. ";
   }
 
   /// Algorithm's version
@@ -134,6 +138,12 @@ private:
       const std::map<int, double> &map_runwavelength, const double xmin,
       const double xmax, const double binsize, bool dolinearinterpolation);
 
+  /// Find the binning boundary according to detectors' positions
+  void findXBoundary(API::IMDEventWorkspace_const_sptr dataws,
+                     const std::string &targetunit,
+                     const std::map<int, double> &map_runwavelength,
+                     double &xmin, double &xmax);
+
   /// Bin signals to its 2theta position
   void binMD(API::IMDEventWorkspace_const_sptr mdws, const char &unitbit,
              const std::map<int, double> &map_runlambda,
diff --git a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
index dbf60ce1b9ddb6a6335cdf12477da31bcd627c8e..1377fd4dc122d97a790ebf4399a69f1a7e4a1903 100644
--- a/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
+++ b/Code/Mantid/Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadMD.h
@@ -75,6 +75,8 @@ private:
 
   void loadDimensions();
 
+  void loadCoordinateSystem();
+
   /// Load all the affine matricies
   void loadAffineMatricies(API::IMDWorkspace_sptr ws);
   /// Load a given affine matrix
@@ -91,6 +93,8 @@ private:
 
   /// Each dimension object loaded.
   std::vector<Mantid::Geometry::IMDDimension_sptr> m_dims;
+  /// Coordinate system
+  Kernel::SpecialCoordinateSystem m_coordSystem;
   /// load only the box structure with empty boxes but do not tload boxes events
   bool m_BoxStructureAndMethadata;
 };
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp
index ee3fe19deeca6bcdf0c39b82adfd8ef57295f01f..418ef2789c7d9a2313f2aff7063094c83fb46981 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/BinMD.cpp
@@ -410,11 +410,15 @@ void BinMD::exec() {
 
   CALL_MDEVENT_FUNCTION(this->binByIterating, m_inWS);
 
-  // Copy the experiment infos to the output
+  // Copy the
+
+  // Copy the coordinate system & experiment infos to the output
   IMDEventWorkspace_sptr inEWS =
       boost::dynamic_pointer_cast<IMDEventWorkspace>(m_inWS);
-  if (inEWS)
+  if (inEWS) {
+    outWS->setCoordinateSystem(inEWS->getSpecialCoordinateSystem());
     outWS->copyExperimentInfos(*inEWS);
+  }
 
   outWS->updateSum();
   // Save the output
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
index 6edfe95bb13237bed211a7ffe0cdc7c696ebd836..590bc5dbc27e8d73de04ae98c6f6e8693fd6df7b 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/ConvertCWPDMDToSpectra.cpp
@@ -15,6 +15,8 @@ using namespace Mantid::MDAlgorithms;
 
 DECLARE_ALGORITHM(ConvertCWPDMDToSpectra)
 
+const double BIGNUMBER = 1.0E100;
+
 //----------------------------------------------------------------------------------------------
 /** Constructor
  */
@@ -53,7 +55,7 @@ void ConvertCWPDMDToSpectra::init() {
   std::vector<std::string> vecunits;
   vecunits.push_back("2theta");
   vecunits.push_back("dSpacing");
-  vecunits.push_back("Momenum Transfer (Q)");
+  vecunits.push_back("Momentum Transfer (Q)");
   auto unitval = boost::make_shared<ListValidator<std::string> >(vecunits);
   declareProperty("UnitOutput", "2theta", unitval,
                   "Unit of the output workspace.");
@@ -140,16 +142,33 @@ void ConvertCWPDMDToSpectra::exec() {
   }
 
   // bin parameters
-  if (binParams.size() != 3)
-    throw std::runtime_error("Binning parameters must have 3 items.");
-  if (binParams[0] >= binParams[2])
+  double xmin, xmax, binsize;
+  xmin = xmax = binsize = -1;
+  if (binParams.size() == 1) {
+    binsize = binParams[0];
+    g_log.warning()
+        << "Only bin size " << binParams[0]
+        << " is specified.  Xmin and Xmax "
+           " will be calcualted from motor positions and wavelength.  "
+           "More CPU time will be used."
+        << "\n";
+  } else if (binParams.size() == 3) {
+    xmin = binParams[0];
+    binsize = binParams[1];
+    xmax = binParams[2];
+    if (xmin >= xmax)
+      throw std::runtime_error(
+          "Min value of the bin must be smaller than maximum value.");
+  } else {
+    // Either 1 or 3 parameters.  Throw exception
     throw std::runtime_error(
-        "Min value of the bin must be smaller than maximum value.");
+        "Binning parameters must have either 1 or 3 items.");
+  }
 
   // Rebin
   API::MatrixWorkspace_sptr outws = reducePowderData(
-      inputDataWS, inputMonitorWS, outputunit, map_runWavelength, binParams[0],
-      binParams[2], binParams[1], doLinearInterpolation);
+      inputDataWS, inputMonitorWS, outputunit, map_runWavelength, xmin, xmax,
+      binsize, doLinearInterpolation);
 
   // Scale
   scaleMatrixWorkspace(outws, scaleFactor, m_infitesimal);
@@ -188,25 +207,46 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData(
   // Get some information
   int64_t numevents = dataws->getNEvents();
 
+  // check xmin and xmax
+  double lowerboundary, upperboundary;
+  if (xmin < 0 || xmax < 0) {
+    // xmin or xmax cannot be negative (2theta, dspace and q are always
+    // positive)
+    findXBoundary(dataws, targetunit, map_runwavelength, lowerboundary,
+                  upperboundary);
+  } else {
+    lowerboundary = xmin;
+    upperboundary = xmax;
+  }
+
+  g_log.debug() << "Binning  from " << lowerboundary << " to " << upperboundary
+                << "\n";
+
   // Create bins in 2theta (degree)
   size_t sizex, sizey;
-  sizex = static_cast<size_t>((xmax - xmin) / binsize + 0.5);
+  sizex = static_cast<size_t>((upperboundary - lowerboundary) / binsize + 1);
+  if (lowerboundary + static_cast<double>(sizex)*binsize < upperboundary)
+    ++ lowerboundary;
+
   sizey = sizex - 1;
   g_log.debug() << "Number of events = " << numevents
-                << "bin size = " << binsize << ", SizeX = " << sizex << ", "
-                << ", SizeY = " << sizey << "\n";
+                << ", bin size = " << binsize << ", SizeX = " << sizex << ", "
+                << ", SizeY = " << sizey
+                << ", Delta = " << upperboundary - lowerboundary
+                << ", Bin size = " << binsize << ", sizex_d = "
+                << (upperboundary - lowerboundary) / binsize + 2 << "\n";
   std::vector<double> vecx(sizex), vecy(sizex - 1, 0), vecm(sizex - 1, 0),
       vece(sizex - 1, 0);
 
   for (size_t i = 0; i < sizex; ++i) {
-    vecx[i] = xmin + static_cast<double>(i) * binsize;
+    vecx[i] = lowerboundary + static_cast<double>(i) * binsize;
   }
 
   // Convert unit to unit char bit
   char unitchar = 't'; // default 2theta
   if (targetunit.compare("dSpacing") == 0)
     unitchar = 'd';
-  else if (targetunit.compare("Momenum Transfer (Q)") == 0)
+  else if (targetunit.compare("Momentum Transfer (Q)") == 0)
     unitchar = 'q';
 
   binMD(dataws, unitchar, map_runwavelength, vecx, vecy);
@@ -243,12 +283,7 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData(
     pdws->getAxis(0)->setUnit("MomentumTransfer");
   else {
     // Twotheta
-    Unit_sptr xUnit = pdws->getAxis(0)->unit();
-    if (xUnit) {
-      g_log.warning("Unable to set unit to an Unit::Empty object.");
-    } else {
-      throw std::runtime_error("Unable to get unit from Axis(0)");
-    }
+    pdws->getAxis(0)->setUnit("Degrees");
   }
 
   MantidVec &dataX = pdws->dataX(0);
@@ -270,6 +305,115 @@ API::MatrixWorkspace_sptr ConvertCWPDMDToSpectra::reducePowderData(
   return pdws;
 }
 
+//----------------------------------------------------------------------------------------------
+/** Find the binning boundaries for 2theta (det position), d-spacing or Q.
+ * @brief ConvertCWPDMDToSpectra::findXBoundary
+ * @param dataws
+ * @param targetunit
+ * @param wavelength
+ * @param xmin :: (output) lower binning boundary
+ * @param xmax :: (output) upper binning boundary
+ */
+void ConvertCWPDMDToSpectra::findXBoundary(
+    API::IMDEventWorkspace_const_sptr dataws, const std::string &targetunit,
+    const std::map<int, double> &map_runwavelength, double &xmin,
+    double &xmax) {
+  // Go through all instruments
+  uint16_t numruns = dataws->getNumExperimentInfo();
+
+  xmin = BIGNUMBER;
+  xmax = -1;
+
+  for (uint16_t irun = 0; irun < numruns; ++irun) {
+    // Skip the Experiment Information does not have run
+    if (!dataws->getExperimentInfo(irun)->getInstrument()) {
+      g_log.warning() << "iRun = " << irun << " of total " << numruns
+                      << " does not have instrument associated"
+                      << "\n";
+      continue;
+    }
+
+    // Get run number
+    int runnumber = dataws->getExperimentInfo(irun)->getRunNumber();
+    g_log.debug() << "Run " << runnumber << ": ";
+    std::map<int, double>::const_iterator miter =
+        map_runwavelength.find(runnumber);
+    double wavelength = -1;
+    if (miter != map_runwavelength.end()) {
+      wavelength = miter->second;
+      g_log.debug() << " wavelength = " << wavelength << "\n";
+    } else {
+      g_log.debug() << " no matched wavelength."
+                     << "\n";
+    }
+
+    // Get source and sample position
+    std::vector<detid_t> vec_detid =
+        dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true);
+    if (vec_detid.size() == 0) {
+      g_log.information() << "Run " << runnumber << " has no detectors."
+                          << "\n";
+      continue;
+    }
+    const V3D samplepos =
+        dataws->getExperimentInfo(irun)->getInstrument()->getSample()->getPos();
+    const V3D sourcepos =
+        dataws->getExperimentInfo(irun)->getInstrument()->getSource()->getPos();
+
+    // Get all detectors
+    // std::vector<detid_t> vec_detid =
+    // dataws->getExperimentInfo(irun)->getInstrument()->getDetectorIDs(true);
+    std::vector<Geometry::IDetector_const_sptr> vec_det =
+        dataws->getExperimentInfo(irun)->getInstrument()->getDetectors(
+            vec_detid);
+    size_t numdets = vec_det.size();
+    g_log.debug() << "Run = " << runnumber
+                  << ": Number of detectors = " << numdets << "\n";
+
+    // Scan all the detectors to get Xmin and Xmax
+    for (size_t idet = 0; idet < numdets; ++idet) {
+      Geometry::IDetector_const_sptr tmpdet = vec_det[idet];
+      const V3D detpos = tmpdet->getPos();
+
+      double R, theta, phi;
+      detpos.getSpherical(R, theta, phi);
+      if (R < 0.0001)
+        g_log.error("Invalid detector position");
+
+      Kernel::V3D v_det_sample = detpos - samplepos;
+      Kernel::V3D v_sample_src = samplepos - sourcepos;
+      double twotheta =
+          calculate2Theta(v_det_sample, v_sample_src) / M_PI * 180.;
+
+      // convert unit optionally
+      double outx = -1;
+      if (targetunit.compare("2theta") == 0)
+        outx = twotheta;
+      else {
+        if (wavelength <= 0)
+          throw std::runtime_error("Wavelength is not defined!");
+
+        if (targetunit.compare("dSpacing") == 0)
+          outx = calculateDspaceFrom2Theta(twotheta, wavelength);
+        else if (targetunit.compare("Momentum Transfer (Q)") == 0)
+          outx = calculateQFrom2Theta(twotheta, wavelength);
+        else
+          throw std::runtime_error("Unrecognized unit.");
+      }
+
+      // Compare with xmin and xmax
+      if (outx < xmin)
+        xmin = outx;
+      if (outx > xmax)
+        xmax = outx;
+    }
+  }
+
+
+  g_log.debug() << "Find boundary for unit " << targetunit << ": [" << xmin << ", " << xmax << "]"
+                 << "\n";
+}
+
 //----------------------------------------------------------------------------------------------
 /** Bin MD Workspace for detector's position at 2theta
  * @brief ConvertCWPDMDToSpectra::binMD
@@ -359,27 +503,84 @@ void ConvertCWPDMDToSpectra::binMD(API::IMDEventWorkspace_const_sptr mdws,
       }
 
       // get signal and assign signal to bin
-      double signal = mditer->getInnerSignal(iev);
-      std::vector<double>::const_iterator vfiter =
-          std::lower_bound(vecx.begin(), vecx.end(), outx);
-      int xindex = static_cast<int>(vfiter - vecx.begin());
+      int xindex;
+      const double SMALL = 1.0E-5;
+      if (outx+SMALL < vecx.front())
+      {
+        // Significantly out of left boundary
+        xindex = -1;
+      }
+      else if (fabs(outx - vecx.front()) < SMALL)
+      {
+        // Almost on the left boundary
+        xindex = 0;
+      }
+      else if (outx-SMALL > vecx.back())
+      {
+        // Significantly out of right boundary
+        xindex = static_cast<int>(vecx.size());
+      }
+      else if (fabs(outx-vecx.back()) < SMALL)
+      {
+        // Right on the right boundary
+        xindex = static_cast<int>(vecy.size())-1;
+      }
+      else
+      {
+        // Other situation
+        std::vector<double>::const_iterator vfiter =
+            std::lower_bound(vecx.begin(), vecx.end(), outx);
+        xindex = static_cast<int>(vfiter - vecx.begin());
+        if ( (xindex < static_cast<int>(vecx.size())) && (outx + 1.0E-5 < vecx[xindex]) )
+        {
+          // assume the bin's boundaries are of [...) and consider numerical error
+          xindex -= 1;
+        }
+        else
+        {
+          g_log.debug() << "Case for almost same.  Event X = " << outx
+                        << ", Boundary = " << vecx[xindex] << "\n";
+        }
+        if (xindex < 0 || xindex >= static_cast<int>(vecy.size()))
+        {
+          g_log.warning() << "Case unexpected:  Event X = " << outx
+                          << ", Boundary = " << vecx[xindex] << "\n";
+        }
+      }
+
+      // add signal
       if (xindex < 0)
-        g_log.warning("xindex < 0");
-      if (xindex >= static_cast<int>(vecy.size()) - 1) {
-        // If the Xmax is set too narrow, then
-        g_log.information() << "Event is out of user-specified range "
-                            << "xindex = " << xindex << ", " << unitbit << " = "
-                            << outx << " out of [" << vecx.front() << ", "
-                            << vecx.back() << "]. dep pos = " << detpos.X()
-                            << ", " << detpos.Y() << ", " << detpos.Z()
-                            << "; sample pos = " << samplepos.X() << ", "
-                            << samplepos.Y() << ", " << samplepos.Z() << "\n";
+      {
+        // Out of left boundary
+        int32_t detid = mditer->getInnerDetectorID(iev);
+        uint16_t runid = mditer->getInnerRunIndex(iev);
+        g_log.debug() << "Event is out of user-specified range by " << (outx-vecx.front())
+                       << ", xindex = " << xindex << ", " << unitbit << " = "
+                       << outx << " out of left boundeary [" << vecx.front() << ", "
+                       << vecx.back() << "]. dep pos = " << detpos.X()
+                       << ", " << detpos.Y() << ", " << detpos.Z()
+                       << ", Run = " << runid << ", DetectorID = " << detid << "\n";
         continue;
       }
-
-      if (xindex > 0 && outx < *vfiter)
-        xindex -= 1;
-      vecy[xindex] += signal;
+      else if (xindex >= static_cast<int>(vecy.size())) {
+        // Out of right boundary
+        int32_t detid = mditer->getInnerDetectorID(iev);
+        uint16_t runid = mditer->getInnerRunIndex(iev);
+        g_log.debug() << "Event is out of user-specified range "
+                      << "xindex = " << xindex << ", " << unitbit << " = "
+                      << outx << " out of [" << vecx.front() << ", "
+                      << vecx.back() << "]. dep pos = " << detpos.X()
+                      << ", " << detpos.Y() << ", " << detpos.Z()
+                      << "; sample pos = " << samplepos.X() << ", "
+                       << samplepos.Y() << ", " << samplepos.Z()
+                       << ", Run = " << runid << ", DetectorID = " << detid << "\n";
+        continue;
+      }
+      else
+      {
+        double signal = mditer->getInnerSignal(iev);
+        vecy[xindex] += signal;
+      }
     }
 
     // Advance to next cell
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
index 022116b5941592f0c4cdf2656195155fc1d297d1..d50f3f3a368673995c33f2feb95a62e23cb61ab1 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/LoadMD.cpp
@@ -40,7 +40,8 @@ DECLARE_NEXUS_FILELOADER_ALGORITHM(LoadMD);
 /** Constructor
 */
 LoadMD::LoadMD()
-    : m_numDims(0),                    // uninitialized incorrect value
+    : m_numDims(0), // uninitialized incorrect value
+      m_coordSystem(None),
       m_BoxStructureAndMethadata(true) // this is faster but rarely needed.
 {}
 
@@ -168,6 +169,8 @@ void LoadMD::exec() {
 
   // Now load all the dimension xml
   this->loadDimensions();
+  // Coordinate system
+  this->loadCoordinateSystem();
 
   if (entryName == "MDEventWorkspace") {
     // The type of event
@@ -233,6 +236,9 @@ void LoadMD::loadHisto() {
   // Now the ExperimentInfo
   MDBoxFlatTree::loadExperimentInfos(m_file.get(), m_filename, ws);
 
+  // Coordinate system
+  ws->setCoordinateSystem(m_coordSystem);
+
   // Load the WorkspaceHistory "process"
   ws->history().loadNexus(m_file.get());
 
@@ -267,6 +273,30 @@ void LoadMD::loadDimensions() {
   }
 }
 
+/** Load the coordinate system **/
+void LoadMD::loadCoordinateSystem() {
+  // Current version stores the coordinate system
+  // in its own field. The first version stored it
+  // as a log value so fallback on that if it can't
+  // be found.
+  try {
+    uint32_t readCoord(0);
+    m_file->readData("coordinate_system", readCoord);
+    m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
+  } catch (::NeXus::Exception &) {
+    auto pathOnEntry = m_file->getPath();
+    try {
+      m_file->openPath(pathOnEntry + "/experiment0/logs/CoordinateSystem");
+      int readCoord(0);
+      m_file->readData("value", readCoord);
+      m_coordSystem = static_cast<SpecialCoordinateSystem>(readCoord);
+    } catch (::NeXus::Exception &) {
+    }
+    // return to where we started
+    m_file->openPath(pathOnEntry);
+  }
+}
+
 //----------------------------------------------------------------------------------------------
 /** Do the loading.
 *
@@ -302,6 +332,9 @@ void LoadMD::doLoad(typename MDEventWorkspace<MDE, nd>::sptr ws) {
   for (size_t d = 0; d < nd; d++)
     ws->addDimension(m_dims[d]);
 
+  // Coordinate system
+  ws->setCoordinateSystem(m_coordSystem);
+
   // ----------------------------------------- Box Structure
   // ------------------------------
   prog->report("Reading box structure from HDD.");
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp
index f9ec66937c51c87e60150eee2c2bd54ce01fed42..e7582e636b6d0023894a13a6cafa9d3ea8cd32ec 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/Quantification/SimulateResolutionConvolvedModel.cpp
@@ -176,6 +176,8 @@ void SimulateResolutionConvolvedModel::createOutputWorkspace() {
   }
   // Run information
   m_outputWS->copyExperimentInfos(*m_inputWS);
+  // Coordinates
+  m_outputWS->setCoordinateSystem(m_inputWS->getSpecialCoordinateSystem());
 
   m_outputWS->initialize();
   m_outputWS->splitBox(); // Make grid box
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
index 8d7503fa945e4b3752e425a083a062d35bd36c15..e515be24ad82fb806d0619d9b4edafc24878a15a 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/SaveMD.cpp
@@ -235,6 +235,10 @@ void SaveMD::doSaveHisto(Mantid::MDEvents::MDHistoWorkspace_sptr ws) {
   // The base entry. Named so as to distinguish from other workspace types.
   file->makeGroup("MDHistoWorkspace", "NXentry", true);
 
+  // Write out the coordinate system
+  file->writeData("coordinate_system",
+                  static_cast<uint32_t>(ws->getSpecialCoordinateSystem()));
+
   // Save the algorithm history under "process"
   ws->getHistory().saveNexus(file);
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp b/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp
index ac2348eadb8fc05f39e4afaa2007c5921ff393e2..f59e3e3feb2b3652bee30a9a800cc786d3ce348a 100644
--- a/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp
+++ b/Code/Mantid/Framework/MDAlgorithms/src/SliceMD.cpp
@@ -122,8 +122,10 @@ void SliceMD::slice(typename MDEventWorkspace<MDE, nd>::sptr ws) {
   // Create the ouput workspace
   typename MDEventWorkspace<OMDE, ond>::sptr outWS(
       new MDEventWorkspace<OMDE, ond>());
-  for (size_t od = 0; od < m_binDimensions.size(); od++)
+  for (size_t od = 0; od < m_binDimensions.size(); od++) {
     outWS->addDimension(m_binDimensions[od]);
+  }
+  outWS->setCoordinateSystem(ws->getSpecialCoordinateSystem());
   outWS->initialize();
   // Copy settings from the original box controller
   BoxController_sptr bc = ws->getBoxController();
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h
index 5200dc777f76e0ea2b4291231ac4e92d968df588..c23b7c04e4c7bb3577691bf7a7d243d2537a08ba 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/BinMDTest.h
@@ -137,8 +137,10 @@ public:
     TS_ASSERT( alg.isInitialized() )
 
     IMDEventWorkspace_sptr in_ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, numEventsPerBox);
-    in_ws->addExperimentInfo(ExperimentInfo_sptr(new ExperimentInfo));
+    Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample;
+    in_ws->setCoordinateSystem(appliedCoord);
     AnalysisDataService::Instance().addOrReplace("BinMDTest_ws", in_ws);
+    
     // 1000 boxes with 1 event each
     TS_ASSERT_EQUALS( in_ws->getNPoints(), 1000*numEventsPerBox);
 
@@ -161,6 +163,7 @@ public:
     TS_ASSERT(out);
     if(!out) return;
 
+    TS_ASSERT_EQUALS(appliedCoord, out->getSpecialCoordinateSystem());
     // Took 6x6x6 bins in the middle of the box
     TS_ASSERT_EQUALS(out->getNPoints(), expected_numBins);
     // Every box has a single event summed into it, so 1.0 weight
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt b/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt
index 791f360df42fb43851ba54cd9409eed32b142fa6..1925dff30ee954097ab795d07c9dd0a98737a677 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt
+++ b/Code/Mantid/Framework/MDAlgorithms/test/CMakeLists.txt
@@ -1,5 +1,5 @@
 if ( CXXTEST_FOUND )
-  include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} )
+  include_directories ( SYSTEM ${CXXTEST_INCLUDE_DIR} ${GMOCK_INCLUDE_DIR} ${GTEST_INCLUDE_DIR} ${HDF5_INCLUDE_DIRS} )
 
   include_directories( ../../TestHelpers/inc ../../DataHandling/inc ../../CurveFitting/inc)	
   # This variable is used within the cxxtest_add_test macro to build these helper classes into the test executable.
@@ -11,10 +11,10 @@ if ( CXXTEST_FOUND )
                         ../../TestHelpers/src/BinaryOperationMDTestHelper.cpp )
   if ( GMOCK_FOUND AND GTEST_FOUND )
     cxxtest_add_test ( MDAlgorithmsTest ${TEST_FILES} ${GMOCK_TEST_FILES})
-    target_link_libraries( MDAlgorithmsTest MDAlgorithms DataHandling CurveFitting Nexus ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} ${NEXUS_LIBRARIES} )
+    target_link_libraries( MDAlgorithmsTest MDAlgorithms DataHandling CurveFitting Nexus ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES} )
   else ()
     cxxtest_add_test ( MDAlgorithmsTest ${TEST_FILES} )
-    target_link_libraries( MDAlgorithmsTest MDAlgorithms Nexus ${NEXUS_LIBRARIES} )
+    target_link_libraries( MDAlgorithmsTest MDAlgorithms Nexus ${NEXUS_LIBRARIES} ${HDF5_LIBRARIES} )
   endif ()
   add_dependencies ( MDAlgorithmsTest DataHandling Algorithms CurveFitting )
   add_dependencies ( FrameworkTests MDAlgorithmsTest )
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
index a88676e9c523d2751a493dc98dc385a368bdbcf2..990a75d4299a7683e30e786f43fdb01b33a0ad95 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/ConvertCWPDMDToSpectraTest.h
@@ -73,7 +73,7 @@ public:
     const Mantid::MantidVec &vecE = outws->readE(0);
 
     TS_ASSERT_DELTA(vecX.front(), 0.0, 0.0001);
-    TS_ASSERT_DELTA(vecX.back(), 120.0 - 0.1, 0.0001);
+    TS_ASSERT_DELTA(vecX.back(), 120.0, 0.0001);
 
     double y1101 = vecY[1101];
     double e1101 = vecE[1101];
@@ -135,7 +135,52 @@ public:
 
     const Mantid::MantidVec &vecX = outws->readX(0);
     TS_ASSERT_DELTA(vecX.front(), 0.5, 0.0001);
-    TS_ASSERT_DELTA(vecX.back(), 4.99, 0.0001);
+    TS_ASSERT_DELTA(vecX.back(), 5.00, 0.0001);
+
+    // Check statistics
+
+    // Clean
+    AnalysisDataService::Instance().remove("ReducedData");
+  }
+
+  //----------------------------------------------------------------------------------------------
+  /** Unit test to reduce/bin the HB2A data with more options
+   * @brief test_ReduceHB2AData
+   */
+  void test_ReduceHB2ADataAutoBinBoundary() {
+    // Init
+    ConvertCWPDMDToSpectra alg;
+    alg.initialize();
+
+    // Set properties
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("InputWorkspace", m_dataMD->name()));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setPropertyValue("InputMonitorWorkspace", m_monitorMD->name()));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("UnitOutput", "dSpacing"));
+    TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("BinningParams", "0.01"));
+    TS_ASSERT_THROWS_NOTHING(
+        alg.setProperty("LinearInterpolateZeroCounts", true));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("ScaleFactor", 10.0));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("NeutronWaveLength", 2.41));
+    TS_ASSERT_THROWS_NOTHING(alg.setProperty("OutputWorkspace", "ReducedData"));
+
+    // Execute
+    TS_ASSERT_THROWS_NOTHING(alg.execute());
+    TS_ASSERT(alg.isExecuted());
+
+    // Get ouput
+    MatrixWorkspace_sptr outws = boost::dynamic_pointer_cast<MatrixWorkspace>(
+        AnalysisDataService::Instance().retrieve("ReducedData"));
+    TS_ASSERT(outws);
+
+    // Check unit and range of X
+    std::string unit = outws->getAxis(0)->unit()->unitID();
+    TS_ASSERT_EQUALS(unit, "dSpacing");
+
+    const Mantid::MantidVec &vecX = outws->readX(0);
+    TS_ASSERT_DELTA(vecX.front(), 1.3416, 0.0001);
+    TS_ASSERT_DELTA(vecX.back(), 23.0216, 0.001);
 
     // Check statistics
 
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
index 0fc5b9c92601b36b424147b66f149856aa867f77..179d58265ca6704dfe4c59f8712424d346009bd6 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/LoadMDTest.h
@@ -17,6 +17,8 @@
 #include "MantidAPI/ExperimentInfo.h"
 #include "MantidMDAlgorithms/LoadMD.h"
 
+#include <hdf5.h>
+
 using namespace Mantid;
 using namespace Mantid::MDEvents;
 using namespace Mantid::MDAlgorithms;
@@ -531,44 +533,122 @@ public:
   }
 
   /// More of an integration test as it uses both load and save.
-  void test_save_and_load_special_coordinates()
-  {
-    MDEventWorkspace1Lean::sptr ws = MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
-    // Set the special coordinate system
+  void test_save_and_load_special_coordinates_MDEventWorkspace() {
+    MDEventWorkspace1Lean::sptr mdeventWS =
+        MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
+    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
+    mdeventWS->setCoordinateSystem(appliedCoordinateSystem);
+
+    auto loadedWS = testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace");
+    // Check that the special coordinate system is the same before the save-load
+    // cycle.
+    TS_ASSERT_EQUALS(appliedCoordinateSystem,
+                     loadedWS->getSpecialCoordinateSystem());
+  }
+
+  // backwards-compatability check for coordinate in log
+  void test_load_coordinate_system_MDEventWorkspace_from_experiment_info() {
+    MDEventWorkspace1Lean::sptr mdeventWS =
+        MDEventsTestHelper::makeMDEW<1>(10, 0.0, 10.0, 2);
     const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
-    ws->setCoordinateSystem(appliedCoordinateSystem);
+    mdeventWS->setCoordinateSystem(appliedCoordinateSystem);
+
+    // Create a log in the first experiment info to simulated an old version of
+    // the file
+    auto expt0 = mdeventWS->getExperimentInfo(0);
+    expt0->mutableRun().addProperty("CoordinateSystem",
+                                    static_cast<int>(appliedCoordinateSystem));
+
+    const bool rmCoordField(true);
+    auto loadedWS =
+        testSaveAndLoadWorkspace(mdeventWS, "MDEventWorkspace", rmCoordField);
+    // Check that the special coordinate system is the same before the save-load
+    // cycle.
+    TS_ASSERT_EQUALS(appliedCoordinateSystem,
+                     loadedWS->getSpecialCoordinateSystem());
+  }
 
-    const std::string inputWSName = "SaveMDSpecialCoordinatesTest";
-    const std::string fileName = inputWSName + ".nxs";
-    AnalysisDataService::Instance().addOrReplace(inputWSName, ws);
+  void test_save_and_load_special_coordinates_MDHistoWorkspace() {
+    auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace(
+        2.5, 2, 10, 10.0, 3.5, "", 4.5);
+    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
+    mdhistoWS->setCoordinateSystem(appliedCoordinateSystem);
+
+    auto loadedWS = testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace");
+    // Check that the special coordinate system is the same before the save-load
+    // cycle.
+    TS_ASSERT_EQUALS(appliedCoordinateSystem,
+                     loadedWS->getSpecialCoordinateSystem());
+  }
 
+  // backwards-compatability check for coordinate in log
+  void test_load_coordinate_system_MDHistoWorkspace_from_experiment_info() {
+    auto mdhistoWS = MDEventsTestHelper::makeFakeMDHistoWorkspace(
+        2.5, 2, 10, 10.0, 3.5, "", 4.5);
+    const SpecialCoordinateSystem appliedCoordinateSystem = QSample;
+    mdhistoWS->setCoordinateSystem(appliedCoordinateSystem);
+
+    // Create a log in the first experiment info to simulated an old version of
+    // the file
+    auto expt0 = mdhistoWS->getExperimentInfo(0);
+    expt0->mutableRun().addProperty("CoordinateSystem",
+                                    static_cast<int>(appliedCoordinateSystem));
+
+    const bool rmCoordField(true);
+    auto loadedWS =
+        testSaveAndLoadWorkspace(mdhistoWS, "MDHistoWorkspace", rmCoordField);
+    // Check that the special coordinate system is the same before the save-load
+    // cycle.
+    TS_ASSERT_EQUALS(appliedCoordinateSystem,
+                     loadedWS->getSpecialCoordinateSystem());
+  }
+
+  Mantid::API::IMDWorkspace_sptr
+  testSaveAndLoadWorkspace(Mantid::API::IMDWorkspace_sptr inputWS,
+                           const char *rootGroup,
+                           const bool rmCoordField = false) {
+    const std::string fileName = "SaveMDSpecialCoordinatesTest.nxs";
     SaveMD saveAlg;
+    saveAlg.setChild(true);
     saveAlg.initialize();
-    saveAlg.isInitialized();
-    saveAlg.setPropertyValue("InputWorkspace", inputWSName);
+    saveAlg.setProperty("InputWorkspace", inputWS);
     saveAlg.setPropertyValue("Filename", fileName);
     saveAlg.execute();
     TS_ASSERT( saveAlg.isExecuted() );
     std::string this_fileName = saveAlg.getProperty("Filename");
 
+    if (rmCoordField) {
+      // Remove the coordinate_system entry so it falls back on the log. NeXus
+      // can't do this
+      // so use the HDF5 API directly
+      auto fid = H5Fopen(fileName.c_str(), H5F_ACC_RDWR, H5P_DEFAULT);
+      auto gid = H5Gopen(fid, rootGroup, H5P_DEFAULT);
+      if (gid > 0) {
+        H5Ldelete(gid, "coordinate_system", H5P_DEFAULT);
+        H5Gclose(gid);
+      } else {
+        TS_FAIL("Cannot open MDEventWorkspace group. Test file has unexpected "
+                "structure.");
+      }
+      H5Fclose(fid);
+    }
+
     LoadMD loadAlg;
+    loadAlg.setChild(true);
     loadAlg.initialize();
     loadAlg.isInitialized();
     loadAlg.setPropertyValue("Filename", fileName);
     loadAlg.setProperty("FileBackEnd", false);
-    loadAlg.setPropertyValue("OutputWorkspace", "reloaded_again");
+    loadAlg.setPropertyValue("OutputWorkspace", "_unused_for_child");
     loadAlg.execute(); 
     TS_ASSERT( loadAlg.isExecuted() );
 
-    // Check that the special coordinate system is the same before the save-load cycle.
-    TS_ASSERT_EQUALS(appliedCoordinateSystem, ws->getSpecialCoordinateSystem());
-
     if (Poco::File(this_fileName).exists())
     {
       Poco::File(this_fileName).remove();
     }
-    AnalysisDataService::Instance().remove(inputWSName);
-    AnalysisDataService::Instance().remove("OutputWorkspace");
+
+    return loadAlg.getProperty("OutputWorkspace");
   }
 
   void test_loadAffine()
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
index 3ecbe17b97b7d4048fb06facfd79cd232f6691f8..e4e4d932672d69ada816168c75b9cfe0d5a8c5d8 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/MergeMDFilesTest.h
@@ -48,6 +48,7 @@ public:
 
     // Create a bunch of input files
     std::vector<std::vector<std::string> > filenames;
+    Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample;
     std::vector<MDEventWorkspace3Lean::sptr> inWorkspaces;
     // how many events put into each file.
     long nFileEvents(1000);
@@ -55,7 +56,9 @@ public:
     {
       std::ostringstream mess;
       mess << "MergeMDFilesTestInput" << i;
-      MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true,-nFileEvents);
+      MDEventWorkspace3Lean::sptr ws = 
+          MDEventsTestHelper::makeFileBackedMDEW(mess.str(), true,-nFileEvents, appliedCoord);
+
       inWorkspaces.push_back(ws);
       filenames.push_back(std::vector<std::string>(1,ws->getBoxController()->getFilename()));
     }
@@ -87,6 +90,7 @@ public:
     TS_ASSERT(ws);
     if (!ws) return;
     
+    TS_ASSERT_EQUALS(appliedCoord, ws->getSpecialCoordinateSystem());
     TS_ASSERT_EQUALS( ws->getNPoints(), 3*nFileEvents);
     MDBoxBase3Lean * box = ws->getBox();
     TS_ASSERT_EQUALS( box->getNumChildren(), 1000);
diff --git a/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h b/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h
index f031322ce1dce76176cfc9d890ae886f4f63d96c..a02607812cd8f5fb7ff57d99bd67a527f2747267 100644
--- a/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h
+++ b/Code/Mantid/Framework/MDAlgorithms/test/SliceMDTest.h
@@ -137,6 +137,8 @@ public:
     TS_ASSERT( alg.isInitialized() )
 
     IMDEventWorkspace_sptr in_ws = MDEventsTestHelper::makeAnyMDEW<MDE,nd>(10, 0.0, 10.0, 1);
+    Mantid::Kernel::SpecialCoordinateSystem appliedCoord = Mantid::Kernel::QSample;
+    in_ws->setCoordinateSystem(appliedCoord);
     AnalysisDataService::Instance().addOrReplace("SliceMDTest_ws", in_ws);
 
     TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("InputWorkspace", "SliceMDTest_ws") );
@@ -166,6 +168,8 @@ public:
 
     TSM_ASSERT_EQUALS("Should default to TakeMaxRecursionDepthFromInput == true", in_ws->getBoxController()->getMaxDepth(), out->getBoxController()->getMaxDepth());
 
+    TS_ASSERT_EQUALS(appliedCoord, out->getSpecialCoordinateSystem());
+
     // Took this many events out with the slice
     TS_ASSERT_EQUALS(out->getNPoints(), expectedNumPoints);
     // Output has this number of dimensions
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h
index 4aaa6769320a38eaf52dcbaa1b2a2c181a99136b..aa134a84b56d0f3e4a649e825d5287402c7c9f72 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDEventWorkspace.h
@@ -32,7 +32,13 @@ namespace MDEvents {
  * */
 TMDE_CLASS
 class DLLExport MDEventWorkspace : public API::IMDEventWorkspace {
+
 public:
+  /// Typedef for a shared pointer of this kind of event workspace
+  typedef boost::shared_ptr<MDEventWorkspace<MDE, nd>> sptr;
+  /// Typedef to access the MDEventType.
+  typedef MDE MDEventType;
+
   MDEventWorkspace();
   MDEventWorkspace(const MDEventWorkspace<MDE, nd> &other);
   virtual ~MDEventWorkspace();
@@ -119,9 +125,6 @@ public:
 
   size_t addEvents(const std::vector<MDE> &events);
 
-  // void addManyEvents(const std::vector<MDE> & events,
-  // Mantid::Kernel::ProgressBase * prog);
-
   std::vector<Mantid::Geometry::MDDimensionExtents<coord_t>>
   getMinimumExtents(size_t depth = 2);
 
@@ -149,13 +152,10 @@ public:
   /// Clear masking
   void clearMDMasking();
 
-  /// Get the special coordinate system.
-  virtual Mantid::Kernel::SpecialCoordinateSystem
-  getSpecialCoordinateSystem() const;
-
-  /// Set the special coordinate system.
-  void setCoordinateSystem(
-      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem);
+  /// Get the coordinate system.
+  Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const;
+  /// Set the coordinate system.
+  void setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordSystem);
   /// make the workspace file backed if it has not been already file backed;
   virtual void setFileBacked(const std::string &fileName);
   /// if workspace was file-backed, this should clear file-backed information
@@ -167,14 +167,10 @@ protected:
   MDBoxBase<MDE, nd> *data;
 
   /// Box controller in use
-  Mantid::API::BoxController_sptr m_BoxController;
+  API::BoxController_sptr m_BoxController;
   // boost::shared_ptr<BoxCtrlChangesList > m_BoxController;
 private:
-public:
-  /// Typedef for a shared pointer of this kind of event workspace
-  typedef boost::shared_ptr<MDEventWorkspace<MDE, nd>> sptr;
-  /// Typedef to access the MDEventType.
-  typedef MDE MDEventType;
+  Kernel::SpecialCoordinateSystem m_coordSystem;
 };
 
 } // namespace MDEvents
diff --git a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
index 1bc89a29dc241b68e26aeccceb723991299da44b..b43bb81ba1b601c6af22dd207f73c7db2e7cd6d8 100644
--- a/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
+++ b/Code/Mantid/Framework/MDEvents/inc/MantidMDEvents/MDHistoWorkspace.h
@@ -147,12 +147,11 @@ public:
   const coord_t *getBinWidths() const { return m_boxLength; }
 
   /// Get the special coordinate system.
-  virtual Mantid::Kernel::SpecialCoordinateSystem
-  getSpecialCoordinateSystem() const;
+  virtual Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const;
 
   /// Set the special coordinate system.
-  void setCoordinateSystem(
-      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem);
+  void
+  setCoordinateSystem(const Kernel::SpecialCoordinateSystem coordinateSystem);
 
   void setTo(signal_t signal, signal_t errorSquared, signal_t numEvents);
 
@@ -161,7 +160,7 @@ public:
 
   coord_t *getVertexesArray(size_t linearIndex, size_t &numVertices) const;
 
-  Mantid::Kernel::VMD getCenter(size_t linearIndex) const;
+  Kernel::VMD getCenter(size_t linearIndex) const;
 
   /// Returns the (normalized) signal at a given coordinates
   signal_t
@@ -422,6 +421,8 @@ private:
   /// the number of events, contributed into the workspace;
   mutable uint64_t m_nEventsContributed;
 
+  Kernel::SpecialCoordinateSystem m_coordSystem;
+
 protected:
   /// Linear array of masks for each bin
   bool *m_masks;
diff --git a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp
index e398bee85440879542788b6ddba14790a211b12c..dbb17e2e1f4f7fafb929f36525899a2a4fc49959 100644
--- a/Code/Mantid/Framework/MDEvents/src/FitMD.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/FitMD.cpp
@@ -211,6 +211,8 @@ boost::shared_ptr<API::Workspace> FitMD::createEventOutputWorkspace(
 
   // Run information
   outputWS->copyExperimentInfos(inputWorkspace);
+  // Coordinates
+  outputWS->setCoordinateSystem(inputWorkspace.getSpecialCoordinateSystem());
   // Set sensible defaults for splitting behaviour
   BoxController_sptr bc = outputWS->getBoxController();
   bc->setSplitInto(3);
diff --git a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp
index ddc312d7ea57429b477793c1c54e811a680247f7..57ede42f6f5f52bc4087bfa13ee87ad0b0ed525f 100644
--- a/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/IntegrateEllipsoids.cpp
@@ -365,9 +365,6 @@ void IntegrateEllipsoids::exec() {
   const size_t numSpectra = wksp->getNumberHistograms();
   Progress prog(this, 0.5, 1.0, numSpectra);
 
-  // loop through the eventlists
-  std::vector<double> buffer(DIMS);
-
   if (eventWS) {
     // process as EventWorkspace
     qListFromEventWS(integrator, prog, eventWS, unitConv, qConverter);
diff --git a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp
index 04bf88b25efc2eabdc3b6eb03d20b6f62daf4672..52782b30ed61049b7cad6ee81995d96a16a956ae 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDBoxFlatTree.cpp
@@ -745,6 +745,9 @@ MDBoxFlatTree::createOrOpenMDWSgroup(const std::string &fileName, int &nDims,
  * dimensions etc.*/
 void MDBoxFlatTree::saveWSGenericInfo(::NeXus::File *const file,
                                       API::IMDWorkspace_const_sptr ws) {
+  // Write out the coordinate system
+  file->writeData("coordinate_system",
+                  static_cast<uint32_t>(ws->getSpecialCoordinateSystem()));
 
   // Save the algorithm history under "process"
   ws->getHistory().saveNexus(file);
diff --git a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp
index a81802c9df25ea59de10adb9d9eb2a74f29aa17d..03e4c2b0d716a5455ab7e7a8de3c619dec258041 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDEventWorkspace.cpp
@@ -34,7 +34,7 @@ namespace MDEvents {
 /** Default constructor
  */
 TMDE(MDEventWorkspace)::MDEventWorkspace()
-    : m_BoxController(new BoxController(nd)) {
+    : data(NULL), m_BoxController(new BoxController(nd)), m_coordSystem(None) {
   // First box is at depth 0, and has this default boxController
   data = new MDBox<MDE, nd>(m_BoxController.get(), 0);
 }
@@ -781,40 +781,21 @@ TMDE(void MDEventWorkspace)::clearMDMasking() {
 }
 
 /**
-Set the special coordinate system (if any) to use.
-@param coordinateSystem : Special coordinate system to use.
+Get the coordinate system (if any) to use.
+@return An enumeration specifying the coordinate system if any.
 */
-TMDE(void MDEventWorkspace)::setCoordinateSystem(
-    const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) {
-  // If there isn't an experiment info, create one.
-  if (this->getNumExperimentInfo() == 0) {
-    ExperimentInfo_sptr expInfo =
-        boost::shared_ptr<ExperimentInfo>(new ExperimentInfo());
-    this->addExperimentInfo(expInfo);
-  }
-  this->getExperimentInfo(0)->mutableRun().addProperty(
-      "CoordinateSystem", (int)coordinateSystem, true);
+TMDE(Kernel::SpecialCoordinateSystem
+         MDEventWorkspace)::getSpecialCoordinateSystem() const {
+  return m_coordSystem;
 }
 
 /**
-Get the special coordinate system (if any) to use.
-@return Special coordinate system if any.
+Set the coordinate system (if any) to use.
+@param coordSystem : Coordinate system to use.
 */
-TMDE(Mantid::Kernel::SpecialCoordinateSystem
-         MDEventWorkspace)::getSpecialCoordinateSystem() const {
-  Mantid::Kernel::SpecialCoordinateSystem result = None;
-  try {
-    auto nInfos = this->getNumExperimentInfo();
-    if (nInfos > 0) {
-      Property *prop =
-          this->getExperimentInfo(0)->run().getProperty("CoordinateSystem");
-      PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop);
-      int temp = *p;
-      result = (SpecialCoordinateSystem)temp;
-    }
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-  }
-  return result;
+TMDE(void MDEventWorkspace)::setCoordinateSystem(
+    const Kernel::SpecialCoordinateSystem coordSystem) {
+  m_coordSystem = coordSystem;
 }
 
 } // namespace MDEvents
diff --git a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
index 6bda2b2a2d1f662f7cfb2992f09e821f38a4c853..f83adb37808c86556b6a5e530893a941e3dc5878 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDHistoWorkspace.cpp
@@ -31,7 +31,8 @@ MDHistoWorkspace::MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX,
                                    Mantid::Geometry::MDHistoDimension_sptr dimZ,
                                    Mantid::Geometry::MDHistoDimension_sptr dimT)
     : IMDHistoWorkspace(), numDimensions(0),
-      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) {
+      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()),
+      m_coordSystem(None) {
   std::vector<Mantid::Geometry::MDHistoDimension_sptr> dimensions;
   if (dimX)
     dimensions.push_back(dimX);
@@ -51,7 +52,8 @@ MDHistoWorkspace::MDHistoWorkspace(Mantid::Geometry::MDHistoDimension_sptr dimX,
 MDHistoWorkspace::MDHistoWorkspace(
     std::vector<Mantid::Geometry::MDHistoDimension_sptr> &dimensions)
     : IMDHistoWorkspace(), numDimensions(0), m_numEvents(NULL),
-      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) {
+      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()),
+      m_coordSystem(None) {
   this->init(dimensions);
 }
 
@@ -62,7 +64,8 @@ MDHistoWorkspace::MDHistoWorkspace(
 MDHistoWorkspace::MDHistoWorkspace(
     std::vector<Mantid::Geometry::IMDDimension_sptr> &dimensions)
     : IMDHistoWorkspace(), numDimensions(0), m_numEvents(NULL),
-      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()) {
+      m_nEventsContributed(std::numeric_limits<uint64_t>::quiet_NaN()),
+      m_coordSystem(None) {
   this->init(dimensions);
 }
 
@@ -1183,39 +1186,20 @@ uint64_t MDHistoWorkspace::sumNContribEvents() const {
 }
 
 /**
-Set the special coordinate system (if any) to use.
-@param coordinateSystem : Special coordinate system to use.
+Get the special coordinate system (if any) to use.
 */
-void MDHistoWorkspace::setCoordinateSystem(
-    const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) {
-  // If there isn't an experiment info, create one.
-  if (this->getNumExperimentInfo() == 0) {
-    ExperimentInfo_sptr expInfo =
-        boost::shared_ptr<ExperimentInfo>(new ExperimentInfo());
-    this->addExperimentInfo(expInfo);
-  }
-  this->getExperimentInfo(0)->mutableRun().addProperty(
-      "CoordinateSystem", (int)coordinateSystem, true);
+Kernel::SpecialCoordinateSystem
+MDHistoWorkspace::getSpecialCoordinateSystem() const {
+  return m_coordSystem;
 }
 
 /**
-Get the special coordinate system (if any) to use.
+Set the special coordinate system (if any) to use.
+@param coordinateSystem : Special coordinate system to use.
 */
-Mantid::Kernel::SpecialCoordinateSystem
-MDHistoWorkspace::getSpecialCoordinateSystem() const {
-  Mantid::Kernel::SpecialCoordinateSystem result = None;
-  try {
-    auto nInfos = this->getNumExperimentInfo();
-    if (nInfos > 0) {
-      Property *prop =
-          this->getExperimentInfo(0)->run().getProperty("CoordinateSystem");
-      PropertyWithValue<int> *p = dynamic_cast<PropertyWithValue<int> *>(prop);
-      int temp = *p;
-      result = (SpecialCoordinateSystem)temp;
-    }
-  } catch (Mantid::Kernel::Exception::NotFoundError &) {
-  }
-  return result;
+void MDHistoWorkspace::setCoordinateSystem(
+    const Kernel::SpecialCoordinateSystem coordinateSystem) {
+  m_coordSystem = coordinateSystem;
 }
 
 /**
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
index 23ee2542e21ba7603a8aba7d277ed8152f169538..07ef49a108f54e31646f4fd7addfd8a80049b5de 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp
@@ -312,6 +312,7 @@ void export_ialgorithm()
     .def("setLogging", &IAlgorithm::setLogging, "Toggle logging on/off.")
     .def("setRethrows", &IAlgorithm::setRethrows)
     .def("initialize", &IAlgorithm::initialize, "Initializes the algorithm")
+    .def("validateInputs", &IAlgorithm::validateInputs, "Cross-check all inputs and return any errors as a dictionary")
     .def("execute", &executeWhileReleasingGIL, "Runs the algorithm and returns whether it has been successful")
     // Special methods
     .def("__str__", &IAlgorithm::toString)
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py
index 17d7d7463573b81bbad2e4e555b2cfe29d37ed37..a8504f916262da4b9f247d1dd228e5a850b044ca 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py
+++ b/Code/Mantid/Framework/PythonInterface/mantid/simpleapi.py
@@ -257,6 +257,23 @@ def FitDialog(*args, **kwargs):
 
 #--------------------------------------------------- --------------------------
 
+#This dictionary maps algorithm names to functions that preprocess their inputs
+#in the simpleapi. The functions take args and kwargs as regular arguments and
+#modify them as required.
+
+_algorithm_preprocessors = dict()
+
+def _pp_cutmd(args, kwargs):
+  if "PBins" in kwargs:
+    bins = kwargs["PBins"]
+    del kwargs["PBins"]
+    if isinstance(bins, tuple) or isinstance(bins, list):
+      #PBin has been provided, we need to split it out into P1Bin, P2Bin, etc.
+      for bin in range(len(bins)):
+        kwargs["P{0}Bin".format(bin+1)] = bins[bin]
+
+_algorithm_preprocessors["CutMD"] = _pp_cutmd
+
 def _get_function_spec(func):
     """Get the python function signature for the given function object
 
@@ -550,6 +567,11 @@ def _create_algorithm_function(algorithm, version, _algm_object):
             Note that if the Version parameter is passed, we will create
             the proper version of the algorithm without failing.
         """
+
+        # If needed, preprocess this algorithm's input
+        if algorithm in _algorithm_preprocessors:
+          _algorithm_preprocessors[algorithm](args, kwargs)
+
         _version = version
         if "Version" in kwargs:
             _version = kwargs["Version"]
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bddc49898f77c8e6f4a8a2631e2b77d878349d4
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/CylinderPaalmanPingsCorrection.py
@@ -0,0 +1,361 @@
+from mantid.simpleapi import *
+from mantid.api import PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty, \
+                       WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator
+from mantid.kernel import StringListValidator, StringMandatoryValidator, IntBoundedValidator, \
+                          FloatBoundedValidator, Direction, logger, CompositeValidator
+from mantid import config
+import math, os.path, numpy as np
+
+
+class CylinderPaalmanPingsCorrection(PythonAlgorithm):
+
+    _sample_ws_name = None
+    _sample_chemical_formula = None
+    _sample_number_density = None
+    _sample_inner_radius = None
+    _sample_outer_radius = None
+    _usecan = False
+    _can_ws_name = None
+    _can_chemical_formula = None
+    _can_number_density = None
+    _can_outer_radius = None
+    _step_size =  None
+    _number_wavelengths = 10
+    _emode = None
+    _efixed = 0.0
+    _output_ws_name = None
+
+
+    def category(self):
+        return "Workflow\\MIDAS;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections"
+
+
+    def summary(self):
+        return "Calculates absorption corrections for a cylindrical or annular sample using Paalman & Pings format."
+
+
+    def PyInit(self):
+        ws_validator = CompositeValidator([WorkspaceUnitValidator('Wavelength'), InstrumentValidator()])
+
+        self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '',
+                             direction=Direction.Input,
+                             validator=ws_validator),
+                             doc='Name for the input sample workspace')
+
+        self.declareProperty(name='SampleChemicalFormula', defaultValue='',
+                             validator=StringMandatoryValidator(),
+                             doc='Sample chemical formula')
+        self.declareProperty(name='SampleNumberDensity', defaultValue=0.1,
+                             validator=FloatBoundedValidator(0.0),
+                             doc='Sample number density in atoms/Angstrom3')
+        self.declareProperty(name='SampleInnerRadius', defaultValue=0.05,
+                             doc='Sample inner radius')
+        self.declareProperty(name='SampleOuterRadius', defaultValue=0.1,
+                             doc='Sample outer radius')
+
+        self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '',
+                             direction=Direction.Input,
+                             optional=PropertyMode.Optional,
+                             validator=ws_validator),
+                             doc="Name for the input container workspace")
+
+        self.declareProperty(name='CanChemicalFormula', defaultValue='',
+                             doc='Container chemical formula')
+        self.declareProperty(name='CanNumberDensity', defaultValue=0.1,
+                             validator=FloatBoundedValidator(0.0),
+                             doc='Container number density in atoms/Angstrom3')
+        self.declareProperty(name='CanOuterRadius', defaultValue=0.15,
+                             doc='Can outer radius')
+
+        self.declareProperty(name='BeamHeight', defaultValue=0.1,
+                             doc='Height of the beam at the sample.')
+        self.declareProperty(name='BeamWidth', defaultValue=0.1,
+                             doc='Width of the beam at the sample.')
+
+        self.declareProperty(name='StepSize', defaultValue=0.002,
+                             doc='Step size for calculation')
+
+        self.declareProperty(name='Interpolate', defaultValue=True,
+                             doc='Interpolate the correction workspaces to match the sample workspace')
+
+        self.declareProperty(name='Emode', defaultValue='Elastic',
+                             validator=StringListValidator(['Elastic', 'Indirect']),
+                             doc='Emode: Elastic or Indirect')
+        self.declareProperty(name='Efixed', defaultValue=1.0,
+                             doc='Analyser energy')
+
+        self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
+                             direction=Direction.Output),
+                             doc='The output corrections workspace group')
+
+
+    def PyExec(self):
+
+        from IndirectImport import is_supported_f2py_platform, import_f2py
+
+        if is_supported_f2py_platform():
+            cylabs = import_f2py("cylabs")
+        else:
+            raise RuntimeError('This algorithm is only available on Windows')
+
+        workdir = config['defaultsave.directory']
+        self._setup()
+        self._wave_range()
+
+        # Set sample material from chemical formula
+        SetSampleMaterial(self._sample_ws_name, ChemicalFormula=self._sample_chemical_formula,
+                          SampleNumberDensity=self._sample_number_density)
+        sample = mtd[self._sample_ws_name].sample()
+        sam_material = sample.getMaterial()
+        # total scattering x-section
+        sigs = [sam_material.totalScatterXSection()]
+        # absorption x-section
+        siga = [sam_material.absorbXSection()]
+        density = [self._sample_number_density, self._can_number_density, self._can_number_density]
+        half_width = 0.5*float(self._beam_width)
+        beam = [self._beam_height, half_width, -half_width, half_width, -half_width, 0.0, self._beam_height, 0.0, self._beam_height]
+        radii = [self._sample_inner_radius, self._sample_outer_radius, self._can_outer_radius, self._can_outer_radius]
+        ncan = 0
+
+        # If using a can, set sample material using chemical formula
+        if self._use_can:
+            ncan = 2
+            SetSampleMaterial(InputWorkspace=self._can_ws_name, ChemicalFormula=self._can_chemical_formula,
+                              SampleNumberDensity=self._can_number_density)
+            can_sample = mtd[self._can_ws_name].sample()
+            can_material = can_sample.getMaterial()
+
+            # total scattering x-section for can
+            sigs.append(can_material.totalScatterXSection())
+            sigs.append(can_material.totalScatterXSection())
+            # absorption x-section for can
+            siga.append(can_material.absorbXSection())
+            siga.append(can_material.absorbXSection())
+
+        else:
+            # total scattering x-section for can
+            sigs.append(0.0)
+            sigs.append(0.0)
+            # absorption x-section for can
+            siga.append(0.0)
+            siga.append(0.0)
+
+        # Holders for the corrected data
+        data_ass = []
+        data_assc = []
+        data_acsc = []
+        data_acc = []
+
+        # initially set errors to zero
+        wrk = workdir + self._can_ws_name
+        self._get_angles()
+        number_angles = len(self._angles)
+
+        for angle_idx in range(number_angles):
+            kill, ass, assc, acsc, acc = cylabs.cylabs(self._step_size, beam, ncan, radii,
+                density, sigs, siga, self._angles[angle_idx], self._elastic, self._waves, angle_idx, wrk, 0)
+
+            if kill == 0:
+                logger.information('Angle %d: %f successful' % (angle_idx+1, self._angles[angle_idx]))
+
+                data_ass = np.append(data_ass, ass)
+                data_assc = np.append(data_assc, assc)
+                data_acsc = np.append(data_acsc, acsc)
+                data_acc = np.append(data_acc, acc)
+
+            else:
+                raise ValueError('Angle ' + str(angle_idx) + ' : ' + str(self._angles[angle_idx]) + ' *** failed : Error code ' + str(kill))
+
+        sample_logs = {'sample_shape': 'cylinder', 'sample_filename': self._sample_ws_name,
+                        'sample_inner_radius': self._sample_inner_radius, 'sample_outer_radius': self._sample_outer_radius}
+        dataX = self._waves * number_angles
+
+        # Create the output workspaces
+        ass_ws = self._output_ws_name + '_ass'
+
+        CreateWorkspace(OutputWorkspace=ass_ws, DataX=dataX, DataY=data_ass,
+                        NSpec=number_angles, UnitX='Wavelength')
+        self._add_sample_logs(ass_ws, sample_logs)
+        workspaces = [ass_ws]
+
+        if self._use_can:
+            sample_logs['can_filename'] = self._can_ws_name
+            sample_logs['can_outer_radius'] = self._can_outer_radius
+
+            assc_ws = self._output_ws_name + '_assc'
+            workspaces.append(assc_ws)
+            CreateWorkspace(OutputWorkspace=assc_ws, DataX=dataX, DataY=data_assc,
+                            NSpec=number_angles, UnitX='Wavelength')
+            self._add_sample_logs(assc_ws, sample_logs)
+
+            acsc_ws = self._output_ws_name + '_acsc'
+            workspaces.append(acsc_ws)
+            CreateWorkspace(OutputWorkspace=acsc_ws, DataX=dataX, DataY=data_acsc,
+                            NSpec=number_angles, UnitX='Wavelength')
+            self._add_sample_logs(acsc_ws, sample_logs)
+
+            acc_ws = self._output_ws_name + '_acc'
+            workspaces.append(acc_ws)
+            CreateWorkspace(OutputWorkspace=acc_ws, DataX=dataX, DataY=data_acc,
+                            NSpec=number_angles, UnitX='Wavelength')
+            self._add_sample_logs(acc_ws, sample_logs)
+
+        if self._interpolate:
+            self._interpolate_corrections(workspaces)
+
+        try:
+            self. _copy_detector_table(workspaces)
+        except RuntimeError:
+            logger.warning('Cannot copy spectra mapping. Check input workspace instrument.')
+
+        GroupWorkspaces(InputWorkspaces=','.join(workspaces), OutputWorkspace=self._output_ws_name)
+        self.setPropertyValue('OutputWorkspace', self._output_ws_name)
+
+
+    def validateInputs(self):
+        self._setup()
+        issues = dict()
+
+        # Ensure that a can chemical formula is given when using a can workspace
+        if self._use_can:
+            can_chemical_formula = self.getPropertyValue('CanChemicalFormula')
+            if can_chemical_formula == '':
+                issues['CanChemicalFormula'] = 'Must provide a chemical foruma when providing a can workspace'
+
+        # Ensure there are enough steps
+        number_steps = int((self._sample_outer_radius - self._sample_inner_radius) / self._step_size)
+        if number_steps < 20:
+            issues['StepSize'] = 'Number of steps (%d) should be >= 20' % number_steps
+
+        return issues
+
+
+    def _setup(self):
+        """
+        Get algorithm properties.
+        """
+
+        # This is fixed by the Fortran code
+        self._number_wavelengths = 10
+
+        self._sample_ws_name = self.getPropertyValue('SampleWorkspace')
+
+        self._sample_chemical_formula = self.getPropertyValue('SampleChemicalFormula')
+        self._sample_number_density = self.getProperty('SampleNumberDensity').value
+        self._sample_inner_radius = self.getProperty('SampleInnerRadius').value
+        self._sample_outer_radius = self.getProperty('SampleOuterRadius').value
+
+        self._can_ws_name = self.getPropertyValue('CanWorkspace')
+        self._use_can = self._can_ws_name != ''
+
+        self._can_chemical_formula = self.getPropertyValue('CanChemicalFormula')
+        self._can_number_density = self.getProperty('CanNumberDensity').value
+        self._can_outer_radius = self.getProperty('CanOuterRadius').value
+
+        self._step_size = self.getProperty('StepSize').value
+
+        self._beam_height = self.getProperty('BeamHeight').value
+        self._beam_width = self.getProperty('BeamWidth').value
+
+        self._interpolate = self.getProperty('Interpolate').value
+
+        self._emode = self.getPropertyValue('Emode')
+        self._efixed = self.getProperty('Efixed').value
+
+        self._output_ws_name = self.getPropertyValue('OutputWorkspace')
+
+
+    def _get_angles(self):
+        """
+        Populates the list of workspace angles.
+        """
+
+        num_hist = mtd[self._sample_ws_name].getNumberHistograms()
+        source_pos = mtd[self._sample_ws_name].getInstrument().getSource().getPos()
+        sample_pos = mtd[self._sample_ws_name].getInstrument().getSample().getPos()
+        beam_pos = sample_pos - source_pos
+        self._angles = list()
+        for index in range(0, num_hist):
+            detector = mtd[self._sample_ws_name].getDetector(index)
+            two_theta = detector.getTwoTheta(sample_pos, beam_pos) * 180.0 / math.pi  # calc angle
+            self._angles.append(two_theta)
+
+
+    def _wave_range(self):
+        wave_range = '__WaveRange'
+        ExtractSingleSpectrum(InputWorkspace=self._sample_ws_name, OutputWorkspace=wave_range, WorkspaceIndex=0)
+        Xin = mtd[wave_range].readX(0)
+        wave_min = mtd[wave_range].readX(0)[0]
+        wave_max = mtd[wave_range].readX(0)[len(Xin) - 1]
+        number_waves = int(self._number_wavelengths)
+        wave_bin = (wave_max - wave_min) / (number_waves-1)
+
+        self._waves = list()
+        for idx in range(0, number_waves):
+            self._waves.append(wave_min + idx * wave_bin)
+
+        if self._emode == 'Elastic':
+            self._elastic = self._waves[int(number_waves / 2)]
+        elif self._emode == 'Indirect':
+            self._elastic = math.sqrt(81.787 / self._efixed)  # elastic wavelength
+
+        logger.information('Elastic lambda %f' % self._elastic)
+        DeleteWorkspace(wave_range)
+
+
+    def _interpolate_corrections(self, workspaces):
+        """
+        Performs interpolation on the correction workspaces such that the number of bins
+        matches that of the input sample workspace.
+
+        @param workspaces List of correction workspaces to interpolate
+        """
+
+        for ws in workspaces:
+            SplineInterpolation(WorkspaceToMatch=self._sample_ws_name,
+                                WorkspaceToInterpolate=ws,
+                                OutputWorkspace=ws,
+                                OutputWorkspaceDeriv='')
+
+
+    def _copy_detector_table(self, workspaces):
+        """
+        Copy the detector table from the sample workspaces to the correction workspaces.
+
+        @param workspaces List of correction workspaces
+        """
+
+        instrument = mtd[self._sample_ws_name].getInstrument().getName()
+
+        for ws in workspaces:
+            LoadInstrument(Workspace=ws,
+                           InstrumentName=instrument)
+
+            CopyDetectorMapping(WorkspaceToMatch=self._sample_ws_name,
+                                WorkspaceToRemap=ws,
+                                IndexBySpectrumNumber=True)
+
+
+    def _add_sample_logs(self, ws, sample_logs):
+        """
+        Add a dictionary of logs to a workspace.
+
+        The type of the log is inferred by the type of the value passed to the log.
+
+        @param ws - workspace to add logs too.
+        @param sample_logs - dictionary of logs to append to the workspace.
+        """
+
+        for key, value in sample_logs.iteritems():
+            if isinstance(value, bool):
+                log_type = 'String'
+            elif isinstance(value, (int, long, float)):
+                log_type = 'Number'
+            else:
+                log_type = 'String'
+
+            AddSampleLog(Workspace=ws, LogName=key, LogType=log_type, LogText=str(value))
+
+
+# Register algorithm with Mantid
+AlgorithmFactory.subscribe(CylinderPaalmanPingsCorrection)
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py
new file mode 100644
index 0000000000000000000000000000000000000000..84df7738b4f721a942d54fcbe6c3f72fe1e96f48
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py
@@ -0,0 +1,199 @@
+from mantid.simpleapi import *
+from mantid.api import *
+from mantid.kernel import *
+
+
+class MSDFit(DataProcessorAlgorithm):
+
+    def category(self):
+        return 'Workflow\\MIDAS;PythonAlgorithms'
+
+
+    def summary(self):
+        return 'Fits log(intensity) vs Q-squared to obtain the mean squared displacement.'
+
+
+    def PyInit(self):
+        self.declareProperty(MatrixWorkspaceProperty('InputWorkspace', '',
+                             direction=Direction.Input),
+                             doc='Sample input workspace')
+
+        self.declareProperty(name='XStart', defaultValue=0.0,
+                             doc='Start of fitting range')
+        self.declareProperty(name='XEnd', defaultValue=0.0,
+                             doc='End of fitting range')
+
+        self.declareProperty(name='SpecMin', defaultValue=0,
+                             doc='Start of spectra range to be fit')
+        self.declareProperty(name='SpecMax', defaultValue=0,
+                             doc='End of spectra range to be fit')
+
+        self.declareProperty(name='Plot', defaultValue=False,
+                             doc='Plots results after fit')
+
+        self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
+                             direction=Direction.Output),
+                             doc='Output mean squared displacement')
+
+        self.declareProperty(ITableWorkspaceProperty('ParameterWorkspace', '',
+                             direction=Direction.Output,
+                             optional=PropertyMode.Optional),
+                             doc='Output fit parameters table')
+
+        self.declareProperty(WorkspaceGroupProperty('FitWorkspaces', '',
+                             direction=Direction.Output,
+                             optional=PropertyMode.Optional),
+                             doc='Output fitted workspaces')
+
+
+    def validateInputs(self):
+        issues = dict()
+        tolerance = 1e-10
+
+        workspace = self.getProperty('InputWorkspace').value
+        x_data = workspace.readX(0)
+
+        # Validate X axis fitting range
+        x_min = self.getProperty('XStart').value
+        x_max = self.getProperty('XEnd').value
+
+        if x_min > x_max:
+            msg = 'XStart must be less then XEnd'
+            issues['XStart'] = msg
+            issues['XEnd'] = msg
+
+        if x_min < x_data[0]:
+            issues['XStart'] = 'Must be greater than minimum X value in workspace'
+
+        if x_max > x_data[-1]:
+            issues['XEnd'] = 'Must be less than maximum X value in workspace'
+
+        # Validate specta fitting range
+        spec_min = self.getProperty('SpecMin').value
+        spec_max = self.getProperty('SpecMax').value
+
+        if spec_min < 0:
+            issues['SpecMin'] = 'Minimum spectrum index must be greater than or equal to 0'
+
+        if spec_max > workspace.getNumberHistograms():
+            issues['SpecMax'] = 'Maximum spectrum index must be less than number of spectra in workspace'
+
+        if spec_min > spec_max:
+            msg = 'SpecMin must be less then SpecMax'
+            issues['SpecMin'] = msg
+            issues['SpecMax'] = msg
+
+        return issues
+
+
+    def PyExec(self):
+        self._setup()
+
+        # Fit line to each of the spectra
+        function = 'name=LinearBackground, A0=0, A1=0'
+        input_params = [self._input_ws + ',i%d' % i for i in xrange(
+                        self._spec_range[0], self._spec_range[1] + 1)]
+        input_params = ';'.join(input_params)
+        PlotPeakByLogValue(Input=input_params, OutputWorkspace=self._output_msd_ws,
+                           Function=function, StartX=self._x_range[0], EndX=self._x_range[1],
+                           FitType='Sequential', CreateOutput=True)
+
+        DeleteWorkspace(self._output_msd_ws + '_NormalisedCovarianceMatrices')
+        DeleteWorkspace(self._output_msd_ws + '_Parameters')
+        RenameWorkspace(self._output_msd_ws, OutputWorkspace=self._output_param_ws)
+
+        params_table = mtd[self._output_param_ws]
+
+        # MSD value should be positive, but the fit output is negative
+        msd = params_table.column('A1')
+        for i, value in enumerate(msd):
+            params_table.setCell('A1', i, value * -1)
+
+        # Create workspaces for each of the parameters
+        parameter_ws_group = []
+
+        # A0 workspace
+        ws_name = self._output_msd_ws + '_A0'
+        parameter_ws_group.append(ws_name)
+        ConvertTableToMatrixWorkspace(self._output_param_ws, OutputWorkspace=ws_name,
+                                      ColumnX='axis-1', ColumnY='A0', ColumnE='A0_Err')
+        xunit = mtd[ws_name].getAxis(0).setUnit('Label')
+        xunit.setLabel('Temperature', 'K')
+
+        # A1 workspace
+        ws_name = self._output_msd_ws + '_A1'
+        parameter_ws_group.append(ws_name)
+        ConvertTableToMatrixWorkspace(self._output_param_ws, OutputWorkspace=ws_name,
+                                      ColumnX='axis-1', ColumnY='A1', ColumnE='A1_Err')
+        xunit = mtd[ws_name].getAxis(0).setUnit('Label')
+        xunit.setLabel('Temperature', 'K')
+        SortXAxis(ws_name, OutputWorkspace=ws_name)
+
+        # Group parameter workspaces
+        GroupWorkspaces(InputWorkspaces=','.join(parameter_ws_group),
+                        OutputWorkspace=self._output_msd_ws)
+
+        # Rename fit workspace group
+        original_fit_ws_name = self._output_msd_ws + '_Workspaces'
+        if original_fit_ws_name != self._output_fit_ws:
+            RenameWorkspace(InputWorkspace=self._output_msd_ws + '_Workspaces',
+                            OutputWorkspace=self._output_fit_ws)
+
+        # Add sample logs to output workspace
+        CopyLogs(InputWorkspace=self._input_ws, OutputWorkspace=self._output_msd_ws)
+        CopyLogs(InputWorkspace=self._output_msd_ws + '_A0', OutputWorkspace=self._output_fit_ws)
+
+        self.setProperty('OutputWorkspace', self._output_msd_ws)
+        self.setProperty('ParameterWorkspace', self._output_param_ws)
+        self.setProperty('FitWorkspaces', self._output_fit_ws)
+
+        if self._plot:
+            self._plot_result()
+
+
+    def _setup(self):
+        """
+        Gets algorithm properties.
+        """
+        self._input_ws = self.getPropertyValue('InputWorkspace')
+        self._output_msd_ws = self.getPropertyValue('OutputWorkspace')
+
+        self._output_param_ws = self.getPropertyValue('ParameterWorkspace')
+        if self._output_param_ws == '':
+            self._output_param_ws = self._output_msd_ws + '_Parameters'
+
+        self._output_fit_ws = self.getPropertyValue('FitWorkspaces')
+        if self._output_fit_ws == '':
+            self._output_fit_ws = self._output_msd_ws + '_Workspaces'
+
+        self._x_range = [self.getProperty('XStart').value,
+                         self.getProperty('XEnd').value]
+
+        self._spec_range = [self.getProperty('SpecMin').value,
+                            self.getProperty('SpecMax').value]
+
+        self._plot = self.getProperty('Plot').value
+
+
+    def _plot_result(self):
+        """
+        Handles plotting result workspaces.
+        """
+
+        from IndirectImport import import_mantidplot
+        mtd_plot = import_mantidplot()
+
+        x_label = ''
+        ws_run = mtd[self._input_ws].getRun()
+        if 'vert_axis' in ws_run:
+            x_label = ws_run.getLogData('vert_axis').value
+
+        result_ws = mtd[self._output_msd_ws + '_A1']
+        if len(result_ws.readX(0)) > 1:
+            msd_plot = mtd_plot.plotSpectrum(result_ws, 0, True)
+            msd_layer = msd_plot.activeLayer()
+            msd_layer.setAxisTitle(mtd_plot.Layer.Bottom, x_label)
+            msd_layer.setAxisTitle(mtd_plot.Layer.Left, '<u2>')
+
+
+AlgorithmFactory.subscribe(MSDFit)
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py
index 67f6efc025b5731ff14298f1fa3b40b514cc992a..96c0f353bca67b3e42c697871d307309877fbc2c 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/CutMD.py
@@ -41,6 +41,9 @@ class CutMD(DataProcessorAlgorithm):
         self.declareProperty(FloatArrayProperty(name='P4Bin', values=[]),
                              doc='Projection 4 binning')
 
+        self.declareProperty(FloatArrayProperty(name='P5Bin', values=[]),
+                             doc='Projection 5 binning')
+
         self.declareProperty(IMDWorkspaceProperty('OutputWorkspace', '',\
                              direction=Direction.Output),
                              doc='Output cut workspace')
@@ -240,11 +243,16 @@ class CutMD(DataProcessorAlgorithm):
         projection_table = self.getProperty("Projection").value
         self.__verify_projection_input(projection_table)
 
-        p1_bins = self.getProperty("P1Bin").value
-        p2_bins = self.getProperty("P2Bin").value
-        p3_bins = self.getProperty("P3Bin").value
-        p4_bins_property = self.getProperty("P4Bin")
-        p4_bins = p4_bins_property.value
+        #Fetch pbins properties
+        pbins = [None] * 5 #Up to 5 dimensions
+        for i in range(len(pbins)):
+            pbins[i] = self.getProperty("P{0}Bin".format(i+1))
+
+            #Also check the correct pbin properties are set
+            if pbins[i].isDefault and i < ndims:
+                raise ValueError("P{0}Bin dimension binning must be set on a workspace with {1} dimensions.".format(i+1, ndims))
+            elif not pbins[i].isDefault and i >= ndims:
+                raise ValueError("Cannot set P{0}Bin dimension binning on a workspace with {1} dimensions.".format(i+1, ndims))
 
         x_extents = self.__extents_in_current_projection(to_cut, 0)
         y_extents = self.__extents_in_current_projection(to_cut, 1)
@@ -257,40 +265,36 @@ class CutMD(DataProcessorAlgorithm):
         u,v,w = self.__scale_projection(projection, origin_units, target_units, to_cut)
 
         extents = self.__calculate_extents(u, v, w, ( x_extents, y_extents, z_extents ) )
-        extents, bins = self.__calculate_steps( extents, ( p1_bins, p2_bins, p3_bins ) )
-
-        if not p4_bins_property.isDefault:
-            if ndims == 4:
-                n_args = len(p4_bins)
-                min, max = self.__extents_in_current_projection(to_cut, 3)
-                d_range = max - min
-                if n_args == 1:
-                    step_size = p4_bins[0]
-                    nbins = d_range / step_size
-                elif n_args == 2:
-                    min = p4_bins[0]
-                    max = p4_bins[1]
-                    nbins = 1
-                elif n_args == 3:
-                    min = p4_bins[0]
-                    max = p4_bins[2]
-                    step_size = p4_bins[1]
-                    dim_range = max - min
-                    if step_size > dim_range:
-                        step_size = dim_range
-                    nbins = int( dim_range / step_size)
-
-                extents.append(min)
-                extents.append(max)
-                bins.append(int(nbins))
-
-                e_units = to_cut.getDimension(3).getUnits()
-
-                temp = list(target_units)
-                temp.append(target_units)
-                target_units = tuple(temp)
-            else:
-                raise ValueError("Cannot specify P4Bins unless the workspace is of sufficient dimensions")
+        extents, bins = self.__calculate_steps( extents, ( pbins[0].value, pbins[1].value, pbins[2].value ) )
+
+        for i in range(3, ndims):
+            pbin = pbins[i].value
+            n_args = len(pbin)
+            min, max = self.__extents_in_current_projection(to_cut, i)
+            d_range = max - min
+            if n_args == 1:
+                step_size = pbin[0]
+                nbins = d_range / step_size
+            elif n_args == 2:
+                min = pbin[0]
+                max = pbin[1]
+                nbins = 1
+            elif n_args == 3:
+                min = pbin[0]
+                max = pbin[2]
+                step_size = pbin[1]
+                dim_range = max - min
+                if step_size > dim_range:
+                    step_size = dim_range
+                nbins = int( dim_range / step_size)
+
+            extents.append(min)
+            extents.append(max)
+            bins.append(int(nbins))
+
+            temp = list(target_units)
+            temp.append(target_units)
+            target_units = tuple(temp)
 
         projection_labels = self.__make_labels(projection)
 
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py
index c89f003cba7a127aba7b6ba1988a81169cc5e7d9..16f1f8d550a2410b3d471ae0d015d2023b5b967d 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/FlatPlatePaalmanPingsCorrection.py
@@ -1,9 +1,9 @@
 #pylint: disable=no-init,invalid-name
 from mantid.simpleapi import *
 from mantid.api import PythonAlgorithm, AlgorithmFactory, PropertyMode, MatrixWorkspaceProperty, \
-                       WorkspaceGroupProperty
+                       WorkspaceGroupProperty, InstrumentValidator, WorkspaceUnitValidator
 from mantid.kernel import StringListValidator, StringMandatoryValidator, IntBoundedValidator, \
-                          FloatBoundedValidator, Direction, logger
+                          FloatBoundedValidator, Direction, logger, CompositeValidator
 import math, numpy as np
 
 
@@ -20,7 +20,6 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
     _can_number_density = None
     _can_front_thickness = None
     _can_back_thickness = None
-    _can_scale = 1.0
     _number_wavelengths = 10
     _emode = None
     _efixed = 0.0
@@ -39,8 +38,11 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
 
 
     def PyInit(self):
+        ws_validator = CompositeValidator([WorkspaceUnitValidator('Wavelength'), InstrumentValidator()])
+
         self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '',
-                             direction=Direction.Input),
+                             direction=Direction.Input,
+                             validator=ws_validator),
                              doc='Name for the input sample workspace')
 
         self.declareProperty(name='SampleChemicalFormula', defaultValue='',
@@ -57,7 +59,8 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
 
         self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '',
                              direction=Direction.Input,
-                             optional=PropertyMode.Optional),
+                             optional=PropertyMode.Optional,
+                             validator=ws_validator),
                              doc="Name for the input container workspace")
 
         self.declareProperty(name='CanChemicalFormula', defaultValue='',
@@ -73,12 +76,12 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
                              validator=FloatBoundedValidator(0.0),
                              doc='Container back thickness in cm')
 
-        self.declareProperty(name='CanScaleFactor', defaultValue=1.0,
-                             doc='Scale factor to multiply can data')
-
         self.declareProperty(name='NumberWavelengths', defaultValue=10,
                              validator=IntBoundedValidator(1),
                              doc='Number of wavelengths for calculation')
+        self.declareProperty(name='Interpolate', defaultValue=True,
+                             doc='Interpolate the correction workspaces to match the sample workspace')
+
         self.declareProperty(name='Emode', defaultValue='Elastic',
                              validator=StringListValidator(['Elastic', 'Indirect']),
                              doc='Emode: Elastic or Indirect')
@@ -174,6 +177,14 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
             self._add_sample_logs(acc_ws, sample_logs)
             AddSampleLog(Workspace=acc_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws_name))
 
+        if self._interpolate:
+            self._interpolate_corrections(workspaces)
+
+        try:
+            self. _copy_detector_table(workspaces)
+        except RuntimeError:
+            logger.warning('Cannot copy spectra mapping. Check input workspace instrument.')
+
         GroupWorkspaces(InputWorkspaces=','.join(workspaces), OutputWorkspace=self._output_ws_name)
         self.setPropertyValue('OutputWorkspace', self._output_ws_name)
 
@@ -192,11 +203,13 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
         self._can_number_density = self.getProperty('CanNumberDensity').value
         self._can_front_thickness = self.getProperty('CanFrontThickness').value
         self._can_back_thickness = self.getProperty('CanBackThickness').value
-        self._can_scale = self.getProperty('CanScaleFactor').value
 
         self._number_wavelengths = self.getProperty('NumberWavelengths').value
+        self._interpolate = self.getProperty('Interpolate').value
+
         self._emode = self.getPropertyValue('Emode')
         self._efixed = self.getProperty('Efixed').value
+
         self._output_ws_name = self.getPropertyValue('OutputWorkspace')
 
 
@@ -234,6 +247,39 @@ class FlatPlatePaalmanPingsCorrection(PythonAlgorithm):
         DeleteWorkspace(wave_range)
 
 
+    def _interpolate_corrections(self, workspaces):
+        """
+        Performs interpolation on the correction workspaces such that the number of bins
+        matches that of the input sample workspace.
+
+        @param workspaces List of correction workspaces to interpolate
+        """
+
+        for ws in workspaces:
+            SplineInterpolation(WorkspaceToMatch=self._sample_ws_name,
+                                WorkspaceToInterpolate=ws,
+                                OutputWorkspace=ws,
+                                OutputWorkspaceDeriv='')
+
+
+    def _copy_detector_table(self, workspaces):
+        """
+        Copy the detector table from the sample workspaces to the correction workspaces.
+
+        @param workspaces List of correction workspaces
+        """
+
+        instrument = mtd[self._sample_ws_name].getInstrument().getName()
+
+        for ws in workspaces:
+            LoadInstrument(Workspace=ws,
+                           InstrumentName=instrument)
+
+            CopyDetectorMapping(WorkspaceToMatch=self._sample_ws_name,
+                                WorkspaceToRemap=ws,
+                                IndexBySpectrumNumber=True)
+
+
     def _add_sample_logs(self, ws, sample_logs):
         """
         Add a dictionary of logs to a workspace.
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce5d2aa46a2964f13e5a51a15990c675cd733325
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectAnnulusAbsorption.py
@@ -0,0 +1,158 @@
+from mantid.simpleapi import *
+from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress
+from mantid.kernel import StringMandatoryValidator, Direction, logger
+
+
+class IndirectAnnulusAbsorption(DataProcessorAlgorithm):
+
+    def category(self):
+        return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS"
+
+
+    def summary(self):
+        return "Calculates indirect absorption corrections for an annulus sample shape."
+
+
+    def PyInit(self):
+        self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input),
+                             doc='Sample workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional,
+                                                     direction=Direction.Input),
+                             doc='Container workspace.')
+
+        self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data')
+
+        self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
+                             doc='Chemical formula')
+
+        self.declareProperty(name='CanInnerRadius', defaultValue=0.2, doc='Sample radius')
+        self.declareProperty(name='SampleInnerRadius', defaultValue=0.15, doc='Sample radius')
+        self.declareProperty(name='SampleOuterRadius', defaultValue=0.16, doc='Sample radius')
+        self.declareProperty(name='CanOuterRadius', defaultValue=0.22, doc='Sample radius')
+        self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density')
+        self.declareProperty(name='Events', defaultValue=5000, doc='Number of neutron events')
+        self.declareProperty(name='Plot', defaultValue=False, doc='Plot options')
+
+        self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output),
+                             doc='The output corrected workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output,
+                                                     optional=PropertyMode.Optional),
+                             doc='The corrections workspace for scattering and absorptions in sample.')
+
+
+    def PyExec(self):
+        from IndirectCommon import getEfixed, addSampleLogs
+
+        self._setup()
+
+        # Set up progress reporting
+        n_prog_reports = 4
+        if self._can_ws is not None:
+            n_prog_reports += 2
+        prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports)
+
+        prog_reporter.report('Processing sample')
+        efixed = getEfixed(self._sample_ws_name)
+
+        sample_wave_ws = '__sam_wave'
+        ConvertUnits(InputWorkspace=self._sample_ws_name, OutputWorkspace=sample_wave_ws,
+                     Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+        sample_thickness = self._sample_outer_radius - self._sample_inner_radius
+
+        prog_reporter.report('Calculating sample corrections')
+        AnnularRingAbsorption(InputWorkspace=sample_wave_ws,
+                              OutputWorkspace=self._ass_ws,
+                              SampleHeight=3.0,
+                              SampleThickness=sample_thickness,
+                              CanInnerRadius=self._can_inner_radius,
+                              CanOuterRadius=self._can_outer_radius,
+                              SampleChemicalFormula=self._chemical_formula,
+                              SampleNumberDensity=self._number_density,
+                              NumberOfWavelengthPoints=10,
+                              EventsPerPoint=self._events)
+
+        plot_list = [self._output_ws, self._sample_ws_name]
+
+        if self._can_ws is not None:
+            prog_reporter.report('Processing can')
+            can_wave_ws = '__can_wave'
+            ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws,
+                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+            if self._can_scale != 1.0:
+                logger.information('Scaling can by: ' + str(self._can_scale))
+                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')
+
+            prog_reporter.report('Applying can corrections')
+            Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
+            DeleteWorkspace(can_wave_ws)
+
+            plot_list.append(self._can_ws)
+
+        prog_reporter.report('Applying corrections')
+        Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
+        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws, Target='DeltaE',
+                     EMode='Indirect', EFixed=efixed)
+        DeleteWorkspace(sample_wave_ws)
+
+        prog_reporter.report('Recording sample logs')
+        sample_logs = {'sample_shape': 'annulus',
+                       'sample_filename': self._sample_ws_name,
+                       'sample_inner': self._sample_inner_radius,
+                       'sample_outer': self._sample_outer_radius,
+                       'can_inner': self._can_inner_radius,
+                       'can_outer': self._can_outer_radius}
+        addSampleLogs(self._ass_ws, sample_logs)
+        addSampleLogs(self._output_ws, sample_logs)
+
+        if self._can_ws is not None:
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+
+        self.setProperty('OutputWorkspace', self._output_ws)
+
+        # Output the Ass workspace if it is wanted, delete if not
+        if self._ass_ws == '_ass':
+            DeleteWorkspace(self._ass_ws)
+        else:
+            self.setProperty('CorrectionsWorkspace', self._ass_ws)
+
+        if self._plot:
+            from IndirectImport import import_mantidplot
+            mantid_plot = import_mantidplot()
+            mantid_plot.plotSpectrum(plot_list, 0)
+
+
+    def _setup(self):
+        """
+        Get algorithm properties.
+        """
+
+        self._sample_ws_name = self.getPropertyValue('SampleWorkspace')
+        self._can_scale = self.getProperty('CanScaleFactor').value
+        self._chemical_formula = self.getPropertyValue('ChemicalFormula')
+        self._number_density = self.getProperty('SampleNumberDensity').value
+        self._can_inner_radius = self.getProperty('CanInnerRadius').value
+        self._sample_inner_radius = self.getProperty('SampleInnerRadius').value
+        self._sample_outer_radius = self.getProperty('SampleOuterRadius').value
+        self._can_outer_radius = self.getProperty('CanOuterRadius').value
+        self._events = self.getProperty('Events').value
+        self._plot = self.getProperty('Plot').value
+        self._output_ws = self.getPropertyValue('OutputWorkspace')
+
+        self._ass_ws = self.getPropertyValue('CorrectionsWorkspace')
+        if self._ass_ws == '':
+            self._ass_ws = '__ass'
+
+        self._can_ws = self.getPropertyValue('CanWorkspace')
+        if self._can_ws == '':
+            self._can_ws = None
+
+
+# Register algorithm with Mantid
+AlgorithmFactory.subscribe(IndirectAnnulusAbsorption)
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py
new file mode 100644
index 0000000000000000000000000000000000000000..d22e65e0440492c48e4fe33a2c5333bccf2e6785
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectCylinderAbsorption.py
@@ -0,0 +1,145 @@
+from mantid.simpleapi import *
+from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress
+from mantid.kernel import StringMandatoryValidator, Direction, logger
+
+
+class IndirectCylinderAbsorption(DataProcessorAlgorithm):
+
+    def category(self):
+        return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS"
+
+
+    def summary(self):
+        return "Calculates indirect absorption corrections for a cylinder sample shape."
+
+
+    def PyInit(self):
+        self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input),
+                             doc='Sample workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional,
+                                                     direction=Direction.Input),
+                             doc='Container workspace.')
+
+        self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data')
+
+        self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
+                             doc='Chemical formula')
+
+        self.declareProperty(name='SampleRadius', defaultValue=0.5, doc='Sample radius')
+        self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density')
+        self.declareProperty(name='Plot', defaultValue=False, doc='Plot options')
+
+        self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output),
+                             doc='The output corrected workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output,
+                                                     optional=PropertyMode.Optional),
+                             doc='The corrections workspace for scattering and absorptions in sample.')
+
+
+    def PyExec(self):
+        from IndirectCommon import getEfixed, addSampleLogs
+
+        self._setup()
+
+        # Set up progress reporting
+        n_prog_reports = 4
+        if self._can_ws is not None:
+            n_prog_reports += 2
+        prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports)
+
+        prog_reporter.report('Processing sample')
+        efixed = getEfixed(self._sample_ws)
+
+        sample_wave_ws = '__sam_wave'
+        ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws,
+                     Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._number_density)
+
+        prog_reporter.report('Calculating sample corrections')
+        CylinderAbsorption(InputWorkspace=sample_wave_ws,
+                           OutputWorkspace=self._ass_ws,
+                           SampleNumberDensity=self._number_density,
+                           NumberOfWavelengthPoints=10,
+                           CylinderSampleHeight=3.0,
+                           CylinderSampleRadius=self._sample_radius,
+                           NumberOfSlices=1,
+                           NumberOfAnnuli=10)
+
+        plot_list = [self._output_ws, self._sample_ws]
+
+        if self._can_ws is not None:
+            prog_reporter.report('Processing can')
+            can_wave_ws = '__can_wave'
+            ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws,
+                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+            if self._can_scale != 1.0:
+                logger.information('Scaling can by: ' + str(self._can_scale))
+                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')
+
+            prog_reporter.report('Applying can corrections')
+            Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
+            DeleteWorkspace(can_wave_ws)
+
+            plot_list.append(self._can_ws)
+
+        prog_reporter.report('Applying corrections')
+        Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
+        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
+                     Target='DeltaE', EMode='Indirect', EFixed=efixed)
+        DeleteWorkspace(sample_wave_ws)
+
+        prog_reporter.report('Recording sample logs')
+        sample_logs = {'sample_shape': 'cylinder',
+                       'sample_filename': self._sample_ws,
+                       'sample_radius': self._sample_radius}
+        addSampleLogs(self._ass_ws, sample_logs)
+        addSampleLogs(self._output_ws, sample_logs)
+
+        if self._can_ws is not None:
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+
+        self.setProperty('OutputWorkspace', self._output_ws)
+
+        # Output the Ass workspace if it is wanted, delete if not
+        if self._ass_ws == '_ass':
+            DeleteWorkspace(self._ass_ws)
+        else:
+            self.setProperty('CorrectionsWorkspace', self._ass_ws)
+
+        if self._plot:
+            from IndirectImport import import_mantidplot
+            mantid_plot = import_mantidplot()
+            mantid_plot.plotSpectrum(plot_list, 0)
+
+
+    def _setup(self):
+        """
+        Get algorithm properties.
+        """
+
+        self._sample_ws = self.getPropertyValue('SampleWorkspace')
+        self._can_scale = self.getProperty('CanScaleFactor').value
+        self._chemical_formula = self.getPropertyValue('ChemicalFormula')
+        self._number_density = self.getProperty('SampleNumberDensity').value
+        self._sample_radius = self.getProperty('SampleRadius').value
+        self._plot = self.getProperty('Plot').value
+        self._output_ws = self.getPropertyValue('OutputWorkspace')
+
+        self._ass_ws = self.getPropertyValue('CorrectionsWorkspace')
+        if self._ass_ws == '':
+            self._ass_ws = '__ass'
+
+        self._can_ws = self.getPropertyValue('CanWorkspace')
+        if self._can_ws == '':
+            self._can_ws = None
+
+
+# Register algorithm with Mantid
+AlgorithmFactory.subscribe(IndirectCylinderAbsorption)
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py
new file mode 100644
index 0000000000000000000000000000000000000000..0fb3e2c3fe040c9a804c0f2a61a128f5c6febf69
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/IndirectFlatPlateAbsorption.py
@@ -0,0 +1,155 @@
+from mantid.simpleapi import *
+from mantid.api import DataProcessorAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty, PropertyMode, Progress
+from mantid.kernel import StringMandatoryValidator, Direction, logger
+
+
+class IndirectFlatPlateAbsorption(DataProcessorAlgorithm):
+
+    def category(self):
+        return "Workflow\\Inelastic;PythonAlgorithms;CorrectionFunctions\\AbsorptionCorrections;Workflow\\MIDAS"
+
+
+    def summary(self):
+        return "Calculates indirect absorption corrections for a flat sample shape."
+
+
+    def PyInit(self):
+        self.declareProperty(MatrixWorkspaceProperty('SampleWorkspace', '', direction=Direction.Input),
+                             doc='Sample workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CanWorkspace', '', optional=PropertyMode.Optional,
+                                                     direction=Direction.Input),
+                             doc='Container workspace.')
+
+        self.declareProperty(name='CanScaleFactor', defaultValue=1.0, doc='Scale factor to multiply can data')
+
+        self.declareProperty(name='ChemicalFormula', defaultValue='', validator=StringMandatoryValidator(),
+                             doc='Chemical formula')
+
+        self.declareProperty(name='SampleHeight', defaultValue=1.0, doc='Sample height')
+        self.declareProperty(name='SampleWidth', defaultValue=1.0, doc='Sample width')
+        self.declareProperty(name='SampleThickness', defaultValue=0.1, doc='Sample thickness')
+        self.declareProperty(name='ElementSize', defaultValue=0.1, doc='Element size in mm')
+        self.declareProperty(name='SampleNumberDensity', defaultValue=0.1, doc='Sample number density')
+        self.declareProperty(name='Plot', defaultValue=False, doc='Plot options')
+
+        self.declareProperty(MatrixWorkspaceProperty('OutputWorkspace', '', direction=Direction.Output),
+                             doc='The output corrected workspace.')
+
+        self.declareProperty(MatrixWorkspaceProperty('CorrectionsWorkspace', '', direction=Direction.Output,
+                                                     optional=PropertyMode.Optional),
+                             doc='The corrections workspace for scattering and absorptions in sample.')
+
+    def PyExec(self):
+        from IndirectCommon import getEfixed, addSampleLogs
+
+        self._setup()
+
+        # Set up progress reporting
+        n_prog_reports = 4
+        if self._can_ws is not None:
+            n_prog_reports += 2
+        prog_reporter = Progress(self, 0.0, 1.0, n_prog_reports)
+
+        prog_reporter.report('Processing sample')
+        efixed = getEfixed(self._sample_ws)
+
+        sample_wave_ws = '__sam_wave'
+        ConvertUnits(InputWorkspace=self._sample_ws, OutputWorkspace=sample_wave_ws,
+                     Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+        SetSampleMaterial(sample_wave_ws, ChemicalFormula=self._chemical_formula, SampleNumberDensity=self._number_density)
+
+        prog_reporter.report('Calculating sample corrections')
+        FlatPlateAbsorption(InputWorkspace=sample_wave_ws,
+                            OutputWorkspace=self._ass_ws,
+                            SampleHeight=self._sample_height,
+                            SampleWidth=self._sample_width,
+                            SampleThickness=self._sample_thichness,
+                            ElementSize=self._element_size,
+                            EMode='Indirect',
+                            EFixed=efixed,
+                            NumberOfWavelengthPoints=10)
+
+        plot_list = [self._output_ws, self._sample_ws]
+
+        if self._can_ws is not None:
+            prog_reporter.report('Processing can')
+            can_wave_ws = '__can_wave'
+            ConvertUnits(InputWorkspace=self._can_ws, OutputWorkspace=can_wave_ws,
+                         Target='Wavelength', EMode='Indirect', EFixed=efixed)
+
+            if self._can_scale != 1.0:
+                logger.information('Scaling can by: ' + str(self._can_scale))
+                Scale(InputWorkspace=can_wave_ws, OutputWorkspace=can_wave_ws, Factor=self._can_scale, Operation='Multiply')
+
+            prog_reporter.report('Applying can corrections')
+            Minus(LHSWorkspace=sample_wave_ws, RHSWorkspace=can_wave_ws, OutputWorkspace=sample_wave_ws)
+            DeleteWorkspace(can_wave_ws)
+
+            plot_list.append(self._can_ws)
+
+        prog_reporter.report('Applying corrections')
+        Divide(LHSWorkspace=sample_wave_ws, RHSWorkspace=self._ass_ws, OutputWorkspace=sample_wave_ws)
+        ConvertUnits(InputWorkspace=sample_wave_ws, OutputWorkspace=self._output_ws,
+                     Target='DeltaE', EMode='Indirect', EFixed=efixed)
+        DeleteWorkspace(sample_wave_ws)
+
+        prog_reporter.report('Recording sample logs')
+        sample_logs = {'sample_shape': 'flatplate',
+                       'sample_filename': self._sample_ws,
+                       'sample_height': self._sample_height,
+                       'sample_width': self._sample_width,
+                       'sample_thickness': self._sample_thichness,
+                       'element_size': self._element_size}
+        addSampleLogs(self._ass_ws, sample_logs)
+        addSampleLogs(self._output_ws, sample_logs)
+
+        if self._can_ws is not None:
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_filename', LogType='String', LogText=str(self._can_ws))
+            AddSampleLog(Workspace=self._ass_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+            AddSampleLog(Workspace=self._output_ws, LogName='can_scale', LogType='String', LogText=str(self._can_scale))
+
+        self.setProperty('OutputWorkspace', self._output_ws)
+
+        # Output the Ass workspace if it is wanted, delete if not
+        if self._ass_ws == '_ass':
+            DeleteWorkspace(self._ass_ws)
+        else:
+            self.setProperty('CorrectionsWorkspace', self._ass_ws)
+
+        if self._plot:
+            prog_reporter.report('Plotting')
+            from IndirectImport import import_mantidplot
+            mantid_plot = import_mantidplot()
+            mantid_plot.plotSpectrum(plot_list, 0)
+
+
+    def _setup(self):
+        """
+        Get algorithm properties.
+        """
+
+        self._sample_ws = self.getPropertyValue('SampleWorkspace')
+        self._can_scale = self.getProperty('CanScaleFactor').value
+        self._chemical_formula = self.getPropertyValue('ChemicalFormula')
+        self._number_density = self.getProperty('SampleNumberDensity').value
+        self._sample_height = self.getProperty('SampleHeight').value
+        self._sample_width = self.getProperty('SampleWidth').value
+        self._sample_thichness = self.getProperty('SampleThickness').value
+        self._element_size = self.getProperty('ElementSize').value
+        self._plot = self.getProperty('Plot').value
+        self._output_ws = self.getPropertyValue('OutputWorkspace')
+
+        self._ass_ws = self.getPropertyValue('CorrectionsWorkspace')
+        if self._ass_ws == '':
+            self._ass_ws = '__ass'
+
+        self._can_ws = self.getPropertyValue('CanWorkspace')
+        if self._can_ws == '':
+            self._can_ws = None
+
+
+# Register algorithm with Mantid
+AlgorithmFactory.subscribe(IndirectFlatPlateAbsorption)
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py
index 54f19d234c8f282a46e35ef3ccfc0a5946638756..f2bfb1f7a92b9c495c216ef9febdc821e3d550e0 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/SimpleAPITest.py
@@ -4,36 +4,6 @@ from mantid.api import (AlgorithmFactory, AlgorithmProxy, IAlgorithm, IEventWork
 import mantid.simpleapi as simpleapi
 import numpy
 
-import os
-import sys
-
-#======================================================================================================================
-# Helper class for test
-class TemporaryPythonAlgorithm(object):
-    """
-    Dumps the given code to a file in the Python algorithm directory
-    an removes the file in the del method
-    """
-    def __init__(self, name, code):
-        from mantid import config
-        
-        plugin_dirs = config['python.plugins.directories'].split(";")
-        if len(plugin_dirs) == 0:
-            raise RuntimeError("No Python algorithm directories defined")
-        
-        self._pyfile = os.path.join(plugin_dirs[0], name + ".py")
-        alg_file = open(self._pyfile, "w")
-        alg_file.write(code)
-        alg_file.close()
-        
-    def __del__(self):
-        try:
-            os.remove(self._pyfile)
-            pycfile = self._pyfile.replace(".py",".pyc")
-            os.remove(pycfile)
-        except OSError:
-            pass
-
 #======================================================================================================================
 
 class SimpleAPITest(unittest.TestCase):
@@ -218,42 +188,34 @@ FullBinsOnly(Input) *boolean*       Omit the final bin if it's width is smaller
         self.assertTrue('raw' in mtd)
 
     def test_python_alg_can_use_other_python_alg_through_simple_api(self):
-        """
-        Runs a test in a separate process as it requires a reload of the
-        whole mantid module 
-        """
-        src = """
-from mantid.api import PythonAlgorithm, AlgorithmFactory
-import mantid.simpleapi as api
-from mantid.simpleapi import *
-
-class %(name)s(PythonAlgorithm):
+        class SimpleAPIPythonAlgorithm1(PythonAlgorithm):
+            def PyInit(self):
+                pass
+            def PyExec(self):
+                from mantid.simpleapi import SimpleAPIPythonAlgorithm2
+                SimpleAPIPythonAlgorithm2()
+        class SimpleAPIPythonAlgorithm2(PythonAlgorithm):
+            def PyInit(self):
+                pass
+            def PyExec(self):
+                pass
 
-    def PyInit(self):
-        pass
-    def PyExec(self):
-        %(execline1)s
-        %(execline2)s
-        
-AlgorithmFactory.subscribe(%(name)s)
-"""
-        name1 = "SimpleAPIPythonAlgorithm1"
-        name2 = "SimpleAPIPythonAlgorithm2"
-        src1 = src % {"name":name1,"execline1":name2+"()","execline2":"api."+name2+"()"}
-        src2 = src % {"name":name2,"execline1":"pass","execline2":"pass"}
-        a = TemporaryPythonAlgorithm(name1,src1)
-        b = TemporaryPythonAlgorithm(name2,src2)
-        import subprocess
-        # Try to use algorithm 1 to run algorithm 2
-        cmd = sys.executable + ' -c "from mantid.simpleapi import %(name)s;%(name)s()"' % {'name':name1}
+        AlgorithmFactory.subscribe(SimpleAPIPythonAlgorithm1)
+        AlgorithmFactory.subscribe(SimpleAPIPythonAlgorithm2)
+        # ---------------------------------------------------------
+        alg1 = SimpleAPIPythonAlgorithm1()
+        alg1.initialize()
+        # Puts function in simpleapi globals
+        simpleapi_alg1_func = simpleapi._create_algorithm_function("SimpleAPIPythonAlgorithm1", 1, alg1)
+        alg2 = SimpleAPIPythonAlgorithm1()
+        alg2.initialize()
+        # Puts function in simpleapi globals
+        simpleapi._create_algorithm_function("SimpleAPIPythonAlgorithm2", 1, alg2)
         try:
-            subprocess.check_call(cmd,shell=True)
-        except subprocess.CalledProcessError, exc:
-            self.fail("Error occurred running one Python algorithm from another: %s" % str(exc))
-        
-        # Ensure the files are removed promptly
-        del a,b
-        
+            simpleapi_alg1_func()
+        except RuntimeError, exc:
+            self.fail("Running algorithm 2 from 1 failed: " + str(exc))
+
     def test_optional_workspaces_are_ignored_if_not_present_in_output_even_if_given_as_input(self):
         # Test algorithm
         from mantid.api import AlgorithmManager,PropertyMode,PythonAlgorithm,MatrixWorkspaceProperty,WorkspaceFactory
@@ -321,5 +283,23 @@ AlgorithmFactory.subscribe(%(name)s)
         self.assertEquals(alg.version(), version)
         self.assertTrue(isinstance(alg, expected_class))
 
+    def test_validate_inputs_with_errors_stops_algorithm(self):
+        class ValidateInputsTest(PythonAlgorithm):
+            def PyInit(self):
+                self.declareProperty("Prop1", 1.0)
+                self.declareProperty("Prop2", 2.0)
+            def validateInputs(self):
+                return {"Prop1":"Value is less than Prop2"}
+            def PyExec(self):
+                pass
+        AlgorithmFactory.subscribe(ValidateInputsTest)
+        # ---------------------------------------------------------
+        alg_obj = ValidateInputsTest()
+        alg_obj.initialize()
+        
+        simpleapi_func = simpleapi._create_algorithm_function("ValidateInputsTest", 1, alg_obj)
+        # call
+        self.assertRaises(RuntimeError, simpleapi_func, Prop1=2.5, Prop2=3.5)
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py
index 9d2589b121185109da04c40f679576621d1eeef6..203ed1ecb0b930ebf9cc5f7e9b5ec199fd41d1e0 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/mantid/api/CutMDTest.py
@@ -151,11 +151,6 @@ class CutMDTest(unittest.TestCase):
         
         self.assertTrue(isinstance(out_md, IMDHistoWorkspace), "Expect that the output was an IMDHistoWorkspace given the NoPix flag.")
         
-        run = out_md.getExperimentInfo(0).run()
-        w_matrix = run.getLogData("W_MATRIX").value
-        w_matrix = list(w_matrix)
-        self.assertEquals([1,1,0,-1,1,0,0,0,1], w_matrix, "W-matrix should have been set, but should be an identity matrix")
-        
     def test_orthogonal_slice_with_cropping(self):
          # We create a fake workspace and check to see that using bin inputs for cropping works
         to_cut = CreateMDWorkspace(Dimensions=3, Extents=[-1,1,-1,1,-1,1], Names='H,K,L', Units='U,U,U')
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt
index bc814404ca605fb4f612f4d2acc5d62a53d98b4c..efddb15f02b89a8328a43c7fd7b39fe870ae5ba7 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt
@@ -10,6 +10,7 @@ set ( TEST_PY_FILES
   CreateLeBailFitInputTest.py
   CreateCalibrationWorkspaceTest.py
   CreateWorkspaceTest.py
+  CylinderPaalmanPingsCorrectionTest.py
   DakotaChiSquaredTest.py
   DensityOfStatesTest.py
   DSFinterpTest.py
@@ -17,6 +18,9 @@ set ( TEST_PY_FILES
   FindReflectometryLinesTest.py
   FlatPlatePaalmanPingsCorrectionTest.py
   GetEiT0atSNSTest.py
+  IndirectAnnulusAbsorptionTest.py
+  IndirectCylinderAbsorptionTest.py
+  IndirectFlatPlateAbsorptionTest.py
   IndirectILLReductionTest.py
   InelasticIndirectReductionTest.py
   IndirectTransmissionTest.py
@@ -31,6 +35,7 @@ set ( TEST_PY_FILES
   MeanTest.py
   MergeCalFilesTest.py
   MolDynTest.py
+  MSDFitTest.py
   PDDetermineCharacterizationsTest.py
   RetrieveRunInfoTest.py
   SANSWideAngleCorrectionTest.py
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..27955836344d640a0a31f0eab286adac148a61ab
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CylinderPaalmanPingsCorrectionTest.py
@@ -0,0 +1,193 @@
+import unittest
+from mantid.kernel import *
+from mantid.api import *
+from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, CylinderPaalmanPingsCorrection, CreateSimulationWorkspace
+from IndirectImport import is_supported_f2py_platform
+
+
+class CylinderPaalmanPingsCorrectionTest(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Create sample workspaces.
+        """
+
+        # Create some test data
+        sample = CreateSampleWorkspace(NumBanks=1,
+                                            BankPixelWidth=1,
+                                            XUnit='Wavelength',
+                                            XMin=6.8,
+                                            XMax=7.9,
+                                            BinWidth=0.1)
+        self._sample_ws = sample
+
+        can = Scale(InputWorkspace=sample, Factor=1.2)
+        self._can_ws = can
+
+        self._corrections_ws_name = 'corrections'
+
+
+    def tearDown(self):
+        """
+        Remove workspaces from ADS.
+        """
+
+        DeleteWorkspace(self._sample_ws)
+        DeleteWorkspace(self._can_ws)
+
+        if self._corrections_ws_name in mtd:
+            DeleteWorkspace(self._corrections_ws_name)
+
+
+    def _verify_workspace(self, ws_name):
+        """
+        Do validation on a correction workspace.
+
+        @param ws_name Name of workspace to validate
+        """
+
+        corrections_ws = mtd[self._corrections_ws_name]
+
+        # Check it is in the corrections workspace group
+        self.assertTrue(corrections_ws.contains(ws_name))
+
+        test_ws = mtd[ws_name]
+
+        # Check workspace is in wavelength
+        self.assertEqual(test_ws.getAxis(0).getUnit().unitID(),
+                         'Wavelength')
+
+        # Check it has the same number of spectra as the sample
+        self.assertEqual(test_ws.getNumberHistograms(),
+                         self._sample_ws.getNumberHistograms())
+
+        # Check it has X binning matching sample workspace
+        self.assertEqual(test_ws.blocksize(), self._sample_ws.blocksize())
+
+
+    def _verify_workspaces_for_can(self):
+        """
+        Do validation on the additional correction factors for sample and can.
+        """
+
+        ass_ws_name = self._corrections_ws_name + '_ass'
+        assc_ws_name = self._corrections_ws_name + '_assc'
+        acsc_ws_name = self._corrections_ws_name + '_acsc'
+        acc_ws_name = self._corrections_ws_name + '_acc'
+
+        workspaces = [ass_ws_name, assc_ws_name, acsc_ws_name, acc_ws_name]
+
+        for workspace in workspaces:
+            self._verify_workspace(workspace)
+
+
+    def test_sampleOnly(self):
+        """
+        Test simple run with sample workspace only.
+        """
+
+        # Just pass if we can't actually run the algorithm
+        if not is_supported_f2py_platform():
+            return
+
+        CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name,
+                                       SampleWorkspace=self._sample_ws,
+                                       SampleChemicalFormula='H2-O',
+                                       SampleInnerRadius=0.05,
+                                       SampleOuterRadius=0.1,
+                                       Emode='Indirect',
+                                       Efixed=1.845)
+
+        ass_ws_name = self._corrections_ws_name + '_ass'
+        self. _verify_workspace(ass_ws_name)
+
+
+    def test_sampleAndCan(self):
+        """
+        Test simple run with sample and can workspace.
+        """
+
+        # Just pass if we can't actually run the algorithm
+        if not is_supported_f2py_platform():
+            return
+
+        CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name,
+                                       SampleWorkspace=self._sample_ws,
+                                       SampleChemicalFormula='H2-O',
+                                       SampleInnerRadius=0.05,
+                                       SampleOuterRadius=0.1,
+                                       CanWorkspace=self._can_ws,
+                                       CanChemicalFormula='V',
+                                       CanOuterRadius=0.15,
+                                       BeamHeight=0.1,
+                                       BeamWidth=0.1,
+                                       Emode='Indirect',
+                                       Efixed=1.845)
+
+        self._verify_workspaces_for_can()
+
+
+    def test_sampleAndCanDefaults(self):
+        """
+        Test simple run with sample and can workspace using the default values.
+        """
+
+        # Just pass if we can't actually run the algorithm
+        if not is_supported_f2py_platform():
+            return
+
+        CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name,
+                                       SampleWorkspace=self._sample_ws,
+                                       SampleChemicalFormula='H2-O',
+                                       CanWorkspace=self._can_ws,
+                                       CanChemicalFormula='V')
+
+        self._verify_workspaces_for_can()
+
+
+    def test_InterpolateDisabled(self):
+        """
+        Tests that a workspace with a bin count equal to NumberWavelengths is created
+        when interpolation is disabled.
+        """
+
+        # Just pass if we can't actually run the algorithm
+        if not is_supported_f2py_platform():
+            return
+
+        CylinderPaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name,
+                                       SampleWorkspace=self._sample_ws,
+                                       SampleChemicalFormula='H2-O',
+                                       CanWorkspace=self._can_ws,
+                                       CanChemicalFormula='V',
+                                       Interpolate=False)
+
+        corrections_ws = mtd[self._corrections_ws_name]
+
+        # Check each correction workspace has X binning matching NumberWavelengths
+        for workspace in corrections_ws:
+            self.assertEqual(workspace.blocksize(), 10)
+
+
+    def test_validationNoCanFormula(self):
+        """
+        Tests validation for no chemical formula for can when a can WS is provided.
+        """
+
+        self.assertRaises(RuntimeError,
+                          CylinderPaalmanPingsCorrection,
+                          OutputWorkspace=self._corrections_ws_name,
+                          SampleWorkspace=self._sample_ws,
+                          SampleChemicalFormula='H2-O',
+                          SampleInnerRadius=0.05,
+                          SampleOuterRadius=0.1,
+                          CanWorkspace=self._can_ws,
+                          CanOuterRadius=0.15,
+                          BeamHeight=0.1,
+                          BeamWidth=0.1,
+                          Emode='Indirect',
+                          Efixed=1.845)
+
+
+if __name__=="__main__":
+    unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py
index a397c69d3458d038fe6e2cc5caf9d53afd088ff4..13732907fdfc99f888071f0d58b0414d6ffbcf83 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/FlatPlatePaalmanPingsCorrectionTest.py
@@ -1,7 +1,7 @@
 import unittest
 from mantid.kernel import *
 from mantid.api import *
-from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, FlatPlatePaalmanPingsCorrection
+from mantid.simpleapi import CreateSampleWorkspace, Scale, DeleteWorkspace, FlatPlatePaalmanPingsCorrection, CreateSimulationWorkspace
 
 
 class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase):
@@ -11,12 +11,13 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase):
         Create sample workspaces.
         """
 
-        sample = CreateSampleWorkspace(NumBanks=5,
-                                       BankPixelWidth=2,
-                                       XUnit='Wavelength',
-                                       XMin=6.8,
-                                       XMax=7.9,
-                                       BinWidth=0.1)
+        # Create some test data
+        sample = CreateSampleWorkspace(NumBanks=1,
+                                            BankPixelWidth=1,
+                                            XUnit='Wavelength',
+                                            XMin=6.8,
+                                            XMax=7.9,
+                                            BinWidth=0.1)
         self._sample_ws = sample
 
         can = Scale(InputWorkspace=sample, Factor=1.2)
@@ -59,8 +60,8 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase):
         self.assertEqual(test_ws.getNumberHistograms(),
                          self._sample_ws.getNumberHistograms())
 
-        # Check it has X binning matching NumWavelengths
-        self.assertEqual(test_ws.blocksize(), 10)
+        # Check it has X binning matching sample workspace
+        self.assertEqual(test_ws.blocksize(), self._sample_ws.blocksize())
 
 
     def _verify_workspaces_for_can(self):
@@ -132,6 +133,27 @@ class FlatPlatePaalmanPingsCorrectionTest(unittest.TestCase):
         self._verify_workspaces_for_can()
 
 
+    def test_InterpolateDisabled(self):
+        """
+        Tests that a workspace with a bin count equal to NumberWavelengths is created
+        when interpolation is disabled.
+        """
+
+        FlatPlatePaalmanPingsCorrection(OutputWorkspace=self._corrections_ws_name,
+                                        SampleWorkspace=self._sample_ws,
+                                        SampleChemicalFormula='H2-O',
+                                        CanWorkspace=self._can_ws,
+                                        CanChemicalFormula='V',
+                                        NumberWavelengths=20,
+                                        Interpolate=False)
+
+        corrections_ws = mtd[self._corrections_ws_name]
+
+        # Check each correction workspace has X binning matching NumberWavelengths
+        for workspace in corrections_ws:
+            self.assertEqual(workspace.blocksize(), 20)
+
+
     def test_validationNoCanFormula(self):
         """
         Tests validation for no chemical formula for can when a can WS is provided.
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..115a9f241e98ea38b8858ff85698a0f8c2c31001
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectAnnulusAbsorptionTest.py
@@ -0,0 +1,91 @@
+import unittest
+from mantid.simpleapi import *
+from mantid.api import *
+
+
+class IndirectAnnulusAbsorptionTest(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Loads the reduced container and sample files.
+        """
+
+        can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+        red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+
+        self._can_ws = can_ws
+        self._red_ws = red_ws
+
+
+    def _test_workspaces(self, corrected, ass):
+        """
+        Checks the units of the Ass and corrected workspaces.
+
+        @param corrected Corrected workspace
+        @param ass Assc corrections workspace
+        """
+
+        corrected_x_unit = corrected.getAxis(0).getUnit().unitID()
+        self.assertEqual(corrected_x_unit, 'DeltaE')
+
+        ass_x_unit = ass.getAxis(0).getUnit().unitID()
+        self.assertEquals(ass_x_unit, 'Wavelength')
+
+        ass_y_unit = ass.YUnitLabel()
+        self.assertEqual(ass_y_unit, 'Attenuation factor')
+
+
+    def test_sample_corrections_only(self):
+        """
+        Tests corrections for the sample only.
+        """
+
+        corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws,
+                                                   ChemicalFormula='H2-O',
+                                                   CanInnerRadius=0.2,
+                                                   SampleInnerRadius=0.15,
+                                                   SampleOuterRadius=0.16,
+                                                   CanOuterRadius=0.22,
+                                                   Events=200)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction(self):
+        """
+        Tests corrections for the sample and simple container subtraction.
+        """
+
+        corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws,
+                                                   CanWorkspace=self._can_ws,
+                                                   ChemicalFormula='H2-O',
+                                                   CanInnerRadius=0.2,
+                                                   SampleInnerRadius=0.15,
+                                                   SampleOuterRadius=0.16,
+                                                   CanOuterRadius=0.22,
+                                                   Events=200)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction_with_scale(self):
+        """
+        Tests corrections for the sample and simple container subtraction
+        with can scale.
+        """
+
+        corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=self._red_ws,
+                                                   CanWorkspace=self._can_ws,
+                                                   CanScaleFactor=0.8,
+                                                   ChemicalFormula='H2-O',
+                                                   CanInnerRadius=0.2,
+                                                   SampleInnerRadius=0.15,
+                                                   SampleOuterRadius=0.16,
+                                                   CanOuterRadius=0.22,
+                                                   Events=200)
+
+        self._test_workspaces(corrected, ass)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..d97057f84b35b200c284825f0ce5bfb3910f8023
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectCylinderAbsorptionTest.py
@@ -0,0 +1,79 @@
+import unittest
+from mantid.simpleapi import *
+from mantid.api import *
+
+
+class IndirectCylinderAbsorptionTest(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Loads the reduced container and sample files.
+        """
+
+        can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+        red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+
+        self._can_ws = can_ws
+        self._red_ws = red_ws
+
+
+    def _test_workspaces(self, corrected, ass):
+        """
+        Checks the units of the Ass and corrected workspaces.
+
+        @param corrected Corrected workspace
+        @param ass Assc corrections workspace
+        """
+
+        corrected_x_unit = corrected.getAxis(0).getUnit().unitID()
+        self.assertEqual(corrected_x_unit, 'DeltaE')
+
+        ass_x_unit = ass.getAxis(0).getUnit().unitID()
+        self.assertEquals(ass_x_unit, 'Wavelength')
+
+        ass_y_unit = ass.YUnitLabel()
+        self.assertEqual(ass_y_unit, 'Attenuation factor')
+
+
+    def test_sample_corrections_only(self):
+        """
+        Tests corrections for the sample only.
+        """
+
+        corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws,
+                                                    ChemicalFormula='H2-O',
+                                                    SampleRadius=0.2)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction(self):
+        """
+        Tests corrections for the sample and simple container subtraction.
+        """
+
+        corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws,
+                                                    CanWorkspace=self._can_ws,
+                                                    ChemicalFormula='H2-O',
+                                                    SampleRadius=0.2)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction_with_scale(self):
+        """
+        Tests corrections for the sample and simple container subtraction
+        with can scale.
+        """
+
+        corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=self._red_ws,
+                                                    CanWorkspace=self._can_ws,
+                                                    CanScaleFactor=0.8,
+                                                    ChemicalFormula='H2-O',
+                                                    SampleRadius=0.2)
+
+        self._test_workspaces(corrected, ass)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..829d8688e685f955632b17e9c86835d4557b4ab2
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/IndirectFlatPlateAbsorptionTest.py
@@ -0,0 +1,88 @@
+import unittest
+from mantid.simpleapi import *
+from mantid.api import *
+
+
+class IndirectFlatPlateAbsorptionTest(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Loads the reduced container and sample files.
+        """
+
+        can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+        red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+
+        self._can_ws = can_ws
+        self._red_ws = red_ws
+
+
+    def _test_workspaces(self, corrected, ass):
+        """
+        Checks the units of the Ass and corrected workspaces.
+
+        @param corrected Corrected workspace
+        @param ass Assc corrections workspace
+        """
+
+        corrected_x_unit = corrected.getAxis(0).getUnit().unitID()
+        self.assertEqual(corrected_x_unit, 'DeltaE')
+
+        ass_x_unit = ass.getAxis(0).getUnit().unitID()
+        self.assertEquals(ass_x_unit, 'Wavelength')
+
+        ass_y_unit = ass.YUnitLabel()
+        self.assertEqual(ass_y_unit, 'Attenuation factor')
+
+
+    def test_sample_corrections_only(self):
+        """
+        Tests corrections for the sample only.
+        """
+
+        corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws,
+                                                     ChemicalFormula='H2-O',
+                                                     SampleHeight=1,
+                                                     SampleWidth=1,
+                                                     SampleThickness=1,
+                                                     ElementSize=1)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction(self):
+        """
+        Tests corrections for the sample and simple container subtraction.
+        """
+
+        corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws,
+                                                     CanWorkspace=self._can_ws,
+                                                     ChemicalFormula='H2-O',
+                                                     SampleHeight=1,
+                                                     SampleWidth=1,
+                                                     SampleThickness=1,
+                                                     ElementSize=1)
+
+        self._test_workspaces(corrected, ass)
+
+
+    def test_sample_and_can_subtraction_with_scale(self):
+        """
+        Tests corrections for the sample and simple container subtraction
+        with can scale.
+        """
+
+        corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=self._red_ws,
+                                                     CanWorkspace=self._can_ws,
+                                                     CanScaleFactor=0.8,
+                                                     ChemicalFormula='H2-O',
+                                                     SampleHeight=1,
+                                                     SampleWidth=1,
+                                                     SampleThickness=1,
+                                                     ElementSize=1)
+
+        self._test_workspaces(corrected, ass)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py
index 576a0bbf5e5c922f1310071f189b006c377124f8..ef51954f33eb75801cbdd116de8c1f1f37c8e997 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/InelasticIndirectReductionTest.py
@@ -11,8 +11,7 @@ class InelasticIndirectReductionTest(unittest.TestCase):
                                    Instrument='IRIS',
                                    Analyser='graphite',
                                    Reflection='002',
-                                   DetectorRange=[3, 53],
-                                   SaveFormats=['nxs'])
+                                   DetectorRange=[3, 53])
 
         reduction_workspace = mtd['IndirectReductions'].getItem(0)
         self.assertEquals(reduction_workspace.getName(), 'irs26176_graphite002_red')
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..d34b9936dbf6ac32446c0ffc4cfca645622f7edc
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/MSDFitTest.py
@@ -0,0 +1,135 @@
+import unittest
+from mantid.simpleapi import *
+from mantid.api import *
+
+class MSDFitTest(unittest.TestCase):
+
+    def setUp(self):
+        """
+        Creates a sample workspace for testing.
+        """
+
+        sample = CreateSampleWorkspace(Function='User Defined',
+                        UserDefinedFunction='name=ExpDecay,Height=1,Lifetime=6',
+                        NumBanks=5, BankPixelWidth=1, XUnit='QSquared', XMin=0.0,
+                        XMax=5.0, BinWidth=0.1)
+        self._ws = sample
+
+
+    def _validate_workspaces(self, msd_ws, param_ws, fit_ws):
+        """
+        Validates the various workspaces produced by MSDFit.
+
+        @param msd_ws The MSD workspace
+        @param param_ws The fit parameter table workspace
+        @param fit_ws The fit workspace group
+        """
+
+        # First validate workspace types
+        self.assertTrue(isinstance(msd_ws, WorkspaceGroup), 'MSD workspace should be a WorkspaceGroup')
+        self.assertTrue(isinstance(param_ws, ITableWorkspace), 'Fit parameter workspace should be a TableWorkspace')
+        self.assertTrue(isinstance(fit_ws, WorkspaceGroup), 'Fit workspace should be a WorkspaceGroup')
+
+        # Validate number of items in groups
+        self.assertEqual(msd_ws.getNumberOfEntries(), 2)
+        self.assertEqual(fit_ws.getNumberOfEntries(), 5)
+
+        # Validate MSD property workspaces
+        self.assertEqual(msd_ws[0].name(), 'msd_A0')
+        self.assertEqual(msd_ws[1].name(), 'msd_A1')
+        self.assertEqual(len(msd_ws[0].readX(0)), 5)
+        self.assertEqual(len(msd_ws[1].readX(0)), 5)
+
+
+    def test_basic_run(self):
+        """
+        Tests a basic run providing the MSD workspace as output.
+        """
+
+        MSDFit(InputWorkspace=self._ws,
+               XStart=0.0, XEnd=5.0,
+               SpecMin=0, SpecMax=4,
+               OutputWorkspace='msd')
+
+        self.assertTrue(mtd.doesExist('msd_Parameters'), 'Should have a parameter WS with the default name')
+        self.assertTrue(mtd.doesExist('msd_Workspaces'), 'Should have a fit WS with the default name')
+        self._validate_workspaces(mtd['msd'], mtd['msd_Parameters'], mtd['msd_Workspaces'])
+
+
+    def test_basic_run_given_names(self):
+        """
+        Tests a basic run providing names of all output workspaces.
+        """
+
+        msd, param, fit = MSDFit(InputWorkspace=self._ws,
+                                 XStart=0.0, XEnd=5.0,
+                                 SpecMin=0, SpecMax=4)
+
+        self._validate_workspaces(msd, param, fit)
+
+
+    def test_fail_spec_min(self):
+        """
+        Tests validation for SpecMin >= 0.
+        """
+
+        with self.assertRaises(RuntimeError):
+            msd, param, fit = MSDFit(InputWorkspace=self._ws,
+                                     XStart=0.0, XEnd=5.0,
+                                     SpecMin=-1, SpecMax=0)
+
+
+    def test_fail_spec_min(self):
+        """
+        Tests validation for SpecMin >= num histograms.
+        """
+
+        self.assertRaises(RuntimeError,
+                          MSDFit,
+                          InputWorkspace=self._ws,
+                          XStart=0.0, XEnd=5.0,
+                          SpecMin=0, SpecMax=20,
+                          OutputWorkspace='msd')
+
+
+    def test_fail_spec_range(self):
+        """
+        Test svalidation for SpecMax >= SpecMin.
+        """
+
+        self.assertRaises(RuntimeError,
+                          MSDFit,
+                          InputWorkspace=self._ws,
+                          XStart=0.0, XEnd=5.0,
+                          SpecMin=1, SpecMax=0,
+                          OutputWorkspace='msd')
+
+
+    def test_fail_x_range(self):
+        """
+        Tests validation for XStart < XEnd.
+        """
+
+        self.assertRaises(RuntimeError,
+                          MSDFit,
+                          InputWorkspace=self._ws,
+                          XStart=10.0, XEnd=5.0,
+                          SpecMin=0, SpecMax=0,
+                          OutputWorkspace='msd')
+
+
+    def test_fail_x_range_ws(self):
+        """
+        Tests validation for X range in workspace range
+        """
+
+        self.assertRaises(RuntimeError,
+                          MSDFit,
+                          InputWorkspace=self._ws,
+                          XStart=0.0, XEnd=20.0,
+                          SpecMin=0, SpecMax=0,
+                          OutputWorkspace='msd')
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
index 602776597d710b18448930039d26f8a3cd4e0dd7..f8a69de9bc935c4dbc9c5d2d8eb30a4c3b164dea 100644
--- a/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
+++ b/Code/Mantid/Framework/TestHelpers/inc/MantidTestHelpers/MDEventsTestHelper.h
@@ -47,7 +47,8 @@ createDiffractionEventWorkspace(int numEvents, int numPixels = 400,
  * @return MDEW sptr
  */
 Mantid::MDEvents::MDEventWorkspace3Lean::sptr
-makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents = 10000);
+makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents = 10000,
+                   Kernel::SpecialCoordinateSystem coord = Kernel::None);
 
 /// Make a fake n-dimensional MDHistoWorkspace
 Mantid::MDEvents::MDHistoWorkspace_sptr
diff --git a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
index 22950faaa81aac46ed6da35937b2e1fca03e3b9b..6fa5be11b7fcf19742f7bfd2dfcb6770dc9845be 100644
--- a/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
+++ b/Code/Mantid/Framework/TestHelpers/src/MDEventsTestHelper.cpp
@@ -128,11 +128,13 @@ createDiffractionEventWorkspace(int numEvents, int numPixels, int numBins) {
  * @return MDEW sptr
  */
 MDEventWorkspace3Lean::sptr
-makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents) {
+makeFileBackedMDEW(std::string wsName, bool fileBacked, long numEvents,
+                   Kernel::SpecialCoordinateSystem coord) {
   // ---------- Make a file-backed MDEventWorkspace -----------------------
   std::string snEvents = boost::lexical_cast<std::string>(numEvents);
   MDEventWorkspace3Lean::sptr ws1 =
       MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 0);
+  ws1->setCoordinateSystem(coord);
   ws1->getBoxController()->setSplitThreshold(100);
   Mantid::API::AnalysisDataService::Instance().addOrReplace(
       wsName, boost::dynamic_pointer_cast<Mantid::API::IMDEventWorkspace>(ws1));
diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
index e9434bad68020a893aae67cce4e44c7ceba208bf..0b3aec0e978ddaed67e8a25d86faca8eac6d5247 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/MantidDock.cpp
@@ -582,7 +582,6 @@ void MantidDockWidget::addMDEventWorkspaceMenuItems(QMenu *menu, const Mantid::A
   menu->addAction(m_showHist);  // Algorithm history
   menu->addAction(m_showListData); // Show data in table
   menu->addAction(m_showLogs);
-  menu->addAction(m_showSampleMaterial); //TODO
 }
 
 void MantidDockWidget::addMDHistoWorkspaceMenuItems(QMenu *menu, const Mantid::API::IMDWorkspace_const_sptr &WS) const
@@ -604,7 +603,6 @@ void MantidDockWidget::addMDHistoWorkspaceMenuItems(QMenu *menu, const Mantid::A
   menu->addAction(m_showListData); // Show data in table
   menu->addAction(m_convertMDHistoToMatrixWorkspace);
   menu->addAction(m_showLogs);
-  menu->addAction(m_showSampleMaterial); //TODO
 }
 
 
diff --git a/Code/Mantid/MantidPlot/src/Mantid/MantidSampleMaterialDialog.cpp b/Code/Mantid/MantidPlot/src/Mantid/MantidSampleMaterialDialog.cpp
index e502f07218a3565449216b886bc86921b58f6c23..7ae2bb94d518300ddccea9f19f1ade8f5d4eb3cb 100644
--- a/Code/Mantid/MantidPlot/src/Mantid/MantidSampleMaterialDialog.cpp
+++ b/Code/Mantid/MantidPlot/src/Mantid/MantidSampleMaterialDialog.cpp
@@ -40,6 +40,9 @@ MantidSampleMaterialDialog::MantidSampleMaterialDialog(const QString & wsName, M
 void MantidSampleMaterialDialog::updateMaterial()
 {
   MatrixWorkspace_sptr ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(m_wsName.toStdString());
+  if(!ws)
+    return;
+
   const Material material = ws->sample().getMaterial();
 
   m_uiForm.treeMaterialProperties->clear();
diff --git a/Code/Mantid/MantidPlot/src/PlotDialog.cpp b/Code/Mantid/MantidPlot/src/PlotDialog.cpp
index 839fd3f965baed883d4665401e262490c10d4a65..f2519bdc5117641ef344ea6fede0b6f21bbea9ec 100644
--- a/Code/Mantid/MantidPlot/src/PlotDialog.cpp
+++ b/Code/Mantid/MantidPlot/src/PlotDialog.cpp
@@ -1596,15 +1596,14 @@ void PlotDialog::updateTabWindow(QTreeWidgetItem *currentItem, QTreeWidgetItem *
   if (currentItem->type() == CurveTreeItem::PlotCurveTreeItem)
   {
     CurveTreeItem *curveItem = dynamic_cast<CurveTreeItem *>(currentItem);
-    if (!curveItem)
+    if (!curveItem) {
+      boxPlotType->blockSignals(false);
       return;
+    }
 
     CurveTreeItem *pi = dynamic_cast<CurveTreeItem *>(previousItem);
-    if (!pi)
-      return;
-
     if (previousItem->type() != CurveTreeItem::PlotCurveTreeItem
-        || pi->plotItemType() != curveItem->plotItemType()
+        || (pi && pi->plotItemType() != curveItem->plotItemType())
         || forceClearTabs)
     {
       clearTabWidget();
diff --git a/Code/Mantid/MantidPlot/src/Spectrogram.cpp b/Code/Mantid/MantidPlot/src/Spectrogram.cpp
index ed8eef7ce6e26f89fb72ca9c3fd32c8f24eb1588..413ab6d07ea9bafe861bcae1f00c011a6c7c60f4 100644
--- a/Code/Mantid/MantidPlot/src/Spectrogram.cpp
+++ b/Code/Mantid/MantidPlot/src/Spectrogram.cpp
@@ -35,11 +35,15 @@
 #include <qwt_scale_engine.h>
 #include <QPainter>
 #include <qwt_symbol.h>
+
 #include "Mantid/MantidMatrix.h"
 #include "Mantid/MantidMatrixFunction.h"
+#include "MantidAPI/IMDIterator.h"
+
+#include "MantidQtAPI/PlotAxis.h"
 #include "MantidQtAPI/QwtRasterDataMD.h"
 #include "MantidQtAPI/SignalRange.h"
-#include "MantidAPI/IMDIterator.h"
+
 #include "TSVSerialiser.h"
 
 #include <iostream>
@@ -266,6 +270,17 @@ void Spectrogram::postDataUpdate()
 
   plot->setAxisScale(color_axis, data().range().minValue(), data().range().maxValue());
 
+  if ( d_wsData )
+  {
+    auto workspace = d_wsData->getWorkspace();
+    if ( workspace )
+    {
+      using MantidQt::API::PlotAxis;
+      plot->setAxisTitle(QwtPlot::xBottom,  PlotAxis(*workspace, 0).title());
+      plot->setAxisTitle(QwtPlot::yLeft, PlotAxis(*workspace, 1).title());
+    }
+  }
+
   plot->replot();
 }
 
diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h
index 40c0ae9e8547f6823f1b2f677cef38a240b32723..a8a8e87cab0dc97a605399f6d61cd6ec5faa5ec8 100644
--- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h
+++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/MdSettings.h
@@ -65,7 +65,7 @@ namespace MantidQt
 
         /** 
           * Set the LastSession color map
-          * @param colormap The colormap for the VSI.
+          * @param colorMap The colormap for the VSI.
           */
         void setLastSessionColorMap(QString colorMap);
 
diff --git a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h
index 8cd434537d5947de889dccc6b4abcbff8417889e..0297da3fd1b19c9ed12084367c1dfd74ad898d6e 100644
--- a/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h
+++ b/Code/Mantid/MantidQt/API/inc/MantidQtAPI/QwtRasterDataMD.h
@@ -36,6 +36,7 @@ public:
   QwtRasterDataMD* copy() const;
 
   virtual void setWorkspace(Mantid::API::IMDWorkspace_const_sptr ws);
+  Mantid::API::IMDWorkspace_const_sptr getWorkspace() const;
 
   void setOverlayWorkspace(Mantid::API::IMDWorkspace_const_sptr ws);
 
diff --git a/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp b/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp
index 897926b8bc072d7884f2eb30e4b68a39e27792de..1a1267c3382f48eaee3cea268e10658fbcee43c6 100644
--- a/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp
+++ b/Code/Mantid/MantidQt/API/src/QwtRasterDataMD.cpp
@@ -199,6 +199,14 @@ void QwtRasterDataMD::setWorkspace(IMDWorkspace_const_sptr ws)
   m_slicePoint = new coord_t[m_nd];
 }
 
+//------------------------------------------------------------------------------------------------------
+/** Gets the workspace being displayed
+ */
+Mantid::API::IMDWorkspace_const_sptr QwtRasterDataMD::getWorkspace() const
+{
+  return m_ws;
+}
+
 //------------------------------------------------------------------------------------------------------
 /** Sets the workspace that will be displayed ON TOP of the original workspace.
  * For dynamic rebinning.
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc b/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc
index a9dba762f557dc591637a434ab628092634b27c5..d6f4340e93961cc9ac7f00cb763d6ad1ded4af40 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc
+++ b/Code/Mantid/MantidQt/CustomInterfaces/icons/CustomInterfacesIcons.qrc
@@ -2,5 +2,6 @@
     <qresource prefix="/MultiDatasetFit/icons">
         <file>zoom.png</file>
         <file>panning.png</file>
+        <file>range.png</file>
     </qresource>
 </RCC>
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png b/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png
new file mode 100644
index 0000000000000000000000000000000000000000..3c1552f3b6376019dfec585084bdadea76c6cc26
Binary files /dev/null and b/Code/Mantid/MantidQt/CustomInterfaces/icons/range.png differ
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui
index 4329c2f27e0825e1d4fd665df56f2836ba3b6abb..6ec1670e1868361294f35eff5b84a65fd214d164 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/CalcCorr.ui
@@ -209,7 +209,7 @@
            <number>1</number>
           </property>
           <property name="currentIndex">
-           <number>1</number>
+           <number>0</number>
           </property>
           <widget class="QWidget" name="pageFlat">
            <layout class="QVBoxLayout" name="verticalLayout_4">
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h
index 1c6750a08434ed347528256c1637a1fcac3422ae..2664203f1fc7f8d0aa4341d4e4a5a252938ae462 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/Indirect/IndirectTab.h
@@ -42,7 +42,9 @@ namespace MantidQt
 {
 namespace CustomInterfaces
 {
-  /** IndirectTab : TODO: DESCRIPTION
+  /** IndirectTab
+
+    Provided common functionality of all indirect interface tabs.
 
     @author Dan Nixon
     @date 08/10/2014
@@ -90,9 +92,13 @@ namespace CustomInterfaces
     bool loadFile(const QString& filename, const QString& outputName, const int specMin = -1, const int specMax = -1);
 
     /// Function to set the range limits of the plot
-    void setPlotPropertyRange(const QString& rsID, QtProperty* min, QtProperty* max, const QPair<double, double> & bounds);
+    void setPlotPropertyRange(MantidQt::MantidWidgets::RangeSelector * rs,
+                              QtProperty* min, QtProperty* max,
+                              const QPair<double, double> & bounds);
     /// Function to set the range selector on the mini plot
-    void setRangeSelector(const QString& rsID, QtProperty* lower, QtProperty* upper, const QPair<double, double> & bounds);
+    void setRangeSelector(MantidQt::MantidWidgets::RangeSelector * rs,
+                          QtProperty* lower, QtProperty* upper,
+                          const QPair<double, double> & bounds);
 
     /// Function to run an algorithm on a seperate thread
     void runAlgorithm(const Mantid::API::IAlgorithm_sptr algorithm);
@@ -102,8 +108,6 @@ namespace CustomInterfaces
     /// Parent QWidget (if applicable)
     QWidget *m_parentWidget;
 
-    /// Range selector widget for mini plot
-    std::map<QString, MantidQt::MantidWidgets::RangeSelector *> m_rangeSelectors;
     /// Tree of the properties
     std::map<QString, QtTreePropertyBrowser *> m_propTrees;
 
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h
index b87017e4256ad7a5342f924495724fcb2140b6ad..e7bb2158cd7eaf37893eeb56c29f97fbfd299a89 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.h
@@ -1,6 +1,7 @@
 #ifndef MULTIDATASETFIT_H_
 #define MULTIDATASETFIT_H_
 
+#include "MantidQtCustomInterfaces/DllConfig.h"
 #include "MantidQtAPI/UserSubWindow.h"
 #include "MantidAPI/AlgorithmObserver.h"
 #include "MantidQtAPI/WorkspaceObserver.h"
@@ -27,6 +28,7 @@ namespace API
 {
   class IFunction;
   class IAlgorithm;
+  class MatrixWorkspace;
 }
 }
 
@@ -37,6 +39,7 @@ namespace MantidQt
 namespace MantidWidgets
 {
   class FunctionBrowser;
+  class RangeSelector;
   class FitOptionsBrowser;
 }
 
@@ -51,13 +54,14 @@ namespace CustomInterfaces
 // Forward declarations
 class PlotController;
 class DatasetPlotData;
+class DataController;
 
 /**
  * Class MultiDatasetFitDialog implements a dialog for setting up a multi-dataset fit
  * and displaying the results.
  */
 
-class MultiDatasetFit: public API::UserSubWindow
+class MANTIDQT_CUSTOMINTERFACES_DLL MultiDatasetFit: public API::UserSubWindow
 {
   Q_OBJECT
 public:
@@ -74,6 +78,8 @@ public:
   std::string getWorkspaceName(int i) const;
   /// Workspace index of the i-th spectrum
   int getWorkspaceIndex(int i) const;
+  /// Get the fitting range for the i-th spectrum
+  std::pair<double,double> getFittingRange(int i) const;
   /// Total number of spectra (datasets).
   int getNumberOfSpectra() const;
   /// Get value of a local parameter
@@ -83,21 +89,18 @@ public:
   /// Check that the data sets in the table are valid
   void checkDataSets();
 
-signals:
-  void dataTableUpdated();
-
 public slots:
   void setLocalParameterValue(const QString& parName, int i, double value);
   void reset();
 
 private slots:
-  void addWorkspace();
-  void workspaceSelectionChanged();
-  void removeSelectedSpectra();
   void fit();
   void editLocalParameterValues(const QString& parName);
   void finishFit(bool);
   void updateLocalParameters(int index);
+  void enableZoom();
+  void enablePan();
+  void enableRange();
 
 protected:
   /// To be overridden to set the appropriate layout
@@ -105,7 +108,6 @@ protected:
 
 private:
   void createPlotToolbar();
-  void addWorkspaceSpectrum(const QString &wsName, int wsIndex);
   boost::shared_ptr<Mantid::API::IFunction> createFunction() const;
   void initLocalParameter(const QString& parName)const;
   void updateParameters(const Mantid::API::IFunction& fun);
@@ -122,6 +124,8 @@ private:
   Ui::MultiDatasetFit m_uiForm;
   /// Controls the plot and plotted data.
   PlotController *m_plotController;
+  /// Contains all logic of dealing with data sets.
+  DataController *m_dataController;
   /// Function editor
   MantidWidgets::FunctionBrowser *m_functionBrowser;
   /// Browser for setting other Fit properties
@@ -175,26 +179,45 @@ public:
   int getCurrentIndex() const {return m_currentIndex;}
   bool isZoomEnabled() const;
   bool isPanEnabled() const;
+  bool isRangeSelectorEnabled() const;
 signals:
   void currentIndexChanged(int);
+  void fittingRangeChanged(int, double, double);
 public slots:
   void enableZoom();
   void enablePan();
+  void enableRange();
+  void updateRange(int index);
 private slots:
   void tableUpdated();
   void prevPlot();
   void nextPlot();
   void plotDataSet(int);
+  void updateFittingRange(double startX, double endX);
 private:
   MultiDatasetFit *owner() const {return static_cast<MultiDatasetFit*>(parent());}
+  void disableAllTools();
+  template<class Tool>
+  void enableTool(Tool* tool, int cursor);
+  bool eventFilter(QObject *widget, QEvent *evn);
+  void resetRange();
+  void zoomToRange();
+  boost::shared_ptr<DatasetPlotData> getData(int i);
+
   /// The plot widget
   QwtPlot *m_plot;
+
+  ///@name Plot tools
+  ///@{
   /// The zoomer
   QwtPlotZoomer *m_zoomer;
   /// The panner
   QwtPlotPanner *m_panner;
   /// The magnifier
   QwtPlotMagnifier *m_magnifier;
+  /// The fitting range selector
+  MantidWidgets::RangeSelector* m_rangeSelector;
+  ///@}
 
   /// The workspace table
   QTableWidget *m_table;
@@ -224,7 +247,49 @@ private:
   QString m_parName;
 };
 
+/*==========================================================================================*/
+/**
+  * A class for controlling the plot widget and the displayed data.
+  */
+class DataController: public QObject
+{
+  Q_OBJECT
+public:
+  DataController(MultiDatasetFit *parent, QTableWidget *dataTable);
+  std::string getWorkspaceName(int i) const;
+  int getWorkspaceIndex(int i) const;
+  int getNumberOfSpectra() const;
+  void checkDataSets();
+  std::pair<double,double> getFittingRange(int i) const;
+
+signals:
+  void dataTableUpdated();
+  void dataSetUpdated(int i);
+  void hasSelection(bool);
+
+public slots:
+  void setFittingRangeGlobal(bool);
+  void setFittingRange(int, double, double);
+
+private slots:
+  void addWorkspace();
+  void workspaceSelectionChanged();
+  void removeSelectedSpectra();
+  void updateDataset(int, int);
+
+private:
+  MultiDatasetFit *owner() const {return static_cast<MultiDatasetFit*>(parent());}
+  void addWorkspaceSpectrum(const QString &wsName, int wsIndex, const Mantid::API::MatrixWorkspace& ws);
+  void removeDataSets(std::vector<int>& rows);
+
+  /// Table with data set names and other data.
+  QTableWidget *m_dataTable;
+  /// Flag for setting the fitting range.
+  bool m_isFittingRangeGlobal;
+};
+
 } // CustomInterfaces
 } // MantidQt
 
+
 #endif /*MULTIDATASETFITDIALOG_H_*/
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui
index c2b680fd31c25c646e454c2d30e1e7b77f37c6bc..e78765d31f80b67c61a4166640f126921b3ec3e3 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit.ui
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>895</width>
-    <height>604</height>
+    <height>621</height>
    </rect>
   </property>
   <property name="windowTitle">
@@ -60,7 +60,7 @@
          <item>
           <widget class="QTableWidget" name="dataTable">
            <property name="editTriggers">
-            <set>QAbstractItemView::NoEditTriggers</set>
+            <set>QAbstractItemView::AnyKeyPressed|QAbstractItemView::DoubleClicked|QAbstractItemView::EditKeyPressed</set>
            </property>
            <column>
             <property name="text">
@@ -72,6 +72,16 @@
              <string>WS Index</string>
             </property>
            </column>
+           <column>
+            <property name="text">
+             <string>Start X</string>
+            </property>
+           </column>
+           <column>
+            <property name="text">
+             <string>End X</string>
+            </property>
+           </column>
           </widget>
          </item>
          <item>
@@ -115,6 +125,9 @@
        </widget>
        <widget class="QWidget" name="verticalLayoutWidget">
         <layout class="QVBoxLayout" name="verticalLayout">
+         <property name="spacing">
+          <number>6</number>
+         </property>
          <item>
           <layout class="QHBoxLayout" name="horizontalLayout">
            <item>
@@ -152,7 +165,7 @@
            <item>
             <widget class="QPushButton" name="btnNext">
              <property name="sizePolicy">
-              <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+              <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
                <horstretch>0</horstretch>
                <verstretch>0</verstretch>
               </sizepolicy>
@@ -189,6 +202,54 @@
            </item>
           </layout>
          </item>
+         <item>
+          <widget class="QStackedWidget" name="toolOptions">
+           <property name="sizePolicy">
+            <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+             <horstretch>0</horstretch>
+             <verstretch>0</verstretch>
+            </sizepolicy>
+           </property>
+           <property name="currentIndex">
+            <number>0</number>
+           </property>
+           <widget class="QWidget" name="ZoomPage">
+            <layout class="QHBoxLayout" name="horizontalLayout_4">
+             <property name="margin">
+              <number>0</number>
+             </property>
+            </layout>
+           </widget>
+           <widget class="QWidget" name="PanPage"/>
+           <widget class="QWidget" name="RangePage">
+            <layout class="QHBoxLayout" name="horizontalLayout_5">
+             <property name="margin">
+              <number>0</number>
+             </property>
+             <item>
+              <widget class="QCheckBox" name="cb_applyRangeToAll">
+               <property name="text">
+                <string>Apply to all spectra</string>
+               </property>
+              </widget>
+             </item>
+             <item>
+              <spacer name="horizontalSpacer_3">
+               <property name="orientation">
+                <enum>Qt::Horizontal</enum>
+               </property>
+               <property name="sizeHint" stdset="0">
+                <size>
+                 <width>543</width>
+                 <height>20</height>
+                </size>
+               </property>
+              </spacer>
+             </item>
+            </layout>
+           </widget>
+          </widget>
+         </item>
          <item>
           <widget class="QwtPlot" name="plot">
            <property name="frameShape">
@@ -231,6 +292,8 @@
   <tabstop>btnNext</tabstop>
   <tabstop>cbPlotSelector</tabstop>
  </tabstops>
- <resources/>
+ <resources>
+  <include location="../../icons/CustomInterfacesIcons.qrc"/>
+ </resources>
  <connections/>
 </ui>
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp
index 21b2211abb35bfd44542d75c30b7dc1b21bfaf61..2f19360e2dff1c784596a81c776ef7d29e670985 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/CalcCorr.cpp
@@ -365,13 +365,13 @@ namespace IDA
     switch(m_uiForm.cbSampleInputType->currentIndex())
     {
       case 0:
-          //using direct input
-          uiv.checkFieldIsValid("Sample Scattering Cross-Section", m_uiForm.lesamsigs, m_uiForm.valSamsigs);
-          uiv.checkFieldIsValid("Sample Absorption Cross-Section", m_uiForm.lesamsiga, m_uiForm.valSamsiga);
+        //input using formula
+        uiv.checkFieldIsValid("Sample Formula", m_uiForm.leSampleFormula, m_uiForm.valSampleFormula);
         break;
       case 1:
-          //input using formula
-          uiv.checkFieldIsValid("Sample Formula", m_uiForm.leSampleFormula, m_uiForm.valSampleFormula);
+        //using direct input
+        uiv.checkFieldIsValid("Sample Scattering Cross-Section", m_uiForm.lesamsigs, m_uiForm.valSamsigs);
+        uiv.checkFieldIsValid("Sample Absorption Cross-Section", m_uiForm.lesamsiga, m_uiForm.valSamsiga);
         break;
     }
 
@@ -390,13 +390,13 @@ namespace IDA
       switch(m_uiForm.cbCanInputType->currentIndex())
       {
         case 0:
-            // using direct input
-            uiv.checkFieldIsValid("Can Scattering Cross-Section", m_uiForm.lecansigs, m_uiForm.valCansigs);
-            uiv.checkFieldIsValid("Can Absorption Cross-Section", m_uiForm.lecansiga, m_uiForm.valCansiga);
+          //input using formula
+          uiv.checkFieldIsValid("Can Formula", m_uiForm.leCanFormula, m_uiForm.valCanFormula);
           break;
         case 1:
-            //input using formula
-            uiv.checkFieldIsValid("Can Formula", m_uiForm.leCanFormula, m_uiForm.valCanFormula);
+          // using direct input
+          uiv.checkFieldIsValid("Can Scattering Cross-Section", m_uiForm.lecansigs, m_uiForm.valCansigs);
+          uiv.checkFieldIsValid("Can Absorption Cross-Section", m_uiForm.lecansiga, m_uiForm.valCansiga);
           break;
       }
     }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
index 58ba4caaaf9e33ab65a7c9785485f442e4c2045e..56fbf8531693c779d2364677204574fa333949a8 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ConvFit.cpp
@@ -51,13 +51,13 @@ namespace IDA
     m_cfTree->setFactoryForManager(m_dblManager, m_dblEdFac);
 
     // Create Range Selectors
-    m_rangeSelectors["ConvFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-    m_rangeSelectors["ConvFitBackRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot,
-        MantidQt::MantidWidgets::RangeSelector::YSINGLE);
-    m_rangeSelectors["ConvFitBackRange"]->setColour(Qt::darkGreen);
-    m_rangeSelectors["ConvFitBackRange"]->setRange(0.0, 1.0);
-    m_rangeSelectors["ConvFitHWHM"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-    m_rangeSelectors["ConvFitHWHM"]->setColour(Qt::red);
+    auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitRange");
+    auto backRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitBackRange",
+                                                               MantidWidgets::RangeSelector::YSINGLE);
+    auto hwhmRangeSelector = m_uiForm.ppPlot->addRangeSelector("ConvFitHWHM");
+    backRangeSelector->setColour(Qt::darkGreen);
+    backRangeSelector->setRange(0.0, 1.0);
+    hwhmRangeSelector->setColour(Qt::red);
 
     // Populate Property Widget
 
@@ -98,11 +98,11 @@ namespace IDA
     m_uiForm.leTempCorrection->setValidator(new QDoubleValidator(m_parentWidget));
 
     // Connections
-    connect(m_rangeSelectors["ConvFitRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
-    connect(m_rangeSelectors["ConvFitRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
-    connect(m_rangeSelectors["ConvFitBackRange"], SIGNAL(minValueChanged(double)), this, SLOT(backgLevel(double)));
-    connect(m_rangeSelectors["ConvFitHWHM"], SIGNAL(minValueChanged(double)), this, SLOT(hwhmChanged(double)));
-    connect(m_rangeSelectors["ConvFitHWHM"], SIGNAL(maxValueChanged(double)), this, SLOT(hwhmChanged(double)));
+    connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
+    connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
+    connect(backRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(backgLevel(double)));
+    connect(hwhmRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(hwhmChanged(double)));
+    connect(hwhmRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(hwhmChanged(double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double)));
     connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(checkBoxUpdate(QtProperty*, bool)));
     connect(m_uiForm.ckTempCorrection, SIGNAL(toggled(bool)), m_uiForm.leTempCorrection, SLOT(setEnabled(bool)));
@@ -113,8 +113,9 @@ namespace IDA
     connect(m_uiForm.ckPlotGuess, SIGNAL(stateChanged(int)), this, SLOT(plotGuess()));
 
     // Have FWHM Range linked to Fit Start/End Range
-    connect(m_rangeSelectors["ConvFitRange"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ConvFitHWHM"], SLOT(setRange(double, double)));
-    m_rangeSelectors["ConvFitHWHM"]->setRange(-1.0,1.0);
+    connect(fitRangeSelector, SIGNAL(rangeChanged(double, double)),
+            hwhmRangeSelector, SLOT(setRange(double, double)));
+    hwhmRangeSelector->setRange(-1.0,1.0);
     hwhmUpdateRS(0.02);
 
     typeSelection(m_uiForm.cbFitType->currentIndex());
@@ -643,19 +644,21 @@ namespace IDA
     m_cfTree->removeProperty(m_properties["Lorentzian1"]);
     m_cfTree->removeProperty(m_properties["Lorentzian2"]);
 
+    auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM");
+
     switch ( index )
     {
       case 0:
-        m_rangeSelectors["ConvFitHWHM"]->setVisible(false);
+        hwhmRangeSelector->setVisible(false);
         break;
       case 1:
         m_cfTree->addProperty(m_properties["Lorentzian1"]);
-        m_rangeSelectors["ConvFitHWHM"]->setVisible(true);
+        hwhmRangeSelector->setVisible(true);
         break;
       case 2:
         m_cfTree->addProperty(m_properties["Lorentzian1"]);
         m_cfTree->addProperty(m_properties["Lorentzian2"]);
-        m_rangeSelectors["ConvFitHWHM"]->setVisible(true);
+        hwhmRangeSelector->setVisible(true);
         break;
     }
   }
@@ -694,7 +697,7 @@ namespace IDA
     {
       const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample");
       const std::pair<double, double> range(curveRange.first, curveRange.second);
-      m_rangeSelectors["ConvFitRange"]->setRange(range.first, range.second);
+      m_uiForm.ppPlot->getRangeSelector("ConvFitRange")->setRange(range.first, range.second);
       m_uiForm.ckPlotGuess->setChecked(plotGuess);
     }
     catch(std::invalid_argument & exc)
@@ -954,9 +957,10 @@ namespace IDA
     // Always want FWHM to display as positive.
     const double hwhm = std::fabs(val-peakCentre);
     // Update the property
-    m_rangeSelectors["ConvFitHWHM"]->blockSignals(true);
+    auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM");
+    hwhmRangeSelector->blockSignals(true);
     m_dblManager->setValue(m_properties["Lorentzian 1.FWHM"], hwhm*2);
-    m_rangeSelectors["ConvFitHWHM"]->blockSignals(false);
+    hwhmRangeSelector->blockSignals(false);
   }
 
   void ConvFit::backgLevel(double val)
@@ -966,9 +970,12 @@ namespace IDA
 
   void ConvFit::updateRS(QtProperty* prop, double val)
   {
-    if ( prop == m_properties["StartX"] ) { m_rangeSelectors["ConvFitRange"]->setMinimum(val); }
-    else if ( prop == m_properties["EndX"] ) { m_rangeSelectors["ConvFitRange"]->setMaximum(val); }
-    else if ( prop == m_properties["BGA0"] ) { m_rangeSelectors["ConvFitBackRange"]->setMinimum(val); }
+    auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitRange");
+    auto backRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitBackRange");
+
+    if ( prop == m_properties["StartX"] ) { fitRangeSelector->setMinimum(val); }
+    else if ( prop == m_properties["EndX"] ) { fitRangeSelector->setMaximum(val); }
+    else if ( prop == m_properties["BGA0"] ) { backRangeSelector->setMinimum(val); }
     else if ( prop == m_properties["Lorentzian 1.FWHM"] ) { hwhmUpdateRS(val); }
     else if ( prop == m_properties["Lorentzian 1.PeakCentre"] )
     {
@@ -979,8 +986,9 @@ namespace IDA
   void ConvFit::hwhmUpdateRS(double val)
   {
     const double peakCentre = m_dblManager->value(m_properties["Lorentzian 1.PeakCentre"]);
-    m_rangeSelectors["ConvFitHWHM"]->setMinimum(peakCentre-val/2);
-    m_rangeSelectors["ConvFitHWHM"]->setMaximum(peakCentre+val/2);
+    auto hwhmRangeSelector = m_uiForm.ppPlot->getRangeSelector("ConvFitHWHM");
+    hwhmRangeSelector->setMinimum(peakCentre-val/2);
+    hwhmRangeSelector->setMaximum(peakCentre+val/2);
   }
 
   void ConvFit::checkBoxUpdate(QtProperty* prop, bool checked)
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp
index db1e27990a7cbd21d225c3d37aeebbe4d8b6c98d..3cc9867a2a20e66c5ebabce68ce73de73aed9f8f 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Elwin.cpp
@@ -65,16 +65,17 @@ namespace IDA
 
     // We always want one range selector... the second one can be controlled from
     // within the elwinTwoRanges(bool state) function
-    m_rangeSelectors["ElwinIntegrationRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-    connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
-    connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
+    auto integrationRangeSelector = m_uiForm.ppPlot->addRangeSelector("ElwinIntegrationRange");
+    connect(integrationRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
+    connect(integrationRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
     // create the second range
-    m_rangeSelectors["ElwinBackgroundRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-    m_rangeSelectors["ElwinBackgroundRange"]->setColour(Qt::darkGreen); // dark green for background
-    connect(m_rangeSelectors["ElwinIntegrationRange"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ElwinBackgroundRange"], SLOT(setRange(double, double)));
-    connect(m_rangeSelectors["ElwinBackgroundRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
-    connect(m_rangeSelectors["ElwinBackgroundRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
-    m_rangeSelectors["ElwinBackgroundRange"]->setRange(m_rangeSelectors["ElwinIntegrationRange"]->getRange());
+    auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector("ElwinBackgroundRange");
+    backgroundRangeSelector->setColour(Qt::darkGreen); // dark green for background
+    connect(integrationRangeSelector, SIGNAL(rangeChanged(double, double)),
+            backgroundRangeSelector, SLOT(setRange(double, double)));
+    connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
+    connect(backgroundRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
+    backgroundRangeSelector->setRange(integrationRangeSelector->getRange());
 
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double)));
     connect(m_blnManager, SIGNAL(valueChanged(QtProperty*, bool)), this, SLOT(twoRanges(QtProperty*, bool)));
@@ -360,7 +361,7 @@ namespace IDA
     try
     {
       QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
-      m_rangeSelectors["ElwinIntegrationRange"]->setRange(range.first, range.second);
+      m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange")->setRange(range.first, range.second);
     }
     catch(std::invalid_argument & exc)
     {
@@ -371,17 +372,21 @@ namespace IDA
   void Elwin::twoRanges(QtProperty* prop, bool val)
   {
     if(prop == m_properties["BackgroundSubtraction"])
-      m_rangeSelectors["ElwinBackgroundRange"]->setVisible(val);
+      m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange")->setVisible(val);
   }
 
   void Elwin::minChanged(double val)
   {
+    auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange");
+    auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange");
+
     MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
-    if ( from == m_rangeSelectors["ElwinIntegrationRange"] )
+
+    if(from == integrationRangeSelector)
     {
       m_dblManager->setValue(m_properties["IntegrationStart"], val);
     }
-    else if ( from == m_rangeSelectors["ElwinBackgroundRange"] )
+    else if(from == backgroundRangeSelector)
     {
       m_dblManager->setValue(m_properties["BackgroundStart"], val);
     }
@@ -389,12 +394,16 @@ namespace IDA
 
   void Elwin::maxChanged(double val)
   {
+    auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange");
+    auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange");
+
     MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
-    if ( from == m_rangeSelectors["ElwinIntegrationRange"] )
+
+    if(from == integrationRangeSelector)
     {
       m_dblManager->setValue(m_properties["IntegrationEnd"], val);
     }
-    else if ( from == m_rangeSelectors["ElwinBackgroundRange"] )
+    else if(from == backgroundRangeSelector)
     {
       m_dblManager->setValue(m_properties["BackgroundEnd"], val);
     }
@@ -402,11 +411,15 @@ namespace IDA
 
   void Elwin::updateRS(QtProperty* prop, double val)
   {
-    if ( prop == m_properties["IntegrationStart"] ) m_rangeSelectors["ElwinIntegrationRange"]->setMinimum(val);
-    else if ( prop == m_properties["IntegrationEnd"] ) m_rangeSelectors["ElwinIntegrationRange"]->setMaximum(val);
-    else if ( prop == m_properties["BackgroundStart"] ) m_rangeSelectors["ElwinBackgroundRange"]->setMinimum(val);
-    else if ( prop == m_properties["BackgroundEnd"] ) m_rangeSelectors["ElwinBackgroundRange"]->setMaximum(val);
+    auto integrationRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinIntegrationRange");
+    auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("ElwinBackgroundRange");
+
+    if ( prop == m_properties["IntegrationStart"] )     integrationRangeSelector->setMinimum(val);
+    else if ( prop == m_properties["IntegrationEnd"] )  integrationRangeSelector->setMaximum(val);
+    else if ( prop == m_properties["BackgroundStart"] ) backgroundRangeSelector->setMinimum(val);
+    else if ( prop == m_properties["BackgroundEnd"] )   backgroundRangeSelector->setMaximum(val);
   }
+
 } // namespace IDA
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp
index e131644b51ea61023537690fe00db8d975b25f8d..87c3b3416da06f74275c0db18fc57d6105fd32eb 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Fury.cpp
@@ -68,10 +68,10 @@ namespace IDA
 
     m_furTree->setFactoryForManager(m_dblManager, m_dblEdFac);
 
-    m_rangeSelectors["FuryRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot);
+    auto xRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryRange");
 
     // signals / slots & validators
-    connect(m_rangeSelectors["FuryRange"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rsRangeChangedLazy(double, double)));
+    connect(xRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rsRangeChangedLazy(double, double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updatePropertyValues(QtProperty*, double)));
     connect(m_uiForm.dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(plotInput(const QString&)));
@@ -252,6 +252,8 @@ namespace IDA
     m_uiForm.ppPlot->clear();
     m_uiForm.ppPlot->addSpectrum("Sample", workspace, 0);
 
+    auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange");
+
     try
     {
       QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
@@ -260,7 +262,7 @@ namespace IDA
       const std::string instrName(workspace->getInstrument()->getName());
       if(instrName == "BASIS")
       {
-        m_rangeSelectors["FuryRange"]->setRange(range.first, range.second);
+        xRangeSelector->setRange(range.first, range.second);
         m_dblManager->setValue(m_properties["ELow"], rounded_min);
         m_dblManager->setValue(m_properties["EHigh"], rounded_max);
         m_dblManager->setValue(m_properties["EWidth"], 0.0004);
@@ -285,13 +287,13 @@ namespace IDA
         //check incase we have a really small range
         if (fabs(rounded_min) > 0 && fabs(rounded_max) > 0)
         {
-          m_rangeSelectors["FuryRange"]->setRange(rounded_min, rounded_max);
+          xRangeSelector->setRange(rounded_min, rounded_max);
           m_dblManager->setValue(m_properties["ELow"], rounded_min);
           m_dblManager->setValue(m_properties["EHigh"], rounded_max);
         }
         else
         {
-          m_rangeSelectors["FuryRange"]->setRange(range.first, range.second);
+          xRangeSelector->setRange(range.first, range.second);
           m_dblManager->setValue(m_properties["ELow"], range.first);
           m_dblManager->setValue(m_properties["EHigh"], range.second);
         }
@@ -327,10 +329,12 @@ namespace IDA
 
   void Fury::updateRS(QtProperty* prop, double val)
   {
+    auto xRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryRange");
+
     if(prop == m_properties["ELow"])
-      m_rangeSelectors["FuryRange"]->setMinimum(val);
+      xRangeSelector->setMinimum(val);
     else if(prop == m_properties["EHigh"])
-      m_rangeSelectors["FuryRange"]->setMaximum(val);
+      xRangeSelector->setMaximum(val);
   }
 
 } // namespace IDA
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp
index 8c8840ab7ace64910c13941f344f8c07b0f7815a..e806dabff5c11fc2f283f0d9b54ef741095ab6bf 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/FuryFit.cpp
@@ -47,15 +47,15 @@ namespace IDA
     m_ffTree = new QtTreePropertyBrowser(m_parentWidget);
     m_uiForm.properties->addWidget(m_ffTree);
 
-    m_rangeSelectors["FuryFitRange"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-    connect(m_rangeSelectors["FuryFitRange"], SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double)));
-    connect(m_rangeSelectors["FuryFitRange"], SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double)));
+    auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitRange");
+    connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(xMinSelected(double)));
+    connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(xMaxSelected(double)));
 
-    m_rangeSelectors["FuryFitBackground"] = new MantidQt::MantidWidgets::RangeSelector(m_uiForm.ppPlot,
-      MantidQt::MantidWidgets::RangeSelector::YSINGLE);
-    m_rangeSelectors["FuryFitBackground"]->setRange(0.0,1.0);
-    m_rangeSelectors["FuryFitBackground"]->setColour(Qt::darkGreen);
-    connect(m_rangeSelectors["FuryFitBackground"], SIGNAL(minValueChanged(double)), this, SLOT(backgroundSelected(double)));
+    auto backgroundRangeSelector = m_uiForm.ppPlot->addRangeSelector("FuryFitBackground",
+                                                                     MantidWidgets::RangeSelector::YSINGLE);
+    backgroundRangeSelector->setRange(0.0,1.0);
+    backgroundRangeSelector->setColour(Qt::darkGreen);
+    connect(backgroundRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(backgroundSelected(double)));
 
     // setupTreePropertyBrowser
     m_ffRangeManager = new QtDoublePropertyManager(m_parentWidget);
@@ -399,7 +399,7 @@ namespace IDA
     {
       const QPair<double, double> curveRange = m_uiForm.ppPlot->getCurveRange("Sample");
       const std::pair<double, double> range(curveRange.first, curveRange.second);
-      m_rangeSelectors["FuryFitRange"]->setRange(range.first, range.second);
+      m_uiForm.ppPlot->getRangeSelector("FuryFitRange")->setRange(range.first, range.second);
       m_ffRangeManager->setRange(m_properties["StartX"], range.first, range.second);
       m_ffRangeManager->setRange(m_properties["EndX"], range.first, range.second);
 
@@ -489,17 +489,20 @@ namespace IDA
 
   void FuryFit::propertyChanged(QtProperty* prop, double val)
   {
+    auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitRange");
+    auto backgroundRangeSelector = m_uiForm.ppPlot->getRangeSelector("FuryFitBackground");
+
     if ( prop == m_properties["StartX"] )
     {
-      m_rangeSelectors["FuryFitRange"]->setMinimum(val);
+      fitRangeSelector->setMinimum(val);
     }
     else if ( prop == m_properties["EndX"] )
     {
-      m_rangeSelectors["FuryFitRange"]->setMaximum(val);
+      fitRangeSelector->setMaximum(val);
     }
     else if ( prop == m_properties["BackgroundA0"])
     {
-      m_rangeSelectors["FuryFitBackground"]->setMinimum(val);
+      backgroundRangeSelector->setMinimum(val);
       m_dblManager->setValue(m_properties["Exponential1.Intensity"], 1.0-val);
       m_dblManager->setValue(m_properties["Exponential2.Intensity"], 1.0-val);
       m_dblManager->setValue(m_properties["StretchedExp.Intensity"], 1.0-val);
@@ -508,7 +511,7 @@ namespace IDA
       || prop == m_properties["Exponential2.Intensity"]
       || prop == m_properties["StretchedExp.Intensity"])
     {
-      m_rangeSelectors["FuryFitBackground"]->setMinimum(1.0-val);
+      backgroundRangeSelector->setMinimum(1.0-val);
       m_dblManager->setValue(m_properties["Exponential1.Intensity"], val);
       m_dblManager->setValue(m_properties["Exponential2.Intensity"], val);
       m_dblManager->setValue(m_properties["StretchedExp.Intensity"], val);
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
index 058459d8cc980e131cf80bdc5f905b5307184e60..f7d72f27df3d7666af4a7f673b0d272128161fe3 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISCalibration.cpp
@@ -46,9 +46,9 @@ namespace CustomInterfaces
     m_propTrees["CalPropTree"]->addProperty(m_properties["CalBackMax"]);
 
     // Cal plot range selectors
-    m_rangeSelectors["CalPeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppCalibration);
-    m_rangeSelectors["CalBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppCalibration);
-    m_rangeSelectors["CalBackground"]->setColour(Qt::darkGreen); //Dark green to signify background range
+    auto calPeak = m_uiForm.ppCalibration->addRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->addRangeSelector("CalBackground");
+    calBackground->setColour(Qt::darkGreen); //Dark green to signify background range
 
     // RES PROPERTY TREE
     m_propTrees["ResPropTree"] = new QtTreePropertyBrowser();
@@ -97,27 +97,28 @@ namespace CustomInterfaces
 
     // Res plot range selectors
     // Create ResBackground first so ResPeak is drawn above it
-    m_rangeSelectors["ResBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppResolution,
-        MantidQt::MantidWidgets::RangeSelector::XMINMAX, true, false);
-    m_rangeSelectors["ResBackground"]->setColour(Qt::darkGreen);
-    m_rangeSelectors["ResPeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppResolution,
-        MantidQt::MantidWidgets::RangeSelector::XMINMAX, true, true);
+    auto resBackground = m_uiForm.ppResolution->addRangeSelector("ResBackground");
+    resBackground->setColour(Qt::darkGreen);
+    auto resPeak = m_uiForm.ppResolution->addRangeSelector("ResPeak");
+    resPeak->setInfoOnly(true);
 
     // SIGNAL/SLOT CONNECTIONS
     // Update instrument information when a new instrument config is selected
     connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setDefaultInstDetails()));
 
-    connect(m_rangeSelectors["ResPeak"], SIGNAL(rangeChanged(double, double)), m_rangeSelectors["ResBackground"], SLOT(setRange(double, double)));
+    connect(resPeak, SIGNAL(rangeChanged(double, double)),
+            resBackground, SLOT(setRange(double, double)));
 
     // Update property map when a range seclector is moved
-    connect(m_rangeSelectors["CalPeak"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
-    connect(m_rangeSelectors["CalPeak"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
-    connect(m_rangeSelectors["CalBackground"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
-    connect(m_rangeSelectors["CalBackground"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
-    connect(m_rangeSelectors["ResPeak"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
-    connect(m_rangeSelectors["ResPeak"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
-    connect(m_rangeSelectors["ResBackground"], SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
-    connect(m_rangeSelectors["ResBackground"], SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
+    connect(calPeak, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
+    connect(calPeak, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
+    connect(calBackground, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
+    connect(calBackground, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
+    connect(resPeak, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
+    connect(resPeak, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
+    connect(resBackground, SIGNAL(minValueChanged(double)), this, SLOT(calMinChanged(double)));
+    connect(resBackground, SIGNAL(maxValueChanged(double)), this, SLOT(calMaxChanged(double)));
+
     // Update range selctor positions when a value in the double manager changes
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(calUpdateRS(QtProperty*, double)));
     // Plot miniplots after a file has loaded
@@ -348,8 +349,10 @@ namespace CustomInterfaces
     QPair<double, double> peakRange(ranges["peak-start-tof"], ranges["peak-end-tof"]);
     QPair<double, double> backgroundRange(ranges["back-start-tof"], ranges["back-end-tof"]);
 
-    setRangeSelector("CalPeak", m_properties["CalPeakMin"], m_properties["CalPeakMax"], peakRange);
-    setRangeSelector("CalBackground", m_properties["CalBackMin"], m_properties["CalBackMax"], backgroundRange);
+    auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground");
+    setRangeSelector(calPeak, m_properties["CalPeakMin"], m_properties["CalPeakMax"], peakRange);
+    setRangeSelector(calBackground, m_properties["CalBackMin"], m_properties["CalBackMax"], backgroundRange);
   }
 
   /**
@@ -396,8 +399,10 @@ namespace CustomInterfaces
     m_uiForm.ppCalibration->addSpectrum("Raw", input, 0);
     m_uiForm.ppCalibration->resizeX();
 
-    setPlotPropertyRange("CalPeak", m_properties["CalELow"], m_properties["CalEHigh"], range);
-    setPlotPropertyRange("CalBackground", m_properties["CalStart"], m_properties["CalEnd"], range);
+    auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground");
+    setPlotPropertyRange(calPeak, m_properties["CalELow"], m_properties["CalEHigh"], range);
+    setPlotPropertyRange(calBackground, m_properties["CalStart"], m_properties["CalEnd"], range);
 
     m_uiForm.ppCalibration->replot();
 
@@ -456,7 +461,8 @@ namespace CustomInterfaces
     const Mantid::MantidVec & dataX = energyWs->readX(0);
     QPair<double, double> range(dataX.front(), dataX.back());
 
-    setPlotPropertyRange("ResBackground", m_properties["ResStart"], m_properties["ResEnd"], range);
+    auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
+    setPlotPropertyRange(resBackground, m_properties["ResStart"], m_properties["ResEnd"], range);
 
     m_uiForm.ppResolution->clear();
     m_uiForm.ppResolution->addSpectrum("Energy", energyWs, 0);
@@ -494,11 +500,13 @@ namespace CustomInterfaces
 
         // Set default rebinning bounds
         QPair<double, double> peakRange(-res*10, res*10);
-        setRangeSelector("ResPeak", m_properties["ResELow"], m_properties["ResEHigh"], peakRange);
+        auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak");
+        setRangeSelector(resPeak, m_properties["ResELow"], m_properties["ResEHigh"], peakRange);
 
         // Set default background bounds
         QPair<double, double> backgroundRange(-res*9, -res*8);
-        setRangeSelector("ResBackground", m_properties["ResStart"], m_properties["ResEnd"], backgroundRange);
+        auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
+        setRangeSelector(resBackground, m_properties["ResStart"], m_properties["ResEnd"], backgroundRange);
       }
     }
   }
@@ -511,20 +519,26 @@ namespace CustomInterfaces
    */
   void ISISCalibration::calMinChanged(double val)
   {
+    auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground");
+    auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak");
+    auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
+
     MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
-    if ( from == m_rangeSelectors["CalPeak"] )
+
+    if(from == calPeak)
     {
       m_dblManager->setValue(m_properties["CalPeakMin"], val);
     }
-    else if ( from == m_rangeSelectors["CalBackground"] )
+    else if(from == calBackground)
     {
       m_dblManager->setValue(m_properties["CalBackMin"], val);
     }
-    else if ( from == m_rangeSelectors["ResPeak"] )
+    else if(from == resPeak)
     {
       m_dblManager->setValue(m_properties["ResELow"], val);
     }
-    else if ( from == m_rangeSelectors["ResBackground"] )
+    else if(from == resBackground)
     {
       m_dblManager->setValue(m_properties["ResStart"], val);
     }
@@ -538,20 +552,26 @@ namespace CustomInterfaces
    */
   void ISISCalibration::calMaxChanged(double val)
   {
+    auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground");
+    auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak");
+    auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
+
     MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
-    if ( from == m_rangeSelectors["CalPeak"] )
+
+    if(from == calPeak)
     {
       m_dblManager->setValue(m_properties["CalPeakMax"], val);
     }
-    else if ( from == m_rangeSelectors["CalBackground"] )
+    else if(from == calBackground)
     {
       m_dblManager->setValue(m_properties["CalBackMax"], val);
     }
-    else if ( from == m_rangeSelectors["ResPeak"] )
+    else if(from == resPeak)
     {
       m_dblManager->setValue(m_properties["ResEHigh"], val);
     }
-    else if ( from == m_rangeSelectors["ResBackground"] )
+    else if(from == resBackground)
     {
       m_dblManager->setValue(m_properties["ResEnd"], val);
     }
@@ -565,14 +585,19 @@ namespace CustomInterfaces
    */
   void ISISCalibration::calUpdateRS(QtProperty* prop, double val)
   {
-    if ( prop == m_properties["CalPeakMin"] ) m_rangeSelectors["CalPeak"]->setMinimum(val);
-    else if ( prop == m_properties["CalPeakMax"] ) m_rangeSelectors["CalPeak"]->setMaximum(val);
-    else if ( prop == m_properties["CalBackMin"] ) m_rangeSelectors["CalBackground"]->setMinimum(val);
-    else if ( prop == m_properties["CalBackMax"] ) m_rangeSelectors["CalBackground"]->setMaximum(val);
-    else if ( prop == m_properties["ResStart"] ) m_rangeSelectors["ResBackground"]->setMinimum(val);
-    else if ( prop == m_properties["ResEnd"] ) m_rangeSelectors["ResBackground"]->setMaximum(val);
-    else if ( prop == m_properties["ResELow"] ) m_rangeSelectors["ResPeak"]->setMinimum(val);
-    else if ( prop == m_properties["ResEHigh"] ) m_rangeSelectors["ResPeak"]->setMaximum(val);
+    auto calPeak = m_uiForm.ppCalibration->getRangeSelector("CalPeak");
+    auto calBackground = m_uiForm.ppCalibration->getRangeSelector("CalBackground");
+    auto resPeak = m_uiForm.ppResolution->getRangeSelector("ResPeak");
+    auto resBackground = m_uiForm.ppResolution->getRangeSelector("ResBackground");
+
+    if ( prop == m_properties["CalPeakMin"] )       calPeak->setMinimum(val);
+    else if ( prop == m_properties["CalPeakMax"] )  calPeak->setMaximum(val);
+    else if ( prop == m_properties["CalBackMin"] )  calBackground->setMinimum(val);
+    else if ( prop == m_properties["CalBackMax"] )  calBackground->setMaximum(val);
+    else if ( prop == m_properties["ResStart"] )    resBackground->setMinimum(val);
+    else if ( prop == m_properties["ResEnd"] )      resBackground->setMaximum(val);
+    else if ( prop == m_properties["ResELow"] )     resPeak->setMinimum(val);
+    else if ( prop == m_properties["ResEHigh"] )    resPeak->setMaximum(val);
   }
 
   /**
@@ -582,8 +607,8 @@ namespace CustomInterfaces
   */
   void ISISCalibration::resCheck(bool state)
   {
-    m_rangeSelectors["ResPeak"]->setVisible(state);
-    m_rangeSelectors["ResBackground"]->setVisible(state);
+    m_uiForm.ppResolution->getRangeSelector("ResPeak")->setVisible(state);
+    m_uiForm.ppResolution->getRangeSelector("ResBackground")->setVisible(state);
 
     // Toggle scale and smooth options
     m_uiForm.ckResolutionScale->setEnabled(state);
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
index 2150358f795ba0846ceaf0ddb101a5e47a633a5a..45119aee24dc67ff1224b2de335968b854a726d4 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ISISDiagnostics.cpp
@@ -72,12 +72,12 @@ namespace CustomInterfaces
     m_propTrees["SlicePropTree"]->addProperty(m_properties["BackgroundRange"]);
 
     // Slice plot
-    m_rangeSelectors["SlicePeak"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot);
-    m_rangeSelectors["SliceBackground"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot);
+    auto peakRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("SlicePeak");
+    auto backgroundRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("SliceBackground");
 
     // Setup second range
-    m_rangeSelectors["SliceBackground"]->setColour(Qt::darkGreen); // Dark green for background
-    m_rangeSelectors["SliceBackground"]->setRange(m_rangeSelectors["SlicePeak"]->getRange());
+    backgroundRangeSelector->setColour(Qt::darkGreen); // Dark green for background
+    backgroundRangeSelector->setRange(peakRangeSelector->getRange());
 
     // SIGNAL/SLOT CONNECTIONS
 
@@ -85,8 +85,8 @@ namespace CustomInterfaces
     connect(this, SIGNAL(newInstrumentConfiguration()), this, SLOT(setDefaultInstDetails()));
 
     // Update properties when a range selector is changed
-    connect(m_rangeSelectors["SlicePeak"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double)));
-    connect(m_rangeSelectors["SliceBackground"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double)));
+    connect(peakRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double)));
+    connect(backgroundRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeSelectorDropped(double, double)));
 
     // Update range selctors when a property is changed
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(doublePropertyChanged(QtProperty*, double)));
@@ -235,10 +235,13 @@ namespace CustomInterfaces
     // Set peak and background ranges
     if(instDetails.size() >= 8)
     {
-      setRangeSelector("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"],
-          qMakePair(instDetails["peak-start"].toDouble(), instDetails["peak-end"].toDouble()));
-      setRangeSelector("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"],
-          qMakePair(instDetails["back-start"].toDouble(), instDetails["back-end"].toDouble()));
+      setRangeSelector(m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"),
+                       m_properties["PeakStart"], m_properties["PeakEnd"],
+                       qMakePair(instDetails["peak-start"].toDouble(), instDetails["peak-end"].toDouble()));
+
+      setRangeSelector(m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"),
+                       m_properties["BackgroundStart"], m_properties["BackgroundEnd"],
+                       qMakePair(instDetails["back-start"].toDouble(), instDetails["back-end"].toDouble()));
     }
   }
 
@@ -271,8 +274,10 @@ namespace CustomInterfaces
     m_uiForm.ppRawPlot->clear();
     m_uiForm.ppRawPlot->addSpectrum("Raw", input, previewSpec);
 
-    setPlotPropertyRange("SlicePeak", m_properties["PeakStart"], m_properties["PeakEnd"], range);
-    setPlotPropertyRange("SliceBackground", m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range);
+    setPlotPropertyRange(m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"),
+                         m_properties["PeakStart"], m_properties["PeakEnd"], range);
+    setPlotPropertyRange(m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"),
+                         m_properties["BackgroundStart"], m_properties["BackgroundEnd"], range);
 
     m_uiForm.ppRawPlot->resizeX();
   }
@@ -284,7 +289,7 @@ namespace CustomInterfaces
    */
   void ISISDiagnostics::sliceTwoRanges(QtProperty*, bool state)
   {
-    m_rangeSelectors["SliceBackground"]->setVisible(state);
+    m_uiForm.ppRawPlot->getRangeSelector("SliceBackground")->setVisible(state);
   }
 
   /**
@@ -301,12 +306,12 @@ namespace CustomInterfaces
   {
     MantidWidgets::RangeSelector* from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
 
-    if(from == m_rangeSelectors["SlicePeak"])
+    if(from == m_uiForm.ppRawPlot->getRangeSelector("SlicePeak"))
     {
       m_dblManager->setValue(m_properties["PeakStart"], min);
       m_dblManager->setValue(m_properties["PeakEnd"], max);
     }
-    else if(from == m_rangeSelectors["SliceBackground"])
+    else if(from == m_uiForm.ppRawPlot->getRangeSelector("SliceBackground"))
     {
       m_dblManager->setValue(m_properties["BackgroundStart"], min);
       m_dblManager->setValue(m_properties["BackgroundEnd"], max);
@@ -321,10 +326,13 @@ namespace CustomInterfaces
    */
   void ISISDiagnostics::doublePropertyChanged(QtProperty* prop, double val)
   {
-    if(prop == m_properties["PeakStart"])             m_rangeSelectors["SlicePeak"]->setMinimum(val);
-    else if(prop == m_properties["PeakEnd"])          m_rangeSelectors["SlicePeak"]->setMaximum(val);
-    else if(prop == m_properties["BackgroundStart"])  m_rangeSelectors["SliceBackground"]->setMinimum(val);
-    else if(prop == m_properties["BackgroundEnd"])    m_rangeSelectors["SliceBackground"]->setMaximum(val);
+    auto peakRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("SlicePeak");
+    auto backgroundRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("SliceBackground");
+
+    if(prop == m_properties["PeakStart"])             peakRangeSelector->setMinimum(val);
+    else if(prop == m_properties["PeakEnd"])          peakRangeSelector->setMaximum(val);
+    else if(prop == m_properties["BackgroundStart"])  backgroundRangeSelector->setMinimum(val);
+    else if(prop == m_properties["BackgroundEnd"])    backgroundRangeSelector->setMaximum(val);
     else if(prop == m_properties["PreviewSpec"])      handleNewFile();
 
     if(prop != m_properties["PreviewSpec"])
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
index 48f35777924b0f3f8bde237f3508b7de8903ee93..dc1563504a4f114ac471271c79f5afd13c4e333e 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectMoments.cpp
@@ -23,8 +23,8 @@ namespace CustomInterfaces
     const unsigned int NUM_DECIMALS = 6;
 
     // RAW PLOT
-    m_rangeSelectors["MomentsRangeSelector"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot);
-    m_rangeSelectors["MomentsRangeSelector"]->setInfoOnly(false);
+    auto xRangeSelector = m_uiForm.ppRawPlot->addRangeSelector("XRange");
+    xRangeSelector->setInfoOnly(false);
 
     // PROPERTY TREE
     m_propTrees["MomentsPropTree"] = new QtTreePropertyBrowser();
@@ -41,7 +41,7 @@ namespace CustomInterfaces
 
     connect(m_uiForm.dsInput, SIGNAL(dataReady(const QString&)), this, SLOT(handleSampleInputReady(const QString&)));
 
-    connect(m_rangeSelectors["MomentsRangeSelector"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeChanged(double, double)));
+    connect(xRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(rangeChanged(double, double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double)));
 
     // Update the preview plot when the algorithm completes
@@ -114,8 +114,10 @@ namespace CustomInterfaces
     m_uiForm.ppRawPlot->clear();
     m_uiForm.ppRawPlot->addSpectrum("Raw", filename, 0);
     QPair<double, double> range = m_uiForm.ppRawPlot->getCurveRange("Raw");
-    setRangeSelector("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range);
-    setPlotPropertyRange("MomentsRangeSelector", m_properties["EMin"], m_properties["EMax"], range);
+
+    auto xRangeSelector = m_uiForm.ppRawPlot->getRangeSelector("XRange");
+    setRangeSelector(xRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
+    setPlotPropertyRange(xRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
 
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateProperties(QtProperty*, double)));
 
@@ -154,7 +156,7 @@ namespace CustomInterfaces
       }
       else
       {
-        m_rangeSelectors["MomentsRangeSelector"]->setMinimum(val);
+        m_uiForm.ppRawPlot->getRangeSelector("XRange")->setMinimum(val);
       }
     }
     else if (prop == m_properties["EMax"])
@@ -166,7 +168,7 @@ namespace CustomInterfaces
       }
       else
       {
-        m_rangeSelectors["MomentsRangeSelector"]->setMaximum(val);
+        m_uiForm.ppRawPlot->getRangeSelector("XRange")->setMaximum(val);
       }
     }
 
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp
index 127a699513cdc01953a36e5b5e32fdfc528d0607..b5de049ce9573a3de4f6ff19193b0c7fbd4e9466 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectSymmetrise.cpp
@@ -69,46 +69,50 @@ namespace CustomInterfaces
     m_propTrees["SymmPVPropTree"]->addProperty(m_properties["DeltaY"]);
 
     // Indicators for Y value at each EMin position
-    m_rangeSelectors["NegativeEMinYPos"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot,
-        MantidWidgets::RangeSelector::YSINGLE, true, true);
-    m_rangeSelectors["PositiveEMinYPos"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot,
-        MantidWidgets::RangeSelector::YSINGLE, true, true);
-
-    m_rangeSelectors["NegativeEMinYPos"]->setColour(Qt::red);
-    m_rangeSelectors["PositiveEMinYPos"]->setColour(Qt::blue);
-    m_rangeSelectors["NegativeEMinYPos"]->setMinimum(0);
-    m_rangeSelectors["PositiveEMinYPos"]->setMinimum(0);
+    auto negativeEMinYPos = m_uiForm.ppRawPlot->addRangeSelector("NegativeEMinYPos",
+                                                                 MantidWidgets::RangeSelector::YSINGLE);
+    negativeEMinYPos->setInfoOnly(true);
+    negativeEMinYPos->setColour(Qt::blue);
+    negativeEMinYPos->setMinimum(0.0);
+
+    auto positiveEMinYPos = m_uiForm.ppRawPlot->addRangeSelector("PositiveEMinYPos",
+                                                                 MantidWidgets::RangeSelector::YSINGLE);
+    positiveEMinYPos->setInfoOnly(true);
+    positiveEMinYPos->setColour(Qt::red);
+    positiveEMinYPos->setMinimum(0.0);
 
     // Indicator for centre of symmetry (x=0)
-    m_rangeSelectors["CentreMark_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot,
-        MantidWidgets::RangeSelector::XSINGLE, true, true);
-    m_rangeSelectors["CentreMark_Raw"]->setColour(Qt::cyan);
-    m_rangeSelectors["CentreMark_Raw"]->setMinimum(0.0);
+    auto centreMarkRaw = m_uiForm.ppRawPlot->addRangeSelector("CentreMark",
+                                                              MantidWidgets::RangeSelector::XSINGLE);
+    centreMarkRaw->setInfoOnly(true);
+    centreMarkRaw->setColour(Qt::cyan);
+    centreMarkRaw->setMinimum(0.0);
 
     // Indicators for negative and positive X range values on X axis
     // The user can use these to move the X range
     // Note that the max and min of the negative range selector corespond to the opposite X value
     // i.e. RS min is X max
-    m_rangeSelectors["NegativeE_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot);
-    m_rangeSelectors["PositiveE_Raw"] = new MantidWidgets::RangeSelector(m_uiForm.ppRawPlot);
+    auto negativeERaw = m_uiForm.ppRawPlot->addRangeSelector("NegativeE");
+    negativeERaw->setColour(Qt::darkGreen);
 
-    m_rangeSelectors["NegativeE_Raw"]->setColour(Qt::darkGreen);
-    m_rangeSelectors["PositiveE_Raw"]->setColour(Qt::darkGreen);
+    auto positiveERaw = m_uiForm.ppRawPlot->addRangeSelector("PositiveE");
+    positiveERaw->setColour(Qt::darkGreen);
 
     // Indicators for negative and positive X range values on X axis
-    m_rangeSelectors["NegativeE_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot,
-        MantidWidgets::RangeSelector::XMINMAX, true, true);
-    m_rangeSelectors["PositiveE_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot,
-        MantidWidgets::RangeSelector::XMINMAX, true, true);
+    auto negativeEPV = m_uiForm.ppPreviewPlot->addRangeSelector("NegativeE");
+    negativeEPV->setInfoOnly(true);
+    negativeEPV->setColour(Qt::darkGreen);
 
-    m_rangeSelectors["NegativeE_PV"]->setColour(Qt::darkGreen);
-    m_rangeSelectors["PositiveE_PV"]->setColour(Qt::darkGreen);
+    auto positiveEPV = m_uiForm.ppPreviewPlot->addRangeSelector("PositiveE");
+    positiveEPV->setInfoOnly(true);
+    positiveEPV->setColour(Qt::darkGreen);
 
     // Indicator for centre of symmetry (x=0)
-    m_rangeSelectors["CentreMark_PV"] = new MantidWidgets::RangeSelector(m_uiForm.ppPreviewPlot,
-        MantidWidgets::RangeSelector::XSINGLE, true, true);
-    m_rangeSelectors["CentreMark_PV"]->setColour(Qt::cyan);
-    m_rangeSelectors["CentreMark_PV"]->setMinimum(0.0);
+    auto centreMarkPV = m_uiForm.ppPreviewPlot->addRangeSelector("CentreMark",
+                                                                 MantidWidgets::RangeSelector::XSINGLE);
+    centreMarkPV->setInfoOnly(true);
+    centreMarkPV->setColour(Qt::cyan);
+    centreMarkPV->setMinimum(0.0);
 
     // SIGNAL/SLOT CONNECTIONS
     // Validate the E range when it is changed
@@ -120,10 +124,10 @@ namespace CustomInterfaces
     // Preview symmetrise
     connect(m_uiForm.pbPreview, SIGNAL(clicked()), this, SLOT(preview()));
     // X range selectors
-    connect(m_rangeSelectors["PositiveE_Raw"], SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double)));
-    connect(m_rangeSelectors["PositiveE_Raw"], SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double)));
-    connect(m_rangeSelectors["NegativeE_Raw"], SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double)));
-    connect(m_rangeSelectors["NegativeE_Raw"], SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double)));
+    connect(positiveERaw, SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double)));
+    connect(positiveERaw, SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double)));
+    connect(negativeERaw, SIGNAL(minValueChanged(double)), this, SLOT(xRangeMinChanged(double)));
+    connect(negativeERaw, SIGNAL(maxValueChanged(double)), this, SLOT(xRangeMaxChanged(double)));
 
     // Set default X range values
     m_dblManager->setValue(m_properties["EMin"], 0.1);
@@ -208,8 +212,8 @@ namespace CustomInterfaces
     double symmRange = std::max(fabs(axisRange.first), fabs(axisRange.second));
 
     // Set valid range for range selectors
-    m_rangeSelectors["NegativeE_Raw"]->setRange(-symmRange, 0);
-    m_rangeSelectors["PositiveE_Raw"]->setRange(0, symmRange);
+    m_uiForm.ppRawPlot->getRangeSelector("NegativeE")->setRange(-symmRange, 0);
+    m_uiForm.ppRawPlot->getRangeSelector("PositiveE")->setRange(0, symmRange);
 
     // Set some default (and valid) values for E range
     m_dblManager->setValue(m_properties["EMax"], axisRange.second);
@@ -401,8 +405,8 @@ namespace CustomInterfaces
     m_dblManager->setValue(m_properties["DeltaY"], deltaY);
 
     // Set indicator positions
-    m_rangeSelectors["NegativeEMinYPos"]->setMinimum(negativeY);
-    m_rangeSelectors["PositiveEMinYPos"]->setMinimum(positiveY);
+    m_uiForm.ppRawPlot->getRangeSelector("NegativeEMinYPos")->setMinimum(negativeY);
+    m_uiForm.ppRawPlot->getRangeSelector("PositiveEMinYPos")->setMinimum(positiveY);
 
     // Plot preview plot
     size_t spectrumIndex = symmWS->getIndexFromSpectrumNumber(spectrumNumber);
@@ -421,24 +425,29 @@ namespace CustomInterfaces
    */
   void IndirectSymmetrise::updateRangeSelectors(QtProperty *prop, double value)
   {
+    auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE");
+    auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE");
+    auto negativeEPV = m_uiForm.ppPreviewPlot->getRangeSelector("NegativeE");
+    auto positiveEPV = m_uiForm.ppPreviewPlot->getRangeSelector("PositiveE");
+
     value = fabs(value);
 
     if(prop == m_properties["EMin"])
     {
-      m_rangeSelectors["NegativeE_Raw"]->setMaximum(-value);
-      m_rangeSelectors["PositiveE_Raw"]->setMinimum(value);
+      negativeERaw->setMaximum(-value);
+      positiveERaw->setMinimum(value);
 
-      m_rangeSelectors["NegativeE_PV"]->setMinimum(-value);
-      m_rangeSelectors["PositiveE_PV"]->setMinimum(value);
+      negativeEPV->setMinimum(-value);
+      positiveEPV->setMinimum(value);
     }
 
     if(prop == m_properties["EMax"])
     {
-      m_rangeSelectors["NegativeE_Raw"]->setMinimum(-value);
-      m_rangeSelectors["PositiveE_Raw"]->setMaximum(value);
+      negativeERaw->setMinimum(-value);
+      positiveERaw->setMaximum(value);
 
-      m_rangeSelectors["NegativeE_PV"]->setMaximum(-value);
-      m_rangeSelectors["PositiveE_PV"]->setMaximum(value);
+      negativeEPV->setMaximum(-value);
+      positiveEPV->setMaximum(value);
     }
   }
 
@@ -449,13 +458,16 @@ namespace CustomInterfaces
    */
   void IndirectSymmetrise::xRangeMinChanged(double value)
   {
+    auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE");
+    auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE");
+
     MantidWidgets::RangeSelector *from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
 
-    if(from == m_rangeSelectors["PositiveE_Raw"])
+    if(from == positiveERaw)
     {
       m_dblManager->setValue(m_properties["EMin"], std::abs(value));
     }
-    else if(from == m_rangeSelectors["NegativeE_Raw"])
+    else if(from == negativeERaw)
     {
       m_dblManager->setValue(m_properties["EMax"], std::abs(value));
     }
@@ -468,13 +480,16 @@ namespace CustomInterfaces
    */
   void IndirectSymmetrise::xRangeMaxChanged(double value)
   {
+    auto negativeERaw = m_uiForm.ppRawPlot->getRangeSelector("NegativeE");
+    auto positiveERaw = m_uiForm.ppRawPlot->getRangeSelector("PositiveE");
+
     MantidWidgets::RangeSelector *from = qobject_cast<MantidWidgets::RangeSelector*>(sender());
 
-    if(from == m_rangeSelectors["PositiveE_Raw"])
+    if(from == positiveERaw)
     {
       m_dblManager->setValue(m_properties["EMax"], std::abs(value));
     }
-    else if(from == m_rangeSelectors["NegativeE_Raw"])
+    else if(from == negativeERaw)
     {
       m_dblManager->setValue(m_properties["EMin"], std::abs(value));
     }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
index 62e87cf653f4d83d78de43ac8888096869d8b2e5..2e35ed5775cab275e89d46d050334fe3a8412936 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/IndirectTab.cpp
@@ -4,10 +4,12 @@
 #include "MantidKernel/Logger.h"
 #include "MantidQtAPI/AlgorithmDialog.h"
 #include "MantidQtAPI/InterfaceManager.h"
+#include "MantidQtMantidWidgets/RangeSelector.h"
 
 using namespace Mantid::API;
 using namespace Mantid::Geometry;
 using namespace Mantid::Kernel;
+using namespace MantidQt::MantidWidgets;
 
 namespace
 {
@@ -22,7 +24,7 @@ namespace CustomInterfaces
   /** Constructor
    */
   IndirectTab::IndirectTab(QObject* parent) : QObject(parent),
-      m_rangeSelectors(), m_properties(),
+      m_properties(),
       m_dblManager(new QtDoublePropertyManager()), m_blnManager(new QtBoolPropertyManager()), m_grpManager(new QtGroupPropertyManager()),
       m_dblEdFac(new DoubleEditorFactory()),
       m_pythonRunner(),
@@ -146,36 +148,36 @@ namespace CustomInterfaces
    * Sets the edge bounds of plot to prevent the user inputting invalid values
    * Also sets limits for range selector movement
    *
-   * @param rsID :: The string index of the range selector in the map m_rangeSelectors
+   * @param rs :: Pointer to the RangeSelector
    * @param min :: The lower bound property in the property browser
    * @param max :: The upper bound property in the property browser
    * @param bounds :: The upper and lower bounds to be set
    */
-  void IndirectTab::setPlotPropertyRange(const QString& rsID, QtProperty* min, QtProperty* max,
+  void IndirectTab::setPlotPropertyRange(RangeSelector * rs, QtProperty* min, QtProperty* max,
       const QPair<double, double> & bounds)
   {
     m_dblManager->setMinimum(min, bounds.first);
     m_dblManager->setMaximum(min, bounds.second);
     m_dblManager->setMinimum(max, bounds.first);
     m_dblManager->setMaximum(max, bounds.second);
-    m_rangeSelectors[rsID]->setRange(bounds.first, bounds.second);
+    rs->setRange(bounds.first, bounds.second);
   }
 
   /**
    * Set the position of the range selectors on the mini plot
    *
-   * @param rsID :: The string index of the range selector in the map m_rangeSelectors
+   * @param rs :: Pointer to the RangeSelector
    * @param lower :: The lower bound property in the property browser
    * @param upper :: The upper bound property in the property browser
    * @param bounds :: The upper and lower bounds to be set
    */
-  void IndirectTab::setRangeSelector(const QString& rsID, QtProperty* lower, QtProperty* upper,
+  void IndirectTab::setRangeSelector(RangeSelector * rs, QtProperty* lower, QtProperty* upper,
       const QPair<double, double> & bounds)
   {
     m_dblManager->setValue(lower, bounds.first);
     m_dblManager->setValue(upper, bounds.second);
-    m_rangeSelectors[rsID]->setMinimum(bounds.first);
-    m_rangeSelectors[rsID]->setMaximum(bounds.second);
+    rs->setMinimum(bounds.first);
+    rs->setMaximum(bounds.second);
   }
 
   /**
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp
index 5fa2ba6da67deafac4326c88de9ce8fbd94a3a28..8e4f96c8d6df3ee2305d9ef3d25a7c96f12c57a4 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/JumpFit.cpp
@@ -19,8 +19,8 @@ namespace MantidQt
 			m_uiForm.setupUi(parent);
 
       // Create range selector
-      m_rangeSelectors["JumpFitQ"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-      connect(m_rangeSelectors["JumpFitQ"], SIGNAL(selectionChangedLazy(double, double)), this, SLOT(qRangeChanged(double, double)));
+      auto qRangeSelector = m_uiForm.ppPlot->addRangeSelector("JumpFitQ");
+      connect(qRangeSelector, SIGNAL(selectionChangedLazy(double, double)), this, SLOT(qRangeChanged(double, double)));
 
 			// Add the properties browser to the ui form
 			m_uiForm.treeSpace->addWidget(m_propTree);
@@ -213,6 +213,8 @@ namespace MantidQt
 
 			findAllWidths(mws);
 
+      auto qRangeSelector = m_uiForm.ppPlot->getRangeSelector("JumpFitQ");
+
 			if(m_spectraList.size() > 0)
 			{
 				m_uiForm.cbWidth->setEnabled(true);
@@ -227,11 +229,11 @@ namespace MantidQt
 
 				// Use the values from the instrument parameter file if we can
 				if(getInstrumentResolution(filename, res))
-					setRangeSelector("JumpFitQ", m_properties["QMin"], m_properties["QMax"], res);
+					setRangeSelector(qRangeSelector, m_properties["QMin"], m_properties["QMax"], res);
 				else
-					setRangeSelector("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range);
+					setRangeSelector(qRangeSelector, m_properties["QMin"], m_properties["QMax"], range);
 
-				setPlotPropertyRange("JumpFitQ", m_properties["QMin"], m_properties["QMax"], range);
+				setPlotPropertyRange(qRangeSelector, m_properties["QMin"], m_properties["QMax"], range);
 			}
 			else
 			{
@@ -341,13 +343,15 @@ namespace MantidQt
 		 */
     void JumpFit::updateProperties(QtProperty* prop, double val)
     {
+      auto qRangeSelector = m_uiForm.ppPlot->getRangeSelector("JumpFitQ");
+
     	if(prop == m_properties["QMin"])
     	{
-    		updateLowerGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val);
+    		updateLowerGuide(qRangeSelector, m_properties["QMin"], m_properties["QMax"], val);
     	}
     	else if (prop == m_properties["QMax"])
     	{
-				updateUpperGuide(m_rangeSelectors["JumpFitQ"], m_properties["QMin"], m_properties["QMax"], val);
+				updateUpperGuide(qRangeSelector, m_properties["QMin"], m_properties["QMax"], val);
     	}
     }
 	} // namespace CustomInterfaces
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
index 945d2d64ba0e5f2455e3f7e6ffd8ed5112c8753a..8e9c83c25e4220db9e8badaa56f5cc1e9fc45d11 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/MSDFit.cpp
@@ -44,10 +44,10 @@ namespace IDA
     m_msdTree->addProperty(m_properties["Start"]);
     m_msdTree->addProperty(m_properties["End"]);
 
-    m_rangeSelectors["MSDRange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
+    auto fitRangeSelector = m_uiForm.ppPlot->addRangeSelector("MSDRange");
 
-    connect(m_rangeSelectors["MSDRange"], SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
-    connect(m_rangeSelectors["MSDRange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
+    connect(fitRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minChanged(double)));
+    connect(fitRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxChanged(double)));
     connect(m_dblManager, SIGNAL(valueChanged(QtProperty*, double)), this, SLOT(updateRS(QtProperty*, double)));
 
     connect(m_uiForm.dsSampleInput, SIGNAL(dataReady(const QString&)), this, SLOT(newDataLoaded(const QString&)));
@@ -57,36 +57,53 @@ namespace IDA
 
     connect(m_uiForm.spSpectraMin, SIGNAL(valueChanged(int)), this, SLOT(specMinChanged(int)));
     connect(m_uiForm.spSpectraMax, SIGNAL(valueChanged(int)), this, SLOT(specMaxChanged(int)));
+
+    connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this, SLOT(plotFit()));
   }
 
   void MSDFit::run()
   {
-    QString pyInput =
-    "from IndirectDataAnalysis import msdfit\n"
-    "startX = " + QString::number(m_dblManager->value(m_properties["Start"])) +"\n"
-    "endX = " + QString::number(m_dblManager->value(m_properties["End"])) +"\n"
-    "specMin = " + m_uiForm.spSpectraMin->text() + "\n"
-    "specMax = " + m_uiForm.spSpectraMax->text() + "\n"
-    "input = '" + m_uiForm.dsSampleInput->getCurrentDataName() + "'\n";
-
-    if ( m_uiForm.ckPlot->isChecked() ) pyInput += "plot = True\n";
-    else pyInput += "plot = False\n";
-
-    if ( m_uiForm.ckSave->isChecked() ) pyInput += "save = True\n";
-    else pyInput += "save = False\n";
-
-    pyInput +=
-      "msdfit(input, startX, endX, spec_min=specMin, spec_max=specMax, Save=save, Plot=plot)\n";
-
-    QString pyOutput = runPythonCode(pyInput);
-    UNUSED_ARG(pyOutput);
+    if(!validate())
+      return;
 
     // Set the result workspace for Python script export
     QString dataName = m_uiForm.dsSampleInput->getCurrentDataName();
     m_pythonExportWsName = dataName.left(dataName.lastIndexOf("_")).toStdString() + "_msd";
 
-    // Plot the fit result
-    plotFit();
+    QString wsName = m_uiForm.dsSampleInput->getCurrentDataName();
+    double xStart = m_dblManager->value(m_properties["Start"]);
+    double xEnd = m_dblManager->value(m_properties["End"]);
+    long specMin = m_uiForm.spSpectraMin->value();
+    long specMax = m_uiForm.spSpectraMax->value();
+    bool plot = m_uiForm.ckPlot->isChecked();
+    bool save = m_uiForm.ckSave->isChecked();
+
+    IAlgorithm_sptr msdAlg = AlgorithmManager::Instance().create("MSDFit");
+    msdAlg->initialize();
+    msdAlg->setProperty("InputWorkspace", wsName.toStdString());
+    msdAlg->setProperty("XStart", xStart);
+    msdAlg->setProperty("XEnd", xEnd);
+    msdAlg->setProperty("SpecMin", specMin);
+    msdAlg->setProperty("SpecMax", specMax);
+    msdAlg->setProperty("Plot", plot);
+    msdAlg->setProperty("OutputWorkspace", m_pythonExportWsName);
+
+    m_batchAlgoRunner->addAlgorithm(msdAlg);
+
+    // Handle saving results
+    if(save)
+    {
+      API::BatchAlgorithmRunner::AlgorithmRuntimeProps saveInputProps;
+      saveInputProps["InputWorkspace"] = m_pythonExportWsName;
+
+      IAlgorithm_sptr saveAlg = AlgorithmManager::Instance().create("SaveNexusProcessed");
+      saveAlg->initialize();
+      saveAlg->setProperty("Filename", m_pythonExportWsName + ".nxs");
+
+      m_batchAlgoRunner->addAlgorithm(saveAlg, saveInputProps);
+    }
+
+    m_batchAlgoRunner->executeBatchAsync();
   }
 
   void MSDFit::singleFit()
@@ -94,20 +111,27 @@ namespace IDA
     if(!validate())
       return;
 
-    QString pyInput =
-      "from IndirectDataAnalysis import msdfit\n"
-      "startX = " + QString::number(m_dblManager->value(m_properties["Start"])) +"\n"
-      "endX = " + QString::number(m_dblManager->value(m_properties["End"])) +"\n"
-      "specMin = " + m_uiForm.spPlotSpectrum->text() + "\n"
-      "specMax = " + m_uiForm.spPlotSpectrum->text() + "\n"
-      "input = '" + m_uiForm.dsSampleInput->getCurrentDataName() + "'\n";
+    // Set the result workspace for Python script export
+    QString dataName = m_uiForm.dsSampleInput->getCurrentDataName();
+    m_pythonExportWsName = dataName.left(dataName.lastIndexOf("_")).toStdString() + "_msd";
+
+    QString wsName = m_uiForm.dsSampleInput->getCurrentDataName();
+    double xStart = m_dblManager->value(m_properties["Start"]);
+    double xEnd = m_dblManager->value(m_properties["End"]);
+    long fitSpec = m_uiForm.spPlotSpectrum->value();
 
-    pyInput +=
-      "output = msdfit(input, startX, endX, spec_min=specMin, spec_max=specMax, Save=False, Plot=False)\n"
-      "print output \n";
+    IAlgorithm_sptr msdAlg = AlgorithmManager::Instance().create("MSDFit");
+    msdAlg->initialize();
+    msdAlg->setProperty("InputWorkspace", wsName.toStdString());
+    msdAlg->setProperty("XStart", xStart);
+    msdAlg->setProperty("XEnd", xEnd);
+    msdAlg->setProperty("SpecMin", fitSpec);
+    msdAlg->setProperty("SpecMax", fitSpec);
+    msdAlg->setProperty("OutputWorkspace", m_pythonExportWsName);
 
-    QString pyOutput = runPythonCode(pyInput).trimmed();
-    plotFit(pyOutput, 0);
+    m_batchAlgoRunner->addAlgorithm(msdAlg);
+
+    m_batchAlgoRunner->executeBatchAsync();
   }
 
   bool MSDFit::validate()
@@ -157,17 +181,24 @@ namespace IDA
       m_uiForm.ppPlot->removeSpectrum("Fit");
 
       // Get the workspace
-      auto groupWs = Mantid::API::AnalysisDataService::Instance().retrieveWS<const Mantid::API::WorkspaceGroup>(wsName.toStdString());
-
-      // If the user has just done a single fit then we probably havent got a workspace to plot
-      // when the change the spectrum selector
-      if(specNo >= static_cast<int>(groupWs->size()))
-        return;
-
-      auto ws = boost::dynamic_pointer_cast<Mantid::API::MatrixWorkspace>(groupWs->getItem(specNo));
-
-      // Plot the new fit
-      m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red);
+      auto groupWs = AnalysisDataService::Instance().retrieveWS<const WorkspaceGroup>(wsName.toStdString());
+      auto groupWsNames = groupWs->getNames();
+
+      // Find the correct fit workspace and plot it
+      std::string searchString = "_" + std::to_string(static_cast<long long int>(specNo)) + "_Workspace";
+      for(auto it = groupWsNames.begin(); it != groupWsNames.end(); ++it)
+      {
+        std::string wsName = *it;
+        if(wsName.find(searchString) != std::string::npos)
+        {
+          // Get the fit workspace
+          auto ws = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName);
+          // Plot the new fit
+          m_uiForm.ppPlot->addSpectrum("Fit", ws, 1, Qt::red);
+          // Nothing else to do
+          return;
+        }
+      }
     }
   }
 
@@ -217,7 +248,7 @@ namespace IDA
     try
     {
       QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
-      m_rangeSelectors["MSDRange"]->setRange(range.first, range.second);
+      m_uiForm.ppPlot->getRangeSelector("MSDRange")->setRange(range.first, range.second);
     }
     catch(std::invalid_argument & exc)
     {
@@ -263,8 +294,10 @@ namespace IDA
 
   void MSDFit::updateRS(QtProperty* prop, double val)
   {
-    if ( prop == m_properties["Start"] ) m_rangeSelectors["MSDRange"]->setMinimum(val);
-    else if ( prop == m_properties["End"] ) m_rangeSelectors["MSDRange"]->setMaximum(val);
+    auto fitRangeSelector = m_uiForm.ppPlot->getRangeSelector("MSDRange");
+
+    if(prop == m_properties["Start"])    fitRangeSelector->setMinimum(val);
+    else if(prop == m_properties["End"]) fitRangeSelector->setMaximum(val);
   }
 
 } // namespace IDA
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp
index b6c99479cf4fad51bbd6837c890f404e60f8b6a6..45f9cfb9f52c6980186d1fea721f2f2fbaccb101 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Quasi.cpp
@@ -15,9 +15,9 @@ namespace MantidQt
 			m_uiForm.setupUi(parent);
 
       // Create range selector
-      m_rangeSelectors["QuasiERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-      connect(m_rangeSelectors["QuasiERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
-      connect(m_rangeSelectors["QuasiERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
+      auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("QuasiERange");
+      connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
+      connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
 
 			// Add the properties browser to the UI form
 			m_uiForm.treeSpace->addWidget(m_propTree);
@@ -276,8 +276,10 @@ namespace MantidQt
       updateMiniPlot();
 
 			QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
-			setRangeSelector("QuasiERange", m_properties["EMin"], m_properties["EMax"], range);
-			setPlotPropertyRange("QuasiERange", m_properties["EMin"], m_properties["EMax"], range);
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("QuasiERange");
+
+			setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
+			setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
 		}
 
 		/**
@@ -308,13 +310,15 @@ namespace MantidQt
 		 */
     void Quasi::updateProperties(QtProperty* prop, double val)
     {
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("QuasiERange");
+
     	if(prop == m_properties["EMin"])
     	{
-    		updateLowerGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val);
+    		updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
     	}
     	else if (prop == m_properties["EMax"])
     	{
-				updateUpperGuide(m_rangeSelectors["QuasiERange"], m_properties["EMin"], m_properties["EMax"], val);
+				updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
     	}
     }
 
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
index 6cd8e4e43a6af21c1f535575b1446e728c5002ec..ff425165cfb37cb57283e491ef3cf963f17448cb 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/ResNorm.cpp
@@ -14,9 +14,9 @@ namespace MantidQt
 			m_uiForm.setupUi(parent);
 
       // Create range selector
-      m_rangeSelectors["ResNormERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-      connect(m_rangeSelectors["ResNormERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
-      connect(m_rangeSelectors["ResNormERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
+      auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("ResNormERange");
+      connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
+      connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
 
 			// Add the properties browser to the ui form
 			m_uiForm.treeSpace->addWidget(m_propTree);
@@ -132,6 +132,8 @@ namespace MantidQt
       MatrixWorkspace_sptr vanWs = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(filename.toStdString());
       m_uiForm.spPreviewSpectrum->setMaximum(static_cast<int>(vanWs->getNumberHistograms()) - 1);
 
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("ResNormERange");
+
 			//Use the values from the instrument parameter file if we can
 			if(getInstrumentResolution(filename, res))
 			{
@@ -139,14 +141,14 @@ namespace MantidQt
 				res.first = res.first * 10;
 				res.second = res.second * 10;
 
-				setRangeSelector("ResNormERange", m_properties["EMin"], m_properties["EMax"], res);
+				setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], res);
 			}
 			else
 			{
-				setRangeSelector("ResNormERange", m_properties["EMin"], m_properties["EMax"], range);
+				setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
 			}
 
-			setPlotPropertyRange("ResNormERange", m_properties["EMin"], m_properties["EMax"], range);
+			setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
 		}
 
 		/**
@@ -177,13 +179,15 @@ namespace MantidQt
 		 */
     void ResNorm::updateProperties(QtProperty* prop, double val)
     {
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("ResNormERange");
+
     	if(prop == m_properties["EMin"])
     	{
-				updateLowerGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val);
+				updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
     	}
     	else if (prop == m_properties["EMax"])
     	{
-    		updateUpperGuide(m_rangeSelectors["ResNormERange"], m_properties["EMin"], m_properties["EMax"], val);
+    		updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
 			}
     }
 
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
index 78f13b6113eba92606f173de483b729ec919f7ec..22186a4b8c02300cdfb290e962f2099dd43f327c 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Indirect/Stretch.cpp
@@ -17,9 +17,9 @@ namespace MantidQt
 
 
       // Create range selector
-      m_rangeSelectors["StretchERange"] = new MantidWidgets::RangeSelector(m_uiForm.ppPlot);
-      connect(m_rangeSelectors["StretchERange"], SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
-      connect(m_rangeSelectors["StretchERange"], SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
+      auto eRangeSelector = m_uiForm.ppPlot->addRangeSelector("StretchERange");
+      connect(eRangeSelector, SIGNAL(minValueChanged(double)), this, SLOT(minValueChanged(double)));
+      connect(eRangeSelector, SIGNAL(maxValueChanged(double)), this, SLOT(maxValueChanged(double)));
 
 			// Add the properties browser to the ui form
 			m_uiForm.treeSpace->addWidget(m_propTree);
@@ -153,8 +153,9 @@ namespace MantidQt
 		{
 			m_uiForm.ppPlot->addSpectrum("Sample", filename, 0);
 			QPair<double, double> range = m_uiForm.ppPlot->getCurveRange("Sample");
-			setRangeSelector("StretchERange", m_properties["EMin"], m_properties["EMax"], range);
-			setPlotPropertyRange("StretchERange", m_properties["EMin"], m_properties["EMax"], range);
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("StretchERange");
+			setRangeSelector(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
+			setPlotPropertyRange(eRangeSelector, m_properties["EMin"], m_properties["EMax"], range);
 		}
 
 		/**
@@ -185,13 +186,15 @@ namespace MantidQt
 		 */
     void Stretch::updateProperties(QtProperty* prop, double val)
     {
+      auto eRangeSelector = m_uiForm.ppPlot->getRangeSelector("StretchERange");
+
     	if(prop == m_properties["EMin"])
     	{
-    		updateLowerGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val);
+    		updateLowerGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
     	}
     	else if (prop == m_properties["EMax"])
     	{
-				updateUpperGuide(m_rangeSelectors["StretchERange"], m_properties["EMin"], m_properties["EMax"], val);
+				updateUpperGuide(eRangeSelector, m_properties["EMin"], m_properties["EMax"], val);
     	}
     }
 
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp
index b2f22a1df402b4129aa2eb74b24b6b0665d7edcf..d2f78f8aea274891da734f5bd26faace46366734 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit.cpp
@@ -1,17 +1,21 @@
 #include "MantidQtCustomInterfaces/MultiDatasetFit.h"
-#include "MantidQtMantidWidgets/FunctionBrowser.h"
-#include "MantidQtMantidWidgets/FitOptionsBrowser.h"
-#include "MantidQtAPI/AlgorithmRunner.h"
 
+#include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/AnalysisDataService.h"
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/MatrixWorkspace.h"
 #include "MantidAPI/MultiDomainFunction.h"
-#include "MantidAPI/AlgorithmManager.h"
 #include "MantidAPI/ParameterTie.h"
+
 #include "MantidKernel/ArrayProperty.h"
 #include "MantidKernel/ArrayBoundedValidator.h"
 #include "MantidKernel/Exception.h"
 
+#include "MantidQtAPI/AlgorithmRunner.h"
+#include "MantidQtMantidWidgets/FitOptionsBrowser.h"
+#include "MantidQtMantidWidgets/FunctionBrowser.h"
+#include "MantidQtMantidWidgets/RangeSelector.h"
+
 #include "qtpropertybrowser.h"
 
 #include <QDialog>
@@ -27,14 +31,25 @@
 #include <qwt_plot_zoomer.h>
 #include <qwt_plot_panner.h>
 #include <qwt_plot_magnifier.h>
+#include <qwt_scale_div.h>
 #include <Poco/ActiveResult.h>
 
 #include <vector>
 #include <algorithm>
 
 namespace{
-  const int wsColumn = 0;
+  // columns in the data table
+  const int wsColumn      = 0;
   const int wsIndexColumn = 1;
+  const int startXColumn  = 2;
+  const int endXColumn    = 3;
+  // tool options pages
+  const int zoomToolPage  = 0;
+  const int panToolPage   = 1;
+  const int rangeToolPage = 2;
+  // colours of the fitting range selector
+  QColor rangeSelectorDisabledColor(Qt::darkGray);
+  QColor rangeSelectorEnabledColor(Qt::blue);
 }
 
 namespace MantidQt
@@ -249,6 +264,7 @@ DatasetPlotData::~DatasetPlotData()
  */
 void DatasetPlotData::setData(const Mantid::API::MatrixWorkspace *ws, int wsIndex, const Mantid::API::MatrixWorkspace *outputWS)
 {
+  bool haveFitCurves = outputWS && outputWS->getNumberHistograms() >= 3;
   std::vector<double> xValues = ws->readX(wsIndex);
   if ( ws->isHistogramData() )
   {
@@ -261,14 +277,19 @@ void DatasetPlotData::setData(const Mantid::API::MatrixWorkspace *ws, int wsInde
   }
   m_dataCurve->setData( xValues.data(), ws->readY(wsIndex).data(), static_cast<int>(xValues.size()) );
 
-  if ( outputWS && outputWS->getNumberHistograms() >= 3 )
+  if ( haveFitCurves )
   {
+    auto xBegin = std::lower_bound(xValues.begin(),xValues.end(), outputWS->readX(1).front());
+    if ( xBegin == xValues.end() ) return;
+    int i0 = static_cast<int>(std::distance(xValues.begin(),xBegin));
+    int n = static_cast<int>(outputWS->readY(1).size());
+    if ( i0 + n > static_cast<int>(xValues.size()) ) return;
     m_calcCurve = new QwtPlotCurve("calc");
-    m_calcCurve->setData( xValues.data(), outputWS->readY(1).data(), static_cast<int>(xValues.size()) );
+    m_calcCurve->setData( xValues.data() + i0, outputWS->readY(1).data(), n );
     QPen penCalc("red");
     m_calcCurve->setPen(penCalc);
     m_diffCurve = new QwtPlotCurve("diff");
-    m_diffCurve->setData( xValues.data(), outputWS->readY(2).data(), static_cast<int>(xValues.size()) );
+    m_diffCurve->setData( xValues.data() + i0, outputWS->readY(2).data(), n );
     QPen penDiff("green");
     m_diffCurve->setPen(penDiff);
   }
@@ -327,10 +348,14 @@ QwtDoubleRect DatasetPlotData::boundingRect() const
 /*                                PlotController                                            */
 /*==========================================================================================*/
 
-PlotController::PlotController(MultiDatasetFit *parent,QwtPlot *plot, QTableWidget *table, QComboBox *plotSelector, QPushButton *prev, QPushButton *next):
+PlotController::PlotController(MultiDatasetFit *parent, 
+                               QwtPlot *plot, 
+                               QTableWidget *table, 
+                               QComboBox *plotSelector, 
+                               QPushButton *prev, 
+                               QPushButton *next):
   QObject(parent),m_plot(plot),m_table(table),m_plotSelector(plotSelector),m_prevPlot(prev),m_nextPlot(next),m_currentIndex(-1)
 {
-  connect(parent,SIGNAL(dataTableUpdated()),this,SLOT(tableUpdated()));
   connect(prev,SIGNAL(clicked()),this,SLOT(prevPlot()));
   connect(next,SIGNAL(clicked()),this,SLOT(nextPlot()));
   connect(plotSelector,SIGNAL(currentIndexChanged(int)),this,SLOT(plotDataSet(int)));
@@ -339,10 +364,19 @@ PlotController::PlotController(MultiDatasetFit *parent,QwtPlot *plot, QTableWidg
       QwtPicker::DragSelection | QwtPicker::CornerToCorner, QwtPicker::AlwaysOff, plot->canvas());
 
   m_panner = new QwtPlotPanner( plot->canvas() );
-  m_panner->setEnabled(false);
 
   m_magnifier = new QwtPlotMagnifier( plot->canvas() );
-  m_magnifier->setEnabled( false );
+
+  m_rangeSelector = new MantidWidgets::RangeSelector(m_plot);
+  m_rangeSelector->setRange( -1e30, 1e30 );
+  m_rangeSelector->setMinimum(10);
+  m_rangeSelector->setMaximum(990);
+  connect(m_rangeSelector,SIGNAL(selectionChanged(double, double)),this,SLOT(updateFittingRange(double, double)));
+
+  disableAllTools();
+
+  m_plot->canvas()->installEventFilter(this);
+  
 }
 
 PlotController::~PlotController()
@@ -350,6 +384,22 @@ PlotController::~PlotController()
   m_plotData.clear();
 }
 
+bool PlotController::eventFilter(QObject *, QEvent *evn)
+{
+  if ( evn->type() == QEvent::MouseButtonDblClick )
+  {
+    if ( isRangeSelectorEnabled() )
+    {
+      resetRange();
+    }
+    else if ( isZoomEnabled() )
+    {
+      zoomToRange();
+    }
+  }
+  return false;
+}
+
 /**
  * Slot. Respond to changes in the data table.
  */
@@ -395,23 +445,10 @@ void PlotController::nextPlot()
   }
 }
 
-/**
- * Plot a data set.
- * @param index :: Index (row) of the data set in the table.
- */
-void PlotController::plotDataSet(int index)
+/// Get a pointer to a dataset data.
+/// @param index :: Index of a dataset.
+boost::shared_ptr<DatasetPlotData> PlotController::getData(int index)
 {
-  if ( index < 0 || index >= m_table->rowCount() )
-  {
-    clear();
-    owner()->checkDataSets();
-    m_plot->replot();
-    return;
-  }
-
-  bool resetZoom = m_plotData.isEmpty();
-
-  // create data if index is displayed for the first time
   if ( !m_plotData.contains(index) )
   {
     QString wsName = m_table->item( index, wsColumn )->text();
@@ -425,6 +462,7 @@ void PlotController::plotDataSet(int index)
     {
       auto value = boost::make_shared<DatasetPlotData>( wsName, wsIndex, outputWorkspaceName );
       m_plotData.insert(index, value );
+      return value;
     }
     catch(std::exception& e)
     {
@@ -432,10 +470,31 @@ void PlotController::plotDataSet(int index)
       clear();
       owner()->checkDataSets();
       m_plot->replot();
-      return;
+      return boost::shared_ptr<DatasetPlotData>();
     }
   }
 
+  return m_plotData[index];
+}
+
+/**
+ * Plot a data set.
+ * @param index :: Index (row) of the data set in the table.
+ */
+void PlotController::plotDataSet(int index)
+{
+  if ( index < 0 || index >= m_table->rowCount() )
+  {
+    clear();
+    owner()->checkDataSets();
+    m_plot->replot();
+    return;
+  }
+
+  bool resetZoom = m_plotData.isEmpty();
+
+  auto plotData = getData(index);
+
   // hide the previously shown data
   if ( m_currentIndex > -1 ) 
   {
@@ -451,9 +510,12 @@ void PlotController::plotDataSet(int index)
     m_plot->setAxisAutoScale(QwtPlot::xBottom);
     m_plot->setAxisAutoScale(QwtPlot::yLeft);
   }
-
+  // change the current data set index
+  m_currentIndex = index;
+  updateRange(index);
+  
   // show the new data
-  m_plotData[index]->show( m_plot );
+  plotData->show( m_plot );
   m_plot->replot();
   // the idea is to set the zoom base (the largest view) to the data's bounding rect
   // but it looks like the base is set to the union of dataRect and current zoomRect
@@ -464,8 +526,6 @@ void PlotController::plotDataSet(int index)
   {
     m_zoomer->setZoomBase(true);
   }
-  // change the current data set index
-  m_currentIndex = index;
   emit currentIndexChanged( index );
 }
 
@@ -479,22 +539,78 @@ void PlotController::update()
   plotDataSet( m_currentIndex );
 }
 
-void PlotController::enableZoom()
+/**
+ * Reset the fitting range to the current limits on the x axis.
+ */
+void PlotController::resetRange()
 {
-  m_zoomer->setEnabled(true);
+  QwtScaleMap xMap = m_plot->canvasMap(QwtPlot::xBottom);
+  double startX = xMap.s1();
+  double endX = xMap.s2();
+  m_rangeSelector->setMinimum( startX );
+  m_rangeSelector->setMaximum( endX );
+}
+
+/**
+ * Set zooming to the current fitting range.
+ */
+void PlotController::zoomToRange()
+{
+  QwtDoubleRect rect = m_zoomer->zoomRect();
+  rect.setX( m_rangeSelector->getMinimum() );
+  rect.setRight( m_rangeSelector->getMaximum() );
+  m_zoomer->zoom( rect );
+}
+
+/**
+ * Disable all plot tools. It is a helper method 
+ * to simplify switchig between tools.
+ */
+void PlotController::disableAllTools()
+{
+  m_zoomer->setEnabled(false);
   m_panner->setEnabled(false);
   m_magnifier->setEnabled(false);
-  m_plot->canvas()->setCursor(QCursor(Qt::CrossCursor));
+  m_rangeSelector->setEnabled(false);
+  m_rangeSelector->setColour(rangeSelectorDisabledColor);
+}
+
+template<class Tool>
+void PlotController::enableTool(Tool* tool, int cursor)
+{
+  disableAllTools();
+  tool->setEnabled(true);
+  m_plot->canvas()->setCursor(QCursor(static_cast<Qt::CursorShape>(cursor)));
+  m_plot->replot();
   owner()->showPlotInfo();
 }
 
+
+/**
+ * Enable zooming tool.
+ */
+void PlotController::enableZoom()
+{
+  enableTool(m_zoomer,Qt::CrossCursor);
+}
+
+/**
+ * Enable panning tool.
+ */
 void PlotController::enablePan()
 {
-  m_zoomer->setEnabled(false);
-  m_panner->setEnabled(true);
+  enableTool(m_panner,Qt::pointingHandCursor);
   m_magnifier->setEnabled(true);
-  m_plot->canvas()->setCursor(Qt::pointingHandCursor);
-  owner()->showPlotInfo();
+}
+
+/**
+ * Enable range selector tool.
+ */
+void PlotController::enableRange()
+{
+  enableTool(m_rangeSelector,Qt::pointingHandCursor);
+  m_rangeSelector->setColour(rangeSelectorEnabledColor);
+  m_plot->replot();
 }
 
 bool PlotController::isZoomEnabled() const
@@ -507,6 +623,31 @@ bool PlotController::isPanEnabled() const
   return m_panner->isEnabled();
 }
 
+bool PlotController::isRangeSelectorEnabled() const
+{
+  return m_rangeSelector->isEnabled();
+}
+
+/// Signal others that fitting range has been updated.
+void PlotController::updateFittingRange(double startX, double endX)
+{
+  emit fittingRangeChanged(m_currentIndex, startX, endX);
+}
+
+void PlotController::updateRange(int index)
+{
+  if ( index >= 0 && index == m_currentIndex )
+  {
+    const double startX = m_table->item(index,startXColumn)->text().toDouble();
+    const double endX = m_table->item(index,endXColumn)->text().toDouble();
+    m_rangeSelector->blockSignals(true);
+    m_rangeSelector->setMinimum(startX);
+    m_rangeSelector->setMaximum(endX);
+    m_rangeSelector->blockSignals(false);
+  }
+}
+
+
 /*==========================================================================================*/
 /*                               EditLocalParameterDialog                                   */
 /*==========================================================================================*/
@@ -594,11 +735,14 @@ void MultiDatasetFit::initLayout()
 
   m_uiForm.btnRemove->setEnabled( false );
 
-  connect(m_uiForm.btnAddWorkspace,SIGNAL(clicked()),this,SLOT(addWorkspace()));
-  connect(m_uiForm.btnRemove,SIGNAL(clicked()),this,SLOT(removeSelectedSpectra()));
-  connect(m_uiForm.dataTable,SIGNAL(itemSelectionChanged()), this,SLOT(workspaceSelectionChanged()));
   connect(m_uiForm.btnFit,SIGNAL(clicked()),this,SLOT(fit()));
-  connect(this,SIGNAL(dataTableUpdated()),this,SLOT(reset()));
+
+  m_dataController = new DataController(this, m_uiForm.dataTable);
+  connect(m_dataController,SIGNAL(dataTableUpdated()),this,SLOT(reset()));
+  connect(m_dataController,SIGNAL(hasSelection(bool)),  m_uiForm.btnRemove, SLOT(setEnabled(bool)));
+  connect(m_uiForm.btnAddWorkspace,SIGNAL(clicked()),m_dataController,SLOT(addWorkspace()));
+  connect(m_uiForm.btnRemove,SIGNAL(clicked()),m_dataController,SLOT(removeSelectedSpectra()));
+  connect(m_uiForm.cb_applyRangeToAll,SIGNAL(toggled(bool)),m_dataController,SLOT(setFittingRangeGlobal(bool)));
 
   m_plotController = new PlotController(this,
                                         m_uiForm.plot,
@@ -606,6 +750,9 @@ void MultiDatasetFit::initLayout()
                                         m_uiForm.cbPlotSelector,
                                         m_uiForm.btnPrev,
                                         m_uiForm.btnNext);
+  connect(m_dataController,SIGNAL(dataTableUpdated()),m_plotController,SLOT(tableUpdated()));
+  connect(m_dataController,SIGNAL(dataSetUpdated(int)),m_plotController,SLOT(updateRange(int)));
+  connect(m_plotController,SIGNAL(fittingRangeChanged(int, double, double)),m_dataController,SLOT(setFittingRange(int, double, double)));
   connect(m_plotController,SIGNAL(currentIndexChanged(int)),this,SLOT(updateLocalParameters(int)));
 
   QSplitter* splitter = new QSplitter(Qt::Vertical,this);
@@ -628,6 +775,7 @@ void MultiDatasetFit::initLayout()
   m_uiForm.plot->installEventFilter( this );
   m_uiForm.dataTable->installEventFilter( this );
 
+  m_plotController->enableZoom();
   showInfo( "Add some data, define fitting function" );
 
   loadSettings();
@@ -635,7 +783,9 @@ void MultiDatasetFit::initLayout()
 
 void MultiDatasetFit::createPlotToolbar()
 {
+  // ----- Main tool bar --------
   auto toolBar = new QToolBar(this);
+  toolBar->setIconSize(QSize(16,16));
   auto group = new QActionGroup(this);
  
   auto action = new QAction(this);
@@ -643,95 +793,27 @@ void MultiDatasetFit::createPlotToolbar()
   action->setCheckable(true);
   action->setChecked(true);
   action->setToolTip("Zooming tool");
-  connect(action,SIGNAL(triggered()),m_plotController,SLOT(enableZoom()));
+  connect(action,SIGNAL(triggered()),this,SLOT(enableZoom()));
   group->addAction(action);
 
   action = new QAction(this);
   action->setIcon(QIcon(":/MultiDatasetFit/icons/panning.png"));
   action->setCheckable(true);
   action->setToolTip("Panning tool");
-  connect(action,SIGNAL(triggered()),m_plotController,SLOT(enablePan()));
+  connect(action,SIGNAL(triggered()),this,SLOT(enablePan()));
+  group->addAction(action);
+
+  action = new QAction(this);
+  action->setIcon(QIcon(":/MultiDatasetFit/icons/range.png"));
+  action->setCheckable(true);
+  action->setToolTip("Set fitting range");
+  connect(action,SIGNAL(triggered()),this,SLOT(enableRange()));
   group->addAction(action);
 
   toolBar->addActions(group->actions());
 
   m_uiForm.horizontalLayout->insertWidget(3,toolBar);
-}
-
-/**
- * Show a dialog to select a workspace.
- */
-void MultiDatasetFit::addWorkspace()
-{
-  AddWorkspaceDialog dialog(this);
-  if ( dialog.exec() == QDialog::Accepted )
-  {
-    QString wsName = dialog.workspaceName().stripWhiteSpace();
-    // if name is empty assume that there are no workspaces in the ADS
-    if ( wsName.isEmpty() ) return;
-    if ( Mantid::API::AnalysisDataService::Instance().doesExist( wsName.toStdString()) )
-    {
-      auto indices = dialog.workspaceIndices();
-      for(auto i = indices.begin(); i != indices.end(); ++i)
-      {
-        addWorkspaceSpectrum( wsName, *i );
-      }
-      emit dataTableUpdated();
-    }
-    else
-    {
-      QMessageBox::warning(this,"MantidPlot - Warning",QString("Workspace \"%1\" doesn't exist.").arg(wsName));
-    }
-  }
-}
-
-/**
- * Add a spectrum from a workspace to the table.
- * @param wsName :: Name of a workspace.
- * @param wsIndex :: Index of a spectrum in the workspace (workspace index).
- */
-void MultiDatasetFit::addWorkspaceSpectrum(const QString &wsName, int wsIndex)
-{
-  int row = m_uiForm.dataTable->rowCount();
-  m_uiForm.dataTable->insertRow(row);
-
-  auto cell = new QTableWidgetItem( wsName );
-  m_uiForm.dataTable->setItem( row, wsColumn, cell );
-  cell = new QTableWidgetItem( QString::number(wsIndex) );
-  m_uiForm.dataTable->setItem( row, wsIndexColumn, cell );
-}
-
-/**
- * Slot. Called when selection in the data table changes.
- */
-void MultiDatasetFit::workspaceSelectionChanged()
-{
-  auto selection = m_uiForm.dataTable->selectionModel();
-  bool enableRemoveButton = selection->hasSelection();
-  if ( enableRemoveButton )
-  {
-    enableRemoveButton = selection->selectedRows().size() > 0;
-  }
-
-  m_uiForm.btnRemove->setEnabled( enableRemoveButton );
-}
 
-/**
- * Slot. Called when "Remove" button is pressed.
- */
-void MultiDatasetFit::removeSelectedSpectra()
-{
-  auto ranges = m_uiForm.dataTable->selectedRanges();
-  if ( ranges.isEmpty() ) return;
-  std::vector<int> rows;
-  for(auto range = ranges.begin(); range != ranges.end(); ++range)
-  {
-    for(int row = range->topRow(); row <= range->bottomRow(); ++row)
-    {
-      rows.push_back( row );
-    }
-  }
-  removeDataSets( rows );
 }
 
 /**
@@ -861,6 +943,9 @@ void MultiDatasetFit::fit()
     fit->setProperty("Function", fun );
     fit->setPropertyValue("InputWorkspace", getWorkspaceName(0));
     fit->setProperty("WorkspaceIndex", getWorkspaceIndex(0));
+    auto range = getFittingRange(0);
+    fit->setProperty( "StartX", range.first );
+    fit->setProperty( "EndX", range.second );
 
     int n = getNumberOfSpectra();
     for(int ispec = 1; ispec < n; ++ispec)
@@ -868,6 +953,9 @@ void MultiDatasetFit::fit()
       std::string suffix = boost::lexical_cast<std::string>(ispec);
       fit->setPropertyValue( "InputWorkspace_" + suffix, getWorkspaceName(ispec) );
       fit->setProperty( "WorkspaceIndex_" + suffix, getWorkspaceIndex(ispec) );
+      auto range = getFittingRange(ispec);
+      fit->setProperty( "StartX_" + suffix, range.first );
+      fit->setProperty( "EndX_" + suffix, range.second );
     }
 
     m_fitOptionsBrowser->copyPropertiesToAlgorithm(*fit);
@@ -906,7 +994,7 @@ void MultiDatasetFit::fit()
  */
 std::string MultiDatasetFit::getWorkspaceName(int i) const
 {
-  return m_uiForm.dataTable->item(i, wsColumn)->text().toStdString();
+  return m_dataController->getWorkspaceName(i);
 }
 
 /**
@@ -915,7 +1003,14 @@ std::string MultiDatasetFit::getWorkspaceName(int i) const
  */
 int MultiDatasetFit::getWorkspaceIndex(int i) const
 {
-  return m_uiForm.dataTable->item(i, wsIndexColumn)->text().toInt();
+  return m_dataController->getWorkspaceIndex(i);
+}
+
+/// Get the fitting range for the i-th spectrum
+/// @param i :: Index of a spectrum in the data table.
+std::pair<double,double> MultiDatasetFit::getFittingRange(int i) const
+{
+  return m_dataController->getFittingRange(i);
 }
 
 /**
@@ -923,7 +1018,7 @@ int MultiDatasetFit::getWorkspaceIndex(int i) const
  */
 int MultiDatasetFit::getNumberOfSpectra() const
 {
-  return m_uiForm.dataTable->rowCount();
+  return m_dataController->getNumberOfSpectra();
 }
 
 /**
@@ -1113,6 +1208,10 @@ void MultiDatasetFit::showPlotInfo()
   {
     text += "Click and drag to move. Use mouse wheel to zoom in and out.";
   }
+  else if ( m_plotController->isRangeSelectorEnabled() )
+  {
+    text += "Drag the vertical dashed lines to adjust the fitting range.";
+  }
   
   showInfo( text );
 }
@@ -1133,6 +1232,147 @@ void MultiDatasetFit::showTableInfo()
  * Check that the data sets in the table are valid and remove invalid ones.
  */
 void MultiDatasetFit::checkDataSets()
+{
+  m_dataController->checkDataSets();
+}
+
+void MultiDatasetFit::enableZoom()
+{
+  m_plotController->enableZoom();
+  m_uiForm.toolOptions->setCurrentIndex(zoomToolPage);
+}
+
+void MultiDatasetFit::enablePan()
+{
+  m_plotController->enablePan();
+  m_uiForm.toolOptions->setCurrentIndex(panToolPage);
+}
+
+void MultiDatasetFit::enableRange()
+{
+  m_plotController->enableRange();
+  m_uiForm.toolOptions->setCurrentIndex(rangeToolPage);
+}
+
+/*==========================================================================================*/
+/*                                    DataController                                        */
+/*==========================================================================================*/
+
+DataController::DataController(MultiDatasetFit *parent, QTableWidget *dataTable):
+  QObject(parent),m_dataTable(dataTable),m_isFittingRangeGlobal(false)
+{
+  connect(dataTable,SIGNAL(itemSelectionChanged()), this,SLOT(workspaceSelectionChanged()));
+  connect(dataTable,SIGNAL(cellChanged(int,int)),this,SLOT(updateDataset(int,int)));
+}
+
+/**
+ * Show a dialog to select a workspace from the ADS.
+ */
+void DataController::addWorkspace()
+{
+  AddWorkspaceDialog dialog(owner());
+  if ( dialog.exec() == QDialog::Accepted )
+  {
+    QString wsName = dialog.workspaceName().stripWhiteSpace();
+    // if name is empty assume that there are no workspaces in the ADS
+    if ( wsName.isEmpty() ) return;
+    if ( Mantid::API::AnalysisDataService::Instance().doesExist( wsName.toStdString()) )
+    {
+      auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::MatrixWorkspace>( wsName.toStdString() );
+      auto indices = dialog.workspaceIndices();
+      for(auto i = indices.begin(); i != indices.end(); ++i)
+      {
+        addWorkspaceSpectrum( wsName, *i, *ws );
+      }
+      emit dataTableUpdated();
+    }
+    else
+    {
+      QMessageBox::warning(owner(),"MantidPlot - Warning",QString("Workspace \"%1\" doesn't exist.").arg(wsName));
+    }
+  }
+}
+
+/**
+ * Add a spectrum from a workspace to the table.
+ * @param wsName :: Name of a workspace.
+ * @param wsIndex :: Index of a spectrum in the workspace (workspace index).
+ * @param ws :: The workspace.
+ */
+void DataController::addWorkspaceSpectrum(const QString &wsName, int wsIndex, const Mantid::API::MatrixWorkspace& ws)
+{
+  int row = m_dataTable->rowCount();
+  m_dataTable->insertRow(row);
+
+  auto cell = new QTableWidgetItem( wsName );
+  m_dataTable->setItem( row, wsColumn, cell );
+  auto flags = cell->flags();
+  flags ^= Qt::ItemIsEditable;
+  cell->setFlags(flags);
+
+  cell = new QTableWidgetItem( QString::number(wsIndex) );
+  m_dataTable->setItem( row, wsIndexColumn, cell );
+  flags = cell->flags();
+  flags ^= Qt::ItemIsEditable;
+  cell->setFlags(flags);
+
+  const double startX = ws.readX(wsIndex).front();
+  cell = new QTableWidgetItem( QString::number(startX) );
+  m_dataTable->setItem( row, startXColumn, cell );
+
+  const double endX = ws.readX(wsIndex).back();
+  cell = new QTableWidgetItem( QString::number(endX) );
+  m_dataTable->setItem( row, endXColumn, cell );
+}
+
+/**
+ * Slot. Called when selection in the data table changes.
+ */
+void DataController::workspaceSelectionChanged()
+{
+  auto selection = m_dataTable->selectionModel();
+  bool enableRemoveButton = selection->hasSelection();
+  if ( enableRemoveButton )
+  {
+    enableRemoveButton = selection->selectedRows().size() > 0;
+  }
+
+  emit hasSelection(enableRemoveButton);
+}
+
+/**
+ * Slot. Called when "Remove" button is pressed.
+ */
+void DataController::removeSelectedSpectra()
+{
+  auto ranges = m_dataTable->selectedRanges();
+  if ( ranges.isEmpty() ) return;
+  std::vector<int> rows;
+  for(auto range = ranges.begin(); range != ranges.end(); ++range)
+  {
+    for(int row = range->topRow(); row <= range->bottomRow(); ++row)
+    {
+      rows.push_back( row );
+    }
+  }
+  removeDataSets( rows );
+}
+
+void DataController::removeDataSets( std::vector<int>& rows )
+{
+  if ( rows.empty() ) return;
+  std::sort( rows.begin(), rows.end() );
+  for(auto row = rows.rbegin(); row != rows.rend(); ++row)
+  {
+    m_dataTable->removeRow( *row );
+  }
+  emit dataTableUpdated();
+}
+
+/**
+ * Check that the data sets in the table are valid and remove invalid ones.
+ */
+void DataController::checkDataSets()
 {
   std::vector<int> rows;
   int nrows = getNumberOfSpectra();
@@ -1157,15 +1397,82 @@ void MultiDatasetFit::checkDataSets()
   removeDataSets( rows );
 }
 
-void MultiDatasetFit::removeDataSets( std::vector<int>& rows )
+/**
+ * Get the workspace name of the i-th spectrum.
+ * @param i :: Index of a spectrum in the data table.
+ */
+std::string DataController::getWorkspaceName(int i) const
 {
-  if ( rows.empty() ) return;
-  std::sort( rows.begin(), rows.end() );
-  for(auto row = rows.rbegin(); row != rows.rend(); ++row)
+  return m_dataTable->item(i, wsColumn)->text().toStdString();
+}
+
+/**
+ * Get the workspace index of the i-th spectrum.
+ * @param i :: Index of a spectrum in the data table.
+ */
+int DataController::getWorkspaceIndex(int i) const
+{
+  return m_dataTable->item(i, wsIndexColumn)->text().toInt();
+}
+
+/**
+ * Get the number of spectra to fit to.
+ */
+int DataController::getNumberOfSpectra() const
+{
+  return m_dataTable->rowCount();
+}
+
+/**
+ * Enable global setting of fitting range (calls to setFittingRage(...)
+ * will set ranges of all datasets.)
+ * @param on :: True for global setting, false for individual.
+ */
+void DataController::setFittingRangeGlobal(bool on)
+{
+  m_isFittingRangeGlobal = on;
+}
+
+/**
+ * Set the fitting range for a data set or all data sets.
+ * @param i :: Index of a data set (spectrum). If m_isFittingRangeGlobal == true
+ *   the index is ignored and fitting range is set for all spectra.
+ * @param startX :: Start of the fitting range.
+ * @param endX :: End of the fitting range.
+ */
+void DataController::setFittingRange(int i, double startX, double endX)
+{
+  if ( i < 0 || i >= m_dataTable->rowCount() ) return;
+  auto start = QString::number(startX);
+  auto end = QString::number(endX);
+  if ( m_isFittingRangeGlobal )
   {
-    m_uiForm.dataTable->removeRow( *row );
+    for(int k = 0; k < getNumberOfSpectra(); ++k)
+    {
+      m_dataTable->item(k, startXColumn)->setText(start);
+      m_dataTable->item(k, endXColumn)->setText(end);
+    }
   }
-  emit dataTableUpdated();
+  else
+  {
+    m_dataTable->item(i, startXColumn)->setText(start);
+    m_dataTable->item(i, endXColumn)->setText(end);
+  }
+}
+
+/// Get the fitting range for a i-th data set.
+/// @param i :: Index of a dataset.
+std::pair<double,double> DataController::getFittingRange(int i) const
+{
+  double startX = m_dataTable->item(i, startXColumn)->text().toDouble();
+  double endX = m_dataTable->item(i, endXColumn)->text().toDouble();
+  return std::make_pair(startX,endX);
+}
+
+/// Inform the others that a dataset was updated.
+void DataController::updateDataset(int row, int)
+{
+  emit dataSetUpdated(row);
 }
 
 void MultiDatasetFit::loadSettings()
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp
index 4205e4ba18f50bbfe01db08d98a18d0b4e8c5375..eac1f56316055d5556eb4c6d68754ba422b12e0b 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCDataLoadingPresenter.cpp
@@ -9,6 +9,7 @@
 #include <QApplication>
 #include <QFileInfo>
 #include <QDir>
+#include <sstream>
 
 using namespace Mantid::Kernel;
 using namespace Mantid::API;
@@ -139,7 +140,9 @@ namespace CustomInterfaces
     std::vector<std::string> periods;
     for (size_t i=0; i<numPeriods; i++)
     {
-      periods.push_back(std::to_string(static_cast<long long int>(i)+1));
+      std::stringstream buffer;
+      buffer << i + 1;
+      periods.push_back(buffer.str());
     }
     m_view->setAvailablePeriods(periods);
   }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
index 22c2f7fd75ae174cb3780ea84d4a835187038369..2721c65258697ec121827a56a268a61e343d3184 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/MuonAnalysis.cpp
@@ -1999,15 +1999,12 @@ void MuonAnalysis::plotSpectrum(const QString& wsName, bool logScale)
     {
       QStringList& s = acquireWindowScript; // To keep short
 
-      s << "w = graph('%WSNAME%-1')";
-      s << "if w == None:";
-      s << "  pw = newGraph('%WSNAME%', 0)";
-      s << "  w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = pw)";
-      s << "  w.setObjectName('%WSNAME%')";
-      s << "else:";
-      s << "  plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = w, clearWindow = True)";
-      s << "  w.show()";
-      s << "  w.setFocus()";
+      s << "pw = newGraph('%WSNAME%-1', 0)";
+      s << "w = plotSpectrum('%WSNAME%', 0, %ERRORS%, %CONNECT%, window = pw, clearWindow = True)";
+      s << "w.setName('%WSNAME%-1')";
+      s << "w.setObjectName('%WSNAME%')";
+      s << "w.show()";
+      s << "w.setFocus()";
     }
 
     QString pyS;
diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
index 13250323b0455137caf1528d1cb21b6e26e1babb..b33d9f330f01014ba3af9be08736d10c90244c83 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
+++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/PreviewPlot.h
@@ -4,6 +4,7 @@
 #include "ui_PreviewPlot.h"
 
 #include "WidgetDllOption.h"
+#include "MantidQtMantidWidgets/RangeSelector.h"
 #include "MantidQtAPI/MantidWidget.h"
 
 #include "MantidAPI/MatrixWorkspace.h"
@@ -11,6 +12,7 @@
 #include <QActionGroup>
 #include <QHBoxLayout>
 #include <QLabel>
+#include <QMap>
 #include <QMenu>
 
 #include <qwt_plot.h>
@@ -81,10 +83,21 @@ namespace MantidWidgets
 
     bool hasCurve(const QString & curveName);
 
+    RangeSelector * addRangeSelector(const QString & rsName,
+                                     RangeSelector::SelectType type = RangeSelector::XMINMAX);
+    RangeSelector * getRangeSelector(const QString & rsName);
+    void removeRangeSelector(const QString & rsName, bool del);
+
+    bool hasRangeSelector(const QString & rsName);
+
+    QString getAxisType(int axisID);
+
   signals:
     /// Signals that the plot should be refreshed
     void needToReplot();
     void needToHardReplot();
+    /// Signals that the axis scale has been changed
+    void axisScaleChanged();
 
   public slots:
     void showLegend(bool show);
@@ -118,7 +131,6 @@ namespace MantidWidgets
 
     QList<QAction *> addOptionsToMenus(QString menuName, QActionGroup *group, QStringList items, QString defaultItem);
 
-    QString getAxisType(int axisID);
     QStringList getCurvesForWorkspace(const Mantid::API::MatrixWorkspace_sptr ws);
 
   private slots:
@@ -129,6 +141,11 @@ namespace MantidWidgets
   private:
     Ui::PreviewPlot m_uiForm;
 
+    /// Range selector widget for mini plot
+    QMap<QString, MantidQt::MantidWidgets::RangeSelector *> m_rangeSelectors;
+    /// Cache of range selector visibility
+    QMap<QString, bool> m_rsVisibility;
+
     /// Poco Observers for ADS Notifications
     Poco::NObserver<PreviewPlot, Mantid::API::WorkspacePreDeleteNotification> m_removeObserver;
     Poco::NObserver<PreviewPlot, Mantid::API::WorkspaceAfterReplaceNotification> m_replaceObserver;
@@ -136,7 +153,6 @@ namespace MantidWidgets
     /// If the widget was initialised
     bool m_init;
 
-    /// The plot its self
     friend class RangeSelector;
 
     /// Map of curve key to plot info
diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h
index 0b16b896cdcef8ec2005359653ddd98df9a21604..38c4235775d9da75a4c95fdf405c6ccbef1e902d 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h
+++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/RangeSelector.h
@@ -2,7 +2,6 @@
 #define MANTIDQT_MANTIDWIDGET_POSHPLOTTING_H
 
 #include "WidgetDllOption.h"
-#include "PreviewPlot.h"
 
 #include <qwt_plot_picker.h>
 #include <qwt_plot.h>
@@ -14,6 +13,8 @@ namespace MantidQt
 {
 namespace MantidWidgets
 {
+  class PreviewPlot;
+
   /**
   * Allows for simpler (in a way) selection of a range on a QwtPlot in MantidQt.
   * @author Michael Whitty, RAL ISIS
@@ -35,6 +36,9 @@ namespace MantidWidgets
     double getMinimum() { return m_min; } ///< Returns current min value
     double getMaximum() { return m_max; } ///< Reutnrs current max value
 
+    SelectType getType() { return m_type; }
+    bool isVisible() { return m_visible; }
+
   signals:
     void minValueChanged(double);
     void maxValueChanged(double);
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp
index 7b0f2ae93709cdbff11739a31e0c495f8e050b10..cad804da02199856bfdf4a15bdb0f676bb4286e4 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/DataSelector.cpp
@@ -24,7 +24,7 @@ namespace MantidQt
       connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SIGNAL(loadClicked()));
 
       //data selected changes
-      connect(m_uiForm.rfFileInput, SIGNAL(filesFound()), this, SLOT(handleFileInput()));
+      connect(m_uiForm.rfFileInput, SIGNAL(filesFoundChanged()), this, SLOT(handleFileInput()));
       connect(m_uiForm.wsWorkspaceInput, SIGNAL(currentIndexChanged(int)), this, SLOT(handleWorkspaceInput()));
       connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SLOT(handleFileInput()));
 
@@ -66,7 +66,7 @@ namespace MantidQt
     /**
      * Get if the file selector is currently being shown.
      *
-     * @return :: true if it is visible, otherwise false 
+     * @return :: true if it is visible, otherwise false
      */
     bool DataSelector::isFileSelectorVisible() const
     {
@@ -77,7 +77,7 @@ namespace MantidQt
     /**
      * Get if the workspace selector is currently being shown.
      *
-     * @return :: true if it is visible, otherwise false 
+     * @return :: true if it is visible, otherwise false
      */
     bool DataSelector::isWorkspaceSelectorVisible() const
     {
@@ -107,7 +107,7 @@ namespace MantidQt
         if(isValid && m_autoLoad)
         {
           const QString wsName = getCurrentDataName();
-          
+
           if(!AnalysisDataService::Instance().doesExist(wsName.toStdString()))
           {
             //attempt to reload if we can
@@ -118,9 +118,9 @@ namespace MantidQt
             loadAlg->setProperty("Filename", filepath.toStdString());
             loadAlg->setProperty("OutputWorkspace", wsName.toStdString());
             loadAlg->execute();
-            
+
             isValid = AnalysisDataService::Instance().doesExist(wsName.toStdString());
-            
+
             if(!isValid)
             {
               m_uiForm.rfFileInput->setFileProblem("The specified workspace is missing from the analysis data service");
@@ -448,18 +448,18 @@ namespace MantidQt
      */
     void DataSelector::dropEvent(QDropEvent *de)
     {
-      const QMimeData *mimeData = de->mimeData();  
+      const QMimeData *mimeData = de->mimeData();
       auto before_action = de->dropAction();
 
       if (de->mimeData() && mimeData->text().contains(" = mtd[\"")){
         m_uiForm.wsWorkspaceInput->dropEvent(de);
-        if (de->dropAction() == before_action){    
+        if (de->dropAction() == before_action){
           m_uiForm.cbInputType->setCurrentIndex(1);
           return;
         }
-        de->setDropAction(before_action);    
+        de->setDropAction(before_action);
       }
-  
+
       m_uiForm.rfFileInput->dropEvent(de);
       if (de->dropAction() == before_action){
         m_uiForm.cbInputType->setCurrentIndex(0);
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp
index b235a39355910a550a22584e52e0c94e01a5e8d2..88b8e682820ea1c0f96308cafe7e5e27a5023e12 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/PreviewPlot.cpp
@@ -327,6 +327,70 @@ bool PreviewPlot::hasCurve(const QString & curveName)
 }
 
 
+/**
+ * Attaches a RangeSelector to the plot and stores it.
+ *
+ * @param rsName Name of range selector
+ * @return RangeSelector object
+ */
+RangeSelector * PreviewPlot::addRangeSelector(const QString & rsName,
+                                              RangeSelector::SelectType type)
+{
+  if(hasRangeSelector(rsName))
+    throw std::runtime_error("RangeSelector already exists on PreviewPlot");
+
+  m_rangeSelectors[rsName] = new MantidWidgets::RangeSelector(m_uiForm.plot, type);
+  m_rsVisibility[rsName] = m_rangeSelectors[rsName]->isVisible();
+
+  return m_rangeSelectors[rsName];
+}
+
+
+/**
+ * Gets a RangeSelector.
+ *
+ * @param rsName Name of range selector
+ * @return RangeSelector object
+ */
+RangeSelector * PreviewPlot::getRangeSelector(const QString & rsName)
+{
+  if(!hasRangeSelector(rsName))
+    throw std::runtime_error("RangeSelector not found on PreviewPlot");
+
+  return m_rangeSelectors[rsName];
+}
+
+
+/**
+ * Removes a RangeSelector from the plot.
+ *
+ * @param rsName Name of range selector
+ * @param del If the object should be deleted
+ */
+void PreviewPlot::removeRangeSelector(const QString & rsName, bool del = true)
+{
+  if(!hasRangeSelector(rsName))
+    return;
+
+  if(del)
+    delete m_rangeSelectors[rsName];
+
+  m_rangeSelectors.remove(rsName);
+}
+
+
+/**
+ * Checks to see if a range selector with a given name is on the plot.
+ *
+ * @param rsName Name of range selector
+ * @return True if the plot has a range selector with the given name
+ */
+bool PreviewPlot::hasRangeSelector(const QString & rsName)
+{
+  return m_rangeSelectors.contains(rsName);
+}
+
+
 /**
  * Shows or hides the plot legend.
  *
@@ -723,6 +787,31 @@ void PreviewPlot::handleAxisTypeSelect()
   if(yEngine)
     m_uiForm.plot->setAxisScaleEngine(QwtPlot::yLeft, yEngine);
 
+  emit axisScaleChanged();
+
+  // Hide range selectors on X axis when X axis scale is X^2
+  bool xIsSquared = xAxisType == "Squared";
+  for(auto it = m_rangeSelectors.begin(); it != m_rangeSelectors.end(); ++it)
+  {
+    QString rsName = it.key();
+    RangeSelector * rs = it.value();
+    RangeSelector::SelectType type = rs->getType();
+
+    if(type == RangeSelector:: XMINMAX || type == RangeSelector::XSINGLE)
+    {
+      // When setting to invisible save the last visibility setting
+      if(xIsSquared)
+      {
+        m_rsVisibility[rsName] = rs->isVisible();
+        rs->setVisible(false);
+      }
+      else
+      {
+        rs->setVisible(m_rsVisibility[rsName]);
+      }
+    }
+  }
+
   // Update the plot
   emit needToHardReplot();
 }
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp
index 30334d6da2cbcb18b9c5d0a5c93a69c66db2c092..ad084ec45389bb207c207f52120a9241493d3287 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/RangeSelector.cpp
@@ -5,6 +5,8 @@
 #include <QEvent>
 #include <QMouseEvent>
 
+#include "MantidQtMantidWidgets/PreviewPlot.h"
+
 using namespace MantidQt::MantidWidgets;
 
 RangeSelector::RangeSelector(QwtPlot* plot, SelectType type, bool visible, bool infoOnly)
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp
index e44a8a5f785d6a35a43608f091ed04f9679a54be..e6d8d87c6c1c37ee8484e845ba9cc91fb9ad052f 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/SlicingAlgorithmDialog.cpp
@@ -459,7 +459,7 @@ namespace MantidQt
 
     /**
      * Resets the axis dimensions externally.
-     * @param propertyName The name of the axis dimension.
+     * @param index The property index.
      * @param propertyValue The new value of the axis dimension.
      */
     void SlicingAlgorithmDialog::resestAlignedDimProperty(size_t index, QString propertyValue)
diff --git a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h
index a95b7fd55e33f3b9a5593228fe0f8e1e1280fe60..775f269a859e69a905042904de78d53e56020326 100644
--- a/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h
+++ b/Code/Mantid/MantidQt/SliceViewer/inc/MantidQtSliceViewer/QPeaksTableModel.h
@@ -1,4 +1,5 @@
 #include <QAbstractTableModel>
+#include "DllOption.h"
 #include <boost/shared_ptr.hpp>
 #include "boost/bind.hpp"
 #include "boost/function.hpp"
@@ -47,7 +48,7 @@ namespace MantidQt
     File change history is stored at: <https://github.com/mantidproject/mantid>.
     Code Documentation is available at: <http://doxygen.mantidproject.org>
 */
-    class QPeaksTableModel : public QAbstractTableModel
+    class EXPORT_OPT_MANTIDQT_SLICEVIEWER QPeaksTableModel : public QAbstractTableModel
     {
       Q_OBJECT
     public:
diff --git a/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..dd49338b31255373fb60d986554ea8a6ce46902c
--- /dev/null
+++ b/Code/Mantid/Testing/Data/DocTest/irs26173_graphite002_red.nxs.md5
@@ -0,0 +1 @@
+f52ac64ec23fb50b6d4649592aee4fdb
\ No newline at end of file
diff --git a/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..1c698d0a291b8ff23c2663d216bc8082b9061928
--- /dev/null
+++ b/Code/Mantid/Testing/Data/DocTest/irs26176_graphite002_red.nxs.md5
@@ -0,0 +1 @@
+a69078cfcdf156b59327798cc71f4d51
\ No newline at end of file
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py
index 92e54edd1f4c9c1eca7134d7de9d1643a8513d76..774a0101e46685db6ce92d70767383206c150145 100644
--- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectAnalysisTest.py
@@ -9,23 +9,20 @@ class ElasticWindowMultipleTest(stresstesting.MantidStressTest):
 
     def runTest(self):
         Load(Filename='osi92762_graphite002_red.nxs,osi92763_graphite002_red.nxs',
-            OutputWorkspace='__ElWinMulti_InputWS')
+             OutputWorkspace='__ElWinMulti_InputWS')
 
-        ElasticWindowMultiple(
-            InputWorkspaces='__ElWinMulti_InputWS',
-            Range1Start=-0.2,
-            Range1End=0.2,
-            Range2Start='-0.24',
-            Range2End='-0.22',
-            OutputInQ='eq',
-            OutputInQSquared='eq2',
-            OutputELF='elf',
-            OutputELT='elt')
+        ElasticWindowMultiple(InputWorkspaces='__ElWinMulti_InputWS',
+                              Range1Start=-0.2,
+                              Range1End=0.2,
+                              Range2Start='-0.24',
+                              Range2End='-0.22',
+                              OutputInQ='eq',
+                              OutputInQSquared='eq2',
+                              OutputELF='elf',
+                              OutputELT='elt')
 
         GroupWorkspaces(InputWorkspaces=['elf', 'elt'],
-            OutputWorkspace='__ElWinMulti_OutputWS')
-
-        SaveNexus(Filename='__ElWinMulti_OutputWS', InputWorkspace='__ElWinMulti_OutputWS')
+                        OutputWorkspace='__ElWinMulti_OutputWS')
 
     def validate(self):
         self.tolerance = 1e-10
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
index 435a08ab9b57efa6a6f9488bfd88a5ae54f4ce12..4b28cd38792e22f75203d7b1672b4b8fd069af3e 100644
--- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISISIndirectInelastic.py
@@ -12,7 +12,7 @@ from mantid.api import FileFinder
 # Import our workflows.
 from inelastic_indirect_reducer import IndirectReducer
 from inelastic_indirect_reduction_steps import CreateCalibrationWorkspace
-from IndirectDataAnalysis import msdfit, furyfitSeq, furyfitMult, confitSeq, abscorFeeder
+from IndirectDataAnalysis import furyfitSeq, furyfitMult, confitSeq, abscorFeeder
 
 '''
 - TOSCA only supported by "Reduction" (the Energy Transfer tab of C2E).
@@ -780,21 +780,12 @@ class ISISIndirectInelasticElwinAndMSDFit(ISISIndirectInelasticBase):
                                InputWorkspace=ws)
 
         eq2_file = elwin_results[1]
-        msdfit_result = msdfit(eq2_file,
-                               startX=self.startX,
-                               endX=self.endX,
-                               Save=False,
+        msdfit_result = MSDFit(InputWorkspace=eq2_file,
+                               XStart=self.startX,
+                               XEnd=self.endX,
+                               SpecMax=1,
                                Plot=False)
 
-        # @TODO: MSDFit has some other, as yet unfinalised, workspaces as its
-        #        output.  We need to test these too, eventually.
-
-        # Annoyingly, MSDFit eats the EQ2 workspaces we feed it, so let's
-        # reload them for checking against the reference files later.
-        for ws, filename in zip(elwin_results, int_files):
-            LoadNexusProcessed(Filename=filename,
-                               OutputWorkspace=ws)
-
         # Clean up the intermediate files.
         for filename in int_files:
             os.remove(filename)
@@ -803,17 +794,15 @@ class ISISIndirectInelasticElwinAndMSDFit(ISISIndirectInelasticBase):
         # final MSDFit result.
         self.result_names = [elwin_results[0],  # EQ1
                              elwin_results[1],  # EQ2
-                             msdfit_result]
+                             msdfit_result[2].name()]  # Fit workspace
 
     def _validate_properties(self):
         """Check the object properties are in an expected state to continue"""
 
         if type(self.files) != list or len(self.files) != 2:
-            raise RuntimeError("files should be a list of exactly 2 "
-                               "strings")
+            raise RuntimeError("files should be a list of exactly 2 strings")
         if type(self.eRange) != list or len(self.eRange) != 2:
-            raise RuntimeError("eRange should be a list of exactly 2 "
-                               "values")
+            raise RuntimeError("eRange should be a list of exactly 2 values")
         if type(self.startX) != float:
             raise RuntimeError("startX should be a float")
         if type(self.endX) != float:
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py
index d030a5185bcfc3a47c1b75b164ad12aa5bae98c1..0a423dadcdc9182c6b77125fb5eb78a0c4a6103c 100644
--- a/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/ISIS_LETReduction.py
@@ -190,6 +190,8 @@ class ReduceLET_MultiRep2015(ReductionWrapper):
         # Should be possibility to define spectra_to_monitors_list to just monitors list, if
         # spectra_to_monitors_list remains undefined
         prop['spectra_to_monitors_list']=5506
+        # similar to the one above. old IDF do not contain this property
+        prop['multirep_tof_specta_list']="12416,21761"
         return prop
       #
     @iliad
@@ -226,7 +228,7 @@ class ReduceLET_MultiRep2015(ReductionWrapper):
             """
             # Note -- properties have the same names  as the list of advanced and
             # main properties
-            ei = prop_man.incident_energy
+            ei = PropertyManager.incident_energy.get_current()
             # sample run is more then just list of runs, so we use
             # the formalization below to access its methods
             run_num = PropertyManager.sample_run.run_number()
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py b/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py
index adae2d6a95035c91847b6f0e01f0ddf5745427d7..7c9e50ae3c20f77e6f58cbf38dd65f4eb0c5938e 100644
--- a/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/REFLReduction.py
@@ -34,9 +34,8 @@ class REFLReduction(stresstesting.MantidStressTest):
                       OutputWorkspace='reflectivity_119814')
 
     def validate(self):
-        # Be more tolerant with the output, mainly because of the errors.
-        # The following tolerance check the errors up to the third digit.
-        self.tolerance = 0.25
+        # Be more tolerant with the output.
+        self.tolerance = 0.0001
         self.disableChecking.append('Instrument')
         self.disableChecking.append('Sample')
         self.disableChecking.append('SpectraMap')
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt
index aabeadb41010fe5c637ed802fddb88a7c5c69e06..605b3dcadab38db0d862a808d3da37c75ed39a98 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/CMakeLists.txt
@@ -1,2 +1,3 @@
 add_subdirectory( SplatterPlot )
 add_subdirectory( ScaleWorkspace )
+add_subdirectory( PeaksFilter )
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c2820075f5b9546d8af25164e2a90a4356c9276c
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/CMakeLists.txt
@@ -0,0 +1,16 @@
+PROJECT(PeaksFilter)
+
+ADD_PARAVIEW_PLUGIN(MantidParaViewPeaksFilterSMPlugin "1.0"
+SERVER_MANAGER_XML PeaksFilter.xml
+SERVER_MANAGER_SOURCES vtkPeaksFilter.cxx
+GUI_RESOURCE_FILES PeaksFilterGUI.xml)
+# Add to the 'VatesParaViewPlugins' group in VS
+set_property( TARGET MantidParaViewPeaksFilterSMPlugin PROPERTY FOLDER "MantidVatesParaViewPlugins")
+
+target_link_libraries( MantidParaViewPeaksFilterSMPlugin
+${MANTID_SUBPROJECT_LIBS} )
+
+# Put library into subfolder.
+SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewPeaksFilterSMPlugin  ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR})
+
+install( TARGETS MantidParaViewPeaksFilterSMPlugin ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR})
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1467d2c912c6d2a89b5989623140b1432bb75abf
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilter.xml
@@ -0,0 +1,40 @@
+<ServerManagerConfiguration>
+  <!-- Begin ScaleWorkspace -->
+  <ProxyGroup name="filters">
+    <SourceProxy name="MantidParaViewPeaksFilter" class="vtkPeaksFilter" label="MD Peaks Filter" >
+      <InputProperty
+        name="Input"
+        command="SetInputConnection">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources"/>
+          <Group name="filters"/>
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid"/>
+        </DataTypeDomain>
+      </InputProperty>
+	  <StringVectorProperty name="PeaksWorkspace" command="SetPeaksWorkspace" number_of_elements="1" panel_visibility="never"/>
+    <DoubleVectorProperty name="RadiusNoShape" command="SetRadiusNoShape" number_of_elements="1" default_values="0.5">
+      <DoubleRangeDomain name="range" min="0.001" max="10" />
+      <Documentation>
+        This sets the radius for peaks without a peak shape.
+      </Documentation>
+    </DoubleVectorProperty>
+    <IntVectorProperty name="RadiusType" command="SetRadiusType" number_of_elements="1" default_values="0">
+      <EnumerationDomain name="enum">
+        <Entry value="0" text="Radius"/>
+        <Entry value="1" text="Outer Radius"/>
+        <Entry value="2" text="Inner Radius"/>
+      </EnumerationDomain>
+      <Documentation>
+        Set the radius type.
+      </Documentation>
+    </IntVectorProperty>
+    <StringVectorProperty name="Delimiter" command="SetDelimiter" number_of_elements="1" panel_visibility="never"/>
+	 <DoubleVectorProperty name="MinValue"	command="GetMinValue" information_only="1"/>
+    <DoubleVectorProperty name="MaxValue" command="GetMaxValue" information_only="1"/>
+	<StringVectorProperty name="Instrument" command="GetInstrument" number_of_elements="1" information_only="1"/>
+    </SourceProxy>
+  </ProxyGroup>
+  <!-- End ScaleWorkspace -->
+</ServerManagerConfiguration>
\ No newline at end of file
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e06286144048cec1062833f566617891c9997d9
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/PeaksFilterGUI.xml
@@ -0,0 +1,6 @@
+  <ParaViewFilters>
+    <Category name="Mantid" menu_label="&amp;Mantid">
+      <!-- adds a new category and then adds our filter to it -->
+      <Filter name="MantidParaViewPeaksFilter"/>
+    </Category>
+  </ParaViewFilters>
\ No newline at end of file
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..fdf20fa28303c06777aa95d603caa228a2fe86c2
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.cxx
@@ -0,0 +1,241 @@
+#include "vtkPeaksFilter.h"
+#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/FilteringUpdateProgressAction.h"
+#include "MantidVatesAPI/FieldDataToMetadata.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
+
+#include <boost/scoped_ptr.hpp>
+
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkNew.h>
+#include <vtkObjectFactory.h>
+#include <vtkUnstructuredGridAlgorithm.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkFieldData.h>
+
+vtkStandardNewMacro(vtkPeaksFilter);
+
+using namespace Mantid::VATES;
+
+vtkPeaksFilter::vtkPeaksFilter() : m_peaksWorkspaceNames(""),
+                                   m_delimiter(";"),
+                                   m_radiusNoShape(0.5),
+                                   m_radiusType(0),
+                                   m_minValue(0.1),
+                                   m_maxValue(0.1),
+                                   m_metadataJsonManager(new MetadataJsonManager()),
+                                   m_vatesConfigurations(new VatesConfigurations()),
+                                   m_coordinateSystem(0)
+{
+  this->SetNumberOfInputPorts(1);
+  this->SetNumberOfOutputPorts(1);
+}
+
+vtkPeaksFilter::~vtkPeaksFilter()
+{
+}
+
+
+int vtkPeaksFilter::RequestData(vtkInformation*, vtkInformationVector **inputVector, vtkInformationVector *outputVector)
+{
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkUnstructuredGrid *inputDataSet = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+  vtkUnstructuredGrid *outputDataSet = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // If the field data does not contain the metadata, then don't do anything.
+  try
+  {
+    vtkFieldData* fieldData = inputDataSet->GetFieldData();
+  
+    // Extract information for meta data in Json format.
+    FieldDataToMetadata fieldDataToMetadata;
+
+    std::string jsonString = fieldDataToMetadata(fieldData, m_vatesConfigurations->getMetadataIdJson());
+    m_metadataJsonManager->readInSerializedJson(jsonString);
+
+    m_minValue = m_metadataJsonManager->getMinValue();
+    m_maxValue = m_metadataJsonManager->getMaxValue();
+    m_instrument = m_metadataJsonManager->getInstrument();
+    m_coordinateSystem = m_metadataJsonManager->getSpecialCoordinates();
+  }
+  catch (...)
+  {
+  }
+
+  std::vector<std::string> peaksWorkspaceNames = extractPeakWorkspaceNames();
+  std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces = getPeaksWorkspaces(peaksWorkspaceNames);
+
+  if (peaksWorkspaces.empty())
+  {
+    return 0;
+  }
+  FilterUpdateProgressAction<vtkPeaksFilter> drawingProgressUpdate(this, "Drawing...");
+
+  vtkDataSetToPeaksFilteredDataSet peaksFilter(inputDataSet, outputDataSet);
+  peaksFilter.initialize(peaksWorkspaces, m_radiusNoShape, m_radiusType, m_coordinateSystem);
+  peaksFilter.execute(drawingProgressUpdate);
+  return 1;
+}
+
+int vtkPeaksFilter::RequestInformation(vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector*)
+{
+  // Set the meta data 
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkUnstructuredGrid *inputDataSet = vtkUnstructuredGrid::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  // If the field data does not contain the metadata, then don't do anything.
+  try
+  {
+    vtkFieldData* fieldData = inputDataSet->GetFieldData();
+  
+    // Extract information for meta data in Json format.
+    FieldDataToMetadata fieldDataToMetadata;
+
+    std::string jsonString = fieldDataToMetadata(fieldData, m_vatesConfigurations->getMetadataIdJson());
+    m_metadataJsonManager->readInSerializedJson(jsonString);
+
+    m_minValue = m_metadataJsonManager->getMinValue();
+    m_maxValue = m_metadataJsonManager->getMaxValue();
+    m_instrument = m_metadataJsonManager->getInstrument();
+    m_coordinateSystem = m_metadataJsonManager->getSpecialCoordinates();
+  }
+  catch (...)
+  {
+  }
+
+  return 1;
+}
+
+void vtkPeaksFilter::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+/**
+ * Set the peaks workspace name
+ * @param peaksWorkspaceName The peaks workspace name.
+*/
+void vtkPeaksFilter::SetPeaksWorkspace(std::string peaksWorkspaceName)
+{
+  m_peaksWorkspaceNames = peaksWorkspaceName;
+  this->Modified();
+}
+
+/**
+ * Set the radius for PeakShape == NoShape.
+ * @param radius The radius
+ */
+void vtkPeaksFilter::SetRadiusNoShape(double radius)
+{
+  m_radiusNoShape = radius;
+  this->Modified();
+}
+
+/**
+ * Set the radius type.
+ * @param type The type of the radius
+ */
+void vtkPeaksFilter::SetRadiusType(int type)
+{
+  m_radiusType = type;
+  this->Modified();
+}
+
+/** 
+ * Updates the progress bar.
+ * @param progress Progress indicator.
+ * @param message Progress message.
+ */
+void vtkPeaksFilter::updateAlgorithmProgress(double progress, const std::string& message)
+{
+  this->SetProgressText(message.c_str());
+  this->UpdateProgress(progress);
+}
+
+/**
+ * Extract the names of the peaks workspaces.
+ * @returns A list of peaks workspace names.
+ */
+std::vector<std::string> vtkPeaksFilter::extractPeakWorkspaceNames()
+{
+  // Split the string in to bits 
+  size_t pos = 0;
+  std::string peakNames = m_peaksWorkspaceNames;
+  std::vector<std::string> peaksWorkspaceNamesList;
+  std::string token;
+  while ((pos = peakNames.find(m_delimiter)) != std::string::npos) {
+      token = peakNames.substr(0, pos);
+      peaksWorkspaceNamesList.push_back(token);
+      peakNames.erase(0, pos + m_delimiter.length());
+  }
+
+  // If there was only one element in there then push it
+  peaksWorkspaceNamesList.push_back(peakNames);
+
+  return peaksWorkspaceNamesList;
+}
+
+/**
+ * Set the delimiter for concatenated workspace names.
+ * @param delimiter The workspace name delimiter
+ */
+void vtkPeaksFilter::SetDelimiter(std::string delimiter){
+  m_delimiter = delimiter;
+  this->Modified();
+}
+
+/**
+  * Get a list of peaks workspace pointers
+  * @returns A list of peaks workspace pointers.
+  */
+std::vector<Mantid::API::IPeaksWorkspace_sptr> vtkPeaksFilter::getPeaksWorkspaces(std::vector<std::string> peaksWorkspaceNames)
+{
+  std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces;
+
+  for (std::vector<std::string>::iterator it = peaksWorkspaceNames.begin(); it != peaksWorkspaceNames.end(); ++it)
+  {
+    // Check if the peaks workspace exists
+    if (!Mantid::API::AnalysisDataService::Instance().doesExist(*it))
+    {
+      continue;
+    }
+    peaksWorkspaces.push_back(Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IPeaksWorkspace>(*it));
+  }
+
+  return peaksWorkspaces;
+}
+
+/**
+ * Gets the minimum value of the data associated with the 
+ * workspace.
+ * @returns The minimum value of the workspace data.
+ */
+double vtkPeaksFilter::GetMinValue()
+{
+  return m_minValue;
+}
+
+/**
+ * Gets the maximum value of the data associated with the 
+ * workspace.
+ * @returns The maximum value of the workspace data.
+ */
+double vtkPeaksFilter::GetMaxValue(){
+
+   return m_maxValue;
+}
+
+/**
+ * Getst the insturment name
+ * @returns The name of the instrument.
+ */
+const char* vtkPeaksFilter::GetInstrument() {
+  return m_instrument.c_str();
+}
+
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h
new file mode 100644
index 0000000000000000000000000000000000000000..272795e238061dca43cbf1c8fe56192df84a3401
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/PeaksFilter/vtkPeaksFilter.h
@@ -0,0 +1,45 @@
+#ifndef _VTKPEAKSFILTER_h
+#define _VTKPEAKSFILTER_h
+#include "vtkUnstructuredGridAlgorithm.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
+#include <boost/scoped_ptr.hpp>
+#include <string>
+// cppcheck-suppress class_X_Y
+class VTK_EXPORT vtkPeaksFilter : public vtkUnstructuredGridAlgorithm
+{
+public:
+  static vtkPeaksFilter *New();
+  vtkTypeMacro(vtkPeaksFilter, vtkUnstructuredGridAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+  void SetPeaksWorkspace(std::string peaksWorkspaceName);
+  void SetRadiusNoShape(double radius);
+  void SetRadiusType(int type);
+  void SetDelimiter(std::string delimiter);
+  void updateAlgorithmProgress(double progress, const std::string& message);
+  double GetMinValue();
+  double GetMaxValue();
+  const char* GetInstrument();
+protected:
+  vtkPeaksFilter();
+  ~vtkPeaksFilter();
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+private:
+  vtkPeaksFilter(const vtkPeaksFilter&);
+  void operator = (const vtkPeaksFilter&);
+  std::vector<std::string> extractPeakWorkspaceNames();
+  std::vector<Mantid::API::IPeaksWorkspace_sptr> getPeaksWorkspaces(std::vector<std::string> peaksWorkspaceNames);
+  std::string m_peaksWorkspaceNames;
+  std::string m_delimiter;
+  double m_radiusNoShape;
+  int m_radiusType;
+  double m_minValue;
+  double m_maxValue;
+  std::string m_instrument;
+  boost::scoped_ptr<Mantid::VATES::MetadataJsonManager> m_metadataJsonManager;
+  boost::scoped_ptr<Mantid::VATES::VatesConfigurations> m_vatesConfigurations;
+  int m_coordinateSystem;
+};
+#endif
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml
index 5b1454980a2078c7370b4a331e003a2cce3b3a32..380139ad7805a395a349457586995a4469fa1b5d 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/ScaleWorkspace.xml
@@ -19,6 +19,9 @@
     <DoubleVectorProperty name="MinValue"	command="GetMinValue" information_only="1"/>
     <DoubleVectorProperty name="MaxValue" command="GetMaxValue" information_only="1"/>
     <StringVectorProperty name="Instrument" command="GetInstrument" number_of_elements="1" information_only="1"/>
+    <IntVectorProperty name="SpecialCoordinates" command="GetSpecialCoordinates" number_of_elements="1" information_only="1" default_values="0">
+		<SimpleIntInformationHelper />
+    </IntVectorProperty>
     </SourceProxy>
   </ProxyGroup>
   <!-- End ScaleWorkspace -->
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx
index 77c9dcb81e1b0141760d00a38c47fce3da865761..a9eef434d14e69bd0b5fcc06b8478c280001e375 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.cxx
@@ -19,6 +19,7 @@ vtkScaleWorkspace::vtkScaleWorkspace() :
   m_xScaling(1),
   m_yScaling(1),
   m_zScaling(1),
+  m_specialCoordinates(-1),
   m_metadataJsonManager(new MetadataJsonManager()),
   m_vatesConfigurations(new VatesConfigurations())
 {
@@ -62,6 +63,7 @@ int vtkScaleWorkspace::RequestInformation(vtkInformation*, vtkInformationVector*
   m_minValue = m_metadataJsonManager->getMinValue();
   m_maxValue = m_metadataJsonManager->getMaxValue();
   m_instrument = m_metadataJsonManager->getInstrument();
+  m_specialCoordinates = m_metadataJsonManager->getSpecialCoordinates();
 
   return 1;
 }
@@ -137,4 +139,9 @@ double vtkScaleWorkspace::GetMaxValue()
 const char* vtkScaleWorkspace::GetInstrument()
 {
   return m_instrument.c_str();
+}
+
+int vtkScaleWorkspace::GetSpecialCoordinates()
+{
+  return m_specialCoordinates;
 }
\ No newline at end of file
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h
index a48719311248e57b2880171d8c7b3198a8b5871b..1a0065a478f40816f1f19d9b90cc409470d57eff 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/ScaleWorkspace/vtkScaleWorkspace.h
@@ -18,7 +18,7 @@ public:
   double GetMinValue();
   double GetMaxValue();
   const char* GetInstrument();
-
+  int GetSpecialCoordinates();
 protected:
   vtkScaleWorkspace();
   ~vtkScaleWorkspace();
@@ -35,6 +35,7 @@ private:
   double m_minValue;
   double m_maxValue;
   std::string m_instrument;
+  int m_specialCoordinates;
 
   boost::scoped_ptr<Mantid::VATES::MetadataJsonManager> m_metadataJsonManager;
   boost::scoped_ptr<Mantid::VATES::VatesConfigurations> m_vatesConfigurations;
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
index 8556d6c34de26491b16c17c9371f587d79a5ef60..b2266585c5321043191545e8756e02c042dd8248 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewFilters/SplatterPlot/vtkSplatterPlot.cxx
@@ -5,6 +5,7 @@
 #include "vtkStreamingDemandDrivenPipeline.h"
 #include "vtkUnstructuredGridAlgorithm.h"
 #include "vtkUnstructuredGrid.h"
+#include "vtkFieldData.h"
 
 #include "MantidGeometry/MDGeometry/MDGeometryXMLDefinitions.h"
 #include "MantidVatesAPI/ADSWorkspaceProvider.h"
@@ -93,8 +94,7 @@ int vtkSplatterPlot::RequestData(vtkInformation *,
   {
     // Get the info objects
     vtkInformation *outInfo = outputVector->GetInformationObject(0);
-    vtkDataSet *output = vtkDataSet::SafeDownCast(
-          outInfo->Get(vtkDataObject::DATA_OBJECT()));
+    vtkDataSet *output = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
 
     if (outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
     {
@@ -110,7 +110,10 @@ int vtkSplatterPlot::RequestData(vtkInformation *,
     FilterUpdateProgressAction<vtkSplatterPlot> drawUpdateProgress(this,
                                                                    "Drawing...");
     vtkDataSet* product = m_presenter->create(drawUpdateProgress);
-    product->SetFieldData(input->GetFieldData());
+
+    // Extract the relevant metadata from the underlying source
+    m_presenter->setMetadata(input->GetFieldData(), product);
+
     output->ShallowCopy(product);
 
     try
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt
index 17b30441e7f1231d79bdae83d1e858df519d91ed..9ccd9b2440cdc5b752de34bccc2eccde1283707f 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/CMakeLists.txt
@@ -1,3 +1,4 @@
 add_subdirectory( MDEWSource )
 add_subdirectory( MDHWSource )
 add_subdirectory( PeaksSource )
+add_subdirectory( SinglePeakMarkerSource )
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
index 198d57ad75e1f946784fdf5db1bd8301cca2c17d..6709e928e1f7d89a664fcd38c5d23855e48532d3 100644
--- a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/PeaksSource/vtkPeaksSource.cxx
@@ -84,48 +84,7 @@ int vtkPeaksSource::RequestData(vtkInformation *, vtkInformationVector **,
                                                                    m_dimToShow);
 
     p_peakFactory->initialize(m_PeakWS);
-    vtkDataSet *structuredMesh = p_peakFactory->create(drawingProgressUpdate);
-
-    // Pick the radius up from the factory if possible, otherwise use the user-provided value.
-    vtkPolyDataAlgorithm* shapeMarker = NULL;
-    if(p_peakFactory->isPeaksWorkspaceIntegrated())
-    {
-      double peakRadius = p_peakFactory->getIntegrationRadius(); 
-      const int resolution = 6;
-      vtkSphereSource *sphere = vtkSphereSource::New();
-      sphere->SetRadius(peakRadius);
-      sphere->SetPhiResolution(resolution);
-      sphere->SetThetaResolution(resolution);
-      shapeMarker = sphere;
-    }
-    else
-    {
-      vtkAxes* axis = vtkAxes::New();
-      axis->SymmetricOn();
-      axis->SetScaleFactor(m_uintPeakMarkerSize);
-
-      vtkTransform* transform = vtkTransform::New();
-      const double rotationDegrees = 45;
-      transform->RotateX(rotationDegrees);
-      transform->RotateY(rotationDegrees);
-      transform->RotateZ(rotationDegrees);
-
-      vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
-      transformFilter->SetTransform(transform);
-      transformFilter->SetInputConnection(axis->GetOutputPort());
-      transformFilter->Update();
-      shapeMarker = transformFilter;
-    }
-
-    vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New();
-    glyphFilter->SetInputData(structuredMesh);
-    glyphFilter->SetSourceConnection(shapeMarker->GetOutputPort());
-    glyphFilter->Update();
-    vtkPolyData *glyphed = glyphFilter->GetOutput();
-
-    output->ShallowCopy(glyphed);
-
-    glyphFilter->Delete();
+    output->ShallowCopy(p_peakFactory->create(drawingProgressUpdate));
   }
   return 1;
 }
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f846a0c12d52d10efc6aa9a44a96867c1d0b0551
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/CMakeLists.txt
@@ -0,0 +1,16 @@
+PROJECT(MantidParaViewSinglePeakMarkerSource)
+
+ADD_PARAVIEW_PLUGIN(MantidParaViewSinglePeakMarkerSourceSMPlugin "1.0"
+	SERVER_MANAGER_XML SinglePeakMarkerSource.xml
+	SERVER_MANAGER_SOURCES vtkSinglePeakMarkerSource.cxx)
+
+# Add to the 'VatesParaViewPlugins' group in VS
+set_property( TARGET MantidParaViewSinglePeakMarkerSourceSMPlugin  PROPERTY FOLDER "MantidVatesParaViewPlugins" )
+
+target_link_libraries( MantidParaViewSinglePeakMarkerSourceSMPlugin  
+${MANTID_SUBPROJECT_LIBS} )
+
+# Put library into subfolder.
+SET_TARGET_OUTPUT_DIRECTORY(MantidParaViewSinglePeakMarkerSourceSMPlugin  ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR})
+
+install( TARGETS MantidParaViewSinglePeakMarkerSourceSMPlugin  ${SYSTEM_PACKAGE_TARGET} DESTINATION ${PVPLUGINS_DIR}/${PVPLUGINS_SUBDIR} )
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e2651bbedbedc2c09ae7472efd9340b3006afe8a
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/SinglePeakMarkerSource.xml
@@ -0,0 +1,12 @@
+<ServerManagerConfiguration>
+  <!-- Begin SinglePeakMarkerSource -->
+  <ProxyGroup name="sources">
+    <SourceProxy name="SinglePeakMarkerSource" class="vtkSinglePeakMarkerSource">
+      <DoubleVectorProperty name="Position1" command="SetPosition1" number_of_elements="1" default_values="0"/>
+      <DoubleVectorProperty name="Position2" command="SetPosition2" number_of_elements="1" default_values="0"/>
+      <DoubleVectorProperty name="Position3" command="SetPosition3" number_of_elements="1" default_values="0"/>
+      <DoubleVectorProperty name="RadiusMarker" command="SetRadiusMarker" number_of_elements="1" default_values="1"/>
+    </SourceProxy>
+  </ProxyGroup>
+  <!-- End SinglePeakMarkerSource -->
+</ServerManagerConfiguration>
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e8da4f13ecdcf8869f319cf583371ae80f0a18db
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.cxx
@@ -0,0 +1,71 @@
+#include "vtkSinglePeakMarkerSource.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkObjectFactory.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+
+#include "MantidVatesAPI/vtkSinglePeakMarker.h"
+
+vtkStandardNewMacro(vtkSinglePeakMarkerSource);
+
+using namespace Mantid::VATES;
+
+/// Constructor
+vtkSinglePeakMarkerSource::vtkSinglePeakMarkerSource() : m_position1(0.0), m_position2(0.0), m_position3(0.0), m_radius(0.1)
+{
+  this->SetNumberOfInputPorts(0);
+  this->SetNumberOfOutputPorts(1);
+}
+
+/// Destructor
+vtkSinglePeakMarkerSource::~vtkSinglePeakMarkerSource()
+{
+}
+
+int vtkSinglePeakMarkerSource::RequestData(vtkInformation *, vtkInformationVector **,
+                                vtkInformationVector *outputVector)
+{
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+  vtkPolyData *output = vtkPolyData::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  vtkSinglePeakMarker singlePeak;
+  output->ShallowCopy(singlePeak.createSinglePeakMarker(m_position1, m_position2, m_position3, m_radius));
+
+  return 1;
+}
+
+int vtkSinglePeakMarkerSource::RequestInformation(vtkInformation *vtkNotUsed(request),
+                                                  vtkInformationVector **vtkNotUsed(inputVector),
+                                                  vtkInformationVector *vtkNotUsed(outputVector))
+{
+  return 1;
+}
+
+void vtkSinglePeakMarkerSource::PrintSelf(ostream& os, vtkIndent indent)
+{
+  this->Superclass::PrintSelf(os, indent);
+}
+
+void vtkSinglePeakMarkerSource::SetRadiusMarker(double radius)
+{
+  m_radius = (radius*0.05);
+  this->Modified();
+}
+
+void vtkSinglePeakMarkerSource::SetPosition1(double position1)
+{
+  m_position1 = position1;
+  this->Modified();
+}
+
+void vtkSinglePeakMarkerSource::SetPosition2(double position2)
+{
+  m_position2 = position2;
+  this->Modified();
+}
+
+void vtkSinglePeakMarkerSource::SetPosition3(double position3)
+{
+  m_position3 = position3;
+  this->Modified();
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h
new file mode 100644
index 0000000000000000000000000000000000000000..dccef350679450a1368911c25cc0b0ed97c20dbe
--- /dev/null
+++ b/Code/Mantid/Vates/ParaviewPlugins/ParaViewSources/SinglePeakMarkerSource/vtkSinglePeakMarkerSource.h
@@ -0,0 +1,59 @@
+#ifndef _vtkSinglePeakMarkerSource_h
+#define _vtkSinglePeakMarkerSource_h
+#include "vtkPolyDataAlgorithm.h"
+
+/**
+    This source is used to mark a single peak.
+
+    @date 23/02/2015
+
+    Copyright &copy; 2007-11 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>
+
+*/
+
+// cppcheck-suppress class_X_Y
+class VTK_EXPORT vtkSinglePeakMarkerSource : public vtkPolyDataAlgorithm
+{
+public:
+  static vtkSinglePeakMarkerSource*New();
+  vtkTypeMacro(vtkSinglePeakMarkerSource,vtkPolyDataAlgorithm);
+  void PrintSelf(ostream& os, vtkIndent indent);
+  void SetRadiusMarker(double radius);
+  void SetPosition1(double position1);
+  void SetPosition2(double position2);
+  void SetPosition3(double position3);
+protected:
+  vtkSinglePeakMarkerSource();
+  ~vtkSinglePeakMarkerSource();
+  int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
+
+private:
+  /// Position information
+  double m_position1;
+  double m_position2;
+  double m_position3;
+  double m_radius;
+
+  vtkSinglePeakMarkerSource(const vtkSinglePeakMarkerSource&);
+  void operator = (const vtkSinglePeakMarkerSource&);
+};
+#endif
diff --git a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt
index 15c608a0266fda2746d0806d0115cb989c9d077d..927bc9468ec3127a1602d702c044bfccffe90267 100644
--- a/Code/Mantid/Vates/VatesAPI/CMakeLists.txt
+++ b/Code/Mantid/Vates/VatesAPI/CMakeLists.txt
@@ -6,6 +6,8 @@ project( VatesAPI )
 set( SRC_FILES 
 src/ADSWorkspaceProvider.cpp
 src/Common.cpp
+src/CompositePeaksPresenterVsi.cpp
+src/ConcretePeaksPresenterVsi.cpp
 src/DimensionPresenter.cpp
 src/EventNexusLoadingPresenter.cpp
 src/FieldDataToMetadata.cpp
@@ -13,13 +15,14 @@ src/IgnoreZerosThresholdRange.cpp
 src/IMDDimensionComparitor.cpp
 src/LoadVTK.cpp
 src/MDEWEventNexusLoadingPresenter.cpp
-src/MDEWInMemoryLoadingPresenter.cpp
 src/MDEWLoadingPresenter.cpp
+src/MDEWInMemoryLoadingPresenter.cpp
 src/MDHWInMemoryLoadingPresenter.cpp
 src/MDHWLoadingPresenter.cpp
 src/MDHWNexusLoadingPresenter.cpp
 src/MedianAndBelowThresholdRange.cpp
 src/MetadataToFieldData.cpp
+src/MetadataToFieldData.cpp
 src/MetaDataExtractorUtils.cpp
 src/MetadataJsonManager.cpp
 src/NoThresholdRange.cpp
@@ -30,14 +33,17 @@ src/TimeToTimeStep.cpp
 src/UserDefinedThresholdRange.cpp
 src/VatesXMLDefinitions.cpp
 src/VatesConfigurations.cpp
+src/ViewFrustum.cpp
 src/VatesKnowledgeSerializer.cpp
 src/vtkDataSetFactory.cpp
 src/vtkDataSetToGeometry.cpp
 src/vtkDataSetToImplicitFunction.cpp
 src/vtkDataSetToNonOrthogonalDataSet.cpp
+src/vtkDataSetToPeaksFilteredDataSet.cpp
 src/vtkDataSetToScaledDataSet.cpp
 src/vtkDataSetToWsName.cpp
 src/vtkDataSetToWsLocation.cpp
+src/vtkEllipsoidTransformer.cpp
 src/vtkMDLineFactory.cpp
 src/vtkMDQuadFactory.cpp
 src/vtkNullUnstructuredGrid.cpp
@@ -48,12 +54,15 @@ src/vtkMDHistoHexFactory.cpp
 src/vtkMDHistoLineFactory.cpp
 src/vtkMDHistoQuadFactory.cpp
 src/vtkMDHistoHex4DFactory.cpp
+src/vtkSinglePeakMarker.cpp
 src/SQWLoadingPresenter.cpp
 )
 
 set( INC_FILES 
 inc/MantidVatesAPI/ADSWorkspaceProvider.h
 inc/MantidVatesAPI/Common.h
+inc/MantidVatesAPI/CompositePeaksPresenterVsi.h
+inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h
 inc/MantidVatesAPI/DimensionPresenter.h
 inc/MantidVatesAPI/DimensionView.h
 inc/MantidVatesAPI/DimensionViewFactory.h
@@ -79,6 +88,8 @@ 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/ProgressAction.h
 inc/MantidVatesAPI/SQWLoadingPresenter.h
 inc/MantidVatesAPI/SynchronisingGeometryPresenter.h
@@ -89,13 +100,16 @@ inc/MantidVatesAPI/UserDefinedThresholdRange.h
 inc/MantidVatesAPI/VatesXMLDefinitions.h
 inc/MantidVatesAPI/VatesConfigurations.h
 inc/MantidVatesAPI/VatesKnowledgeSerializer.h
+inc/MantidVatesAPI/ViewFrustum.h
 inc/MantidVatesAPI/vtkDataSetFactory.h
 inc/MantidVatesAPI/vtkDataSetToGeometry.h
 inc/MantidVatesAPI/vtkDataSetToImplicitFunction.h
 inc/MantidVatesAPI/vtkDataSetToNonOrthogonalDataSet.h
+inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h
 inc/MantidVatesAPI/vtkDataSetToScaledDataSet.h
 inc/MantidVatesAPI/vtkDataSetToWsName.h
 inc/MantidVatesAPI/vtkDataSetToWsLocation.h
+inc/MantidVatesAPI/vtkEllipsoidTransformer.h
 inc/MantidVatesAPI/vtkMDLineFactory.h
 inc/MantidVatesAPI/vtkMDQuadFactory.h
 inc/MantidVatesAPI/vtkMDHexFactory.h
@@ -106,6 +120,7 @@ inc/MantidVatesAPI/vtkMDHistoHexFactory.h
 inc/MantidVatesAPI/vtkMDHistoLineFactory.h
 inc/MantidVatesAPI/vtkMDHistoQuadFactory.h
 inc/MantidVatesAPI/vtkMDHistoHex4DFactory.h
+inc/MantidVatesAPI/vtkSinglePeakMarker.h
 inc/MantidVatesAPI/WorkspaceProvider.h
 )
 
@@ -149,9 +164,15 @@ test/MedianAndBelowThresholdRangeTest.h
 test/NoThresholdRangeTest.h
 test/IgnoreZerosThresholdRangeTest.h
 test/VatesKnowledgeSerializerTest.h
+test/ViewFrustumTest.h
 test/vtkDataSetToScaledDataSetTest.h
+test/vtkDataSetToPeaksFilteredDataSetTest.h
 test/vtkDataSetToNonOrthogonalDataSetTest.h
 test/vtkNullUnstructuredGridTest.h
+test/vtkEllipsoidTransformerTest.h
+test/NullPeaksPresenterVsiTest.h
+test/ConcretePeaksPresenterVsiTest.h
+test/CompositePeaksPresenterVsiTest.h
 )
 
 include_directories( inc )
@@ -180,6 +201,9 @@ ${MANTID_SUBPROJECT_LIBS}
 vtkCommonCore
 vtkCommonDataModel
 vtkIOLegacy
+vtkFiltersExtraction
+vtkFiltersSources
+vtkPVVTKExtensionsDefault
 ${QWT_LIBRARIES}
 )
 
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..19066a024046b27b7f2ed73499d26a41172468e7
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/CompositePeaksPresenterVsi.h
@@ -0,0 +1,41 @@
+#ifndef MANTID_VATES_COMPOSITE_PEAKS_PRESENTER_VSI_H
+#define MANTID_VATES_COMPOSITE_PEAKS_PRESENTER_VSI_H
+
+#include "MantidKernel/System.h"
+#include "MantidVatesAPI/PeaksPresenterVsi.h"
+#include "MantidAPI/PeakTransform.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include <vector>
+#include <string>
+
+namespace Mantid
+{
+namespace VATES
+{
+class DLLExport CompositePeaksPresenterVsi : public PeaksPresenterVsi
+{
+public:
+  CompositePeaksPresenterVsi();
+  ~CompositePeaksPresenterVsi();
+  virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace(){throw std::runtime_error("The composite peaks presenter has no single peaks workspace.");}
+  std::vector<Mantid::API::IPeaksWorkspace_sptr> getPeaksWorkspaces();
+  virtual std::vector<bool> getViewablePeaks();
+  virtual void updateViewFrustum(ViewFrustum frustum);
+  virtual std::string getFrame();
+  virtual std::string getPeaksWorkspaceName(){throw std::runtime_error("The composite peaks presenter has no peaks workspace");} 
+  std::vector<std::string> getPeaksWorkspaceNames();
+  virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius);
+  void addPresenter(PeaksPresenterVsi_sptr presenter);
+  std::map<std::string, std::vector<bool>> getInitializedViewablePeaks();
+  void removePresenter(std::string peaksWorkspaceName);
+  void updateWorkspaces(std::vector<std::string> peaksWorkspaceNames);
+  bool hasPeaks();
+private:
+  /// The list of presenters
+  std::vector<PeaksPresenterVsi_sptr> m_peaksPresenters;
+};
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..773eb04ac4fd0831b2b8ad74710b6440478ef6b7
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ConcretePeaksPresenterVsi.h
@@ -0,0 +1,42 @@
+#ifndef MANTID_VATES_CONCRETE_PEAKS_PRESENTER_VSI_H
+#define MANTID_VATES_CONCRETE_PEAKS_PRESENTER_VSI_H
+
+#include "MantidKernel/System.h"
+#include "MantidVatesAPI/PeaksPresenterVsi.h"
+#include "MantidAPI/PeakTransform.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include <vector>
+
+
+namespace Mantid
+{
+namespace VATES
+{
+class DLLExport ConcretePeaksPresenterVsi : public PeaksPresenterVsi
+{
+  public:
+    ConcretePeaksPresenterVsi(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, ViewFrustum frustum, std::string wsFrame);
+    ~ConcretePeaksPresenterVsi();
+    virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace();
+    virtual std::vector<bool> getViewablePeaks();
+    virtual void updateViewFrustum(ViewFrustum frustum);
+    virtual std::string getFrame();
+    virtual std::string getPeaksWorkspaceName();
+    virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius);
+  private:
+    /// Get the max radius.
+    double getMaxRadius(Mantid::Geometry::PeakShape_sptr shape);
+    /// Viewable Peaks
+    std::vector<bool> m_viewablePeaks;
+    /// The viewable region
+    ViewFrustum m_viewableRegion;
+    /// The peaks workspace
+    Mantid::API::IPeaksWorkspace_sptr m_peaksWorkspace;
+    /// The frame
+    std::string m_frame;
+};
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h
index f29bc938eb9cee5da80d909b40f12e52d06000f7..7c24ceb80423476dabd3ff79f60557efd4f3150f 100644
--- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/MetadataJsonManager.h
@@ -1,7 +1,7 @@
 #ifndef METADATA_JSON_MANAGER_H
 #define METADATA_JSON_MANAGER_H
 
-#include <jsoncpp/json/json.h>
+#include <json/json.h>
 #include "MantidKernel/System.h"
 #include <string>
 namespace Mantid
@@ -54,12 +54,16 @@ namespace Mantid
       void setMaxValue(double maxValue);
       double getMaxValue();
 
+      void setSpecialCoordinates(int specialCoordinates);
+      int getSpecialCoordinates();
+
     private:
       Json::Value metadataContainer;
 
       std::string instrument;
       double minValue;
       double maxValue;
+      int specialCoordinates;
   };
   }
 }
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..72b0f84fd46509f2dd00cee1ad7a0b035a826500
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/NullPeaksPresenterVsi.h
@@ -0,0 +1,30 @@
+#ifndef MANTID_VATES_NULL_PEAKS_PRESENTER
+#define MANTID_VATES_NULL_PEAKS_PRESENTER
+
+#include "MantidKernel/System.h"
+#include "MantidVatesAPI/PeaksPresenterVsi.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include <vector>
+
+namespace Mantid
+{
+namespace VATES
+{
+  class DLLExport NullPeaksPresenterVsi : public PeaksPresenterVsi
+  {
+    public:
+    NullPeaksPresenterVsi(){}
+    virtual ~NullPeaksPresenterVsi(){}
+    virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");}
+    virtual std::vector<bool> getViewablePeaks() {throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");}
+    virtual void updateViewFrustum(ViewFrustum ) {}
+    virtual std::string getFrame(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");}
+    virtual std::string getPeaksWorkspaceName(){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");}
+    virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr , int ,
+                              Mantid::Kernel::V3D& , double& ){throw std::runtime_error("NullPeaksPresenterVsi does not implement this method. Misused");}
+  };
+}
+}
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e4e7e92ff9b4380c3a8e816e9b277e5ec971cd9
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/PeaksPresenterVsi.h
@@ -0,0 +1,34 @@
+#ifndef MANTID_VATES_PEAKS_PRESENTER_VSI_H
+#define MANTID_VATES_PEAKS_PRESENTER_VSI_H
+
+#include "MantidKernel/System.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidKernel/V3D.h"
+#include <vector>
+#include <string>
+
+
+namespace Mantid
+{
+namespace VATES
+{
+class ViewFrustum;
+
+class DLLExport PeaksPresenterVsi
+{
+  public:
+    virtual ~PeaksPresenterVsi(){};
+    virtual std::vector<bool> getViewablePeaks() = 0;
+    virtual Mantid::API::IPeaksWorkspace_sptr getPeaksWorkspace() = 0;
+    virtual void updateViewFrustum(ViewFrustum frustum) = 0;
+    virtual std::string getFrame() = 0;
+    virtual std::string getPeaksWorkspaceName() = 0;
+    virtual void getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row,
+                              Mantid::Kernel::V3D& position, double& radius) = 0;
+};
+
+typedef boost::shared_ptr<PeaksPresenterVsi> PeaksPresenterVsi_sptr;
+typedef boost::shared_ptr<const PeaksPresenterVsi> PeaksPresenterVsi_const_sptr;
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h
new file mode 100644
index 0000000000000000000000000000000000000000..d6e6847ff2beca6d86f5c505fa32c976d8fcad8a
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/ViewFrustum.h
@@ -0,0 +1,175 @@
+#ifndef MANTID_PARAVIEW_VIEWFRUSTUM
+#define MANTID_PARAVIEW_VIEWFRUSTUM
+
+#include "MantidKernel/System.h"
+#include "MantidKernel/Matrix.h"
+#include <stdexcept>
+#include <cmath>
+#include <cfloat>
+#include <vector>
+
+namespace Mantid
+{
+namespace VATES
+{
+
+enum PLANELOCATION{LEFTPLANE, RIGHTPLANE, BOTTOMPLANE, TOPPLANE, FARPLANE, NEARPLANE};
+
+template<PLANELOCATION I, typename T>
+class DLLExport FrustumPlane
+{
+  public:
+    explicit FrustumPlane(const T& paramA, const T& paramB, const T& paramC, const T& paramD) : m_paramA(paramA), 
+                                                                                                m_paramB(paramB),
+                                                                                                m_paramC(paramC), 
+                                                                                                m_paramD(paramD){}
+    FrustumPlane(const FrustumPlane<I, T>& other) : m_paramA(other.m_paramA), 
+                                                    m_paramB(other.m_paramB),
+                                                    m_paramC(other.m_paramC), 
+                                                    m_paramD(other.m_paramD){}
+    T A() {return m_paramA;}
+    T B() {return m_paramB;}
+    T C() {return m_paramC;}
+    T D() {return m_paramD;}
+
+    std::vector<T> getPlaneCoefficients()
+    {
+      std::vector<T> coefficients;
+      coefficients.push_back(m_paramA);
+      coefficients.push_back(m_paramB);
+      coefficients.push_back(m_paramC);
+      coefficients.push_back(m_paramD);
+
+      return coefficients;
+    }
+
+private:
+    T m_paramA;
+    T m_paramB;
+    T m_paramC;
+    T m_paramD;
+    enum{m_location = I};
+};
+
+typedef FrustumPlane<LEFTPLANE, double> LeftPlane;
+typedef FrustumPlane<RIGHTPLANE, double> RightPlane;
+typedef FrustumPlane<BOTTOMPLANE, double> BottomPlane;
+typedef FrustumPlane<TOPPLANE, double> TopPlane;
+typedef FrustumPlane<FARPLANE, double> FarPlane;
+typedef FrustumPlane<NEARPLANE, double> NearPlane;
+
+
+class DLLExport ViewFrustum
+{
+  public:
+    ViewFrustum(const LeftPlane leftPlane,
+                const RightPlane rightPlane,
+                const BottomPlane bottomPlane,
+                const TopPlane topPlane,
+                const FarPlane farPlane, 
+                const NearPlane nearPlane);
+    ViewFrustum(const ViewFrustum& other);
+    ~ViewFrustum();
+    ViewFrustum& operator=(const ViewFrustum& other);
+    std::vector<std::pair<double, double>> toExtents() const;
+    std::string toExtentsAsString() const;
+
+  private:
+    mutable LeftPlane m_leftPlane;
+    mutable RightPlane m_rightPlane;
+    mutable TopPlane m_topPlane;
+    mutable BottomPlane m_bottomPlane;
+    mutable FarPlane m_farPlane;
+    mutable NearPlane m_nearPlane;
+
+    template<PLANELOCATION p1, PLANELOCATION p2, PLANELOCATION p3, typename T>
+    std::vector<T> getIntersectionPointThreePlanes(FrustumPlane<p1, T> plane1, FrustumPlane<p2, T> plane2, FrustumPlane<p3, T> plane3) const;
+
+    template<typename T>
+    void initializeMatrix(Mantid::Kernel::Matrix<T>& matrix, std::vector<T> vec0, std::vector<T> vec1, std::vector<T> vec2) const;
+};
+  /**
+   * Get the intersection point of three planes using Cramer's rule.
+   * @param plane1 The first frustum plane
+   * @param plane2 The second frustum plane
+   * @param plane3 The third frustum plane
+   */
+  template<PLANELOCATION p1, PLANELOCATION p2, PLANELOCATION p3, typename T>
+  std::vector<T> ViewFrustum::getIntersectionPointThreePlanes(FrustumPlane<p1, T> plane1, FrustumPlane<p2, T> plane2, FrustumPlane<p3, T> plane3) const
+  {
+    const size_t dim = 3;
+
+    std::vector<T> aVec;
+    aVec.push_back(plane1.A());
+    aVec.push_back(plane2.A());
+    aVec.push_back(plane3.A());
+
+    std::vector<T> bVec;
+    bVec.push_back(plane1.B());
+    bVec.push_back(plane2.B());
+    bVec.push_back(plane3.B());
+
+    std::vector<T> cVec;
+    cVec.push_back(plane1.C());
+    cVec.push_back(plane2.C());
+    cVec.push_back(plane3.C());
+
+    // The input is Ax+By+Cz+D=0 but we need the form Ax+By+Cz=D
+    std::vector<T> dVec;
+    const T factor = -1;
+    dVec.push_back(factor*plane1.D());
+    dVec.push_back(factor*plane2.D());
+    dVec.push_back(factor*plane3.D());
+
+    // Get the different matrix permutations
+    Mantid::Kernel::Matrix<T> abcMatrix(dim, dim);
+    Mantid::Kernel::Matrix<T>  dbcMatrix(dim, dim);
+    Mantid::Kernel::Matrix<T>  adcMatrix(dim, dim);
+    Mantid::Kernel::Matrix<T>  abdMatrix(dim, dim);
+    
+    initializeMatrix<T>(abcMatrix, aVec, bVec, cVec);
+    T abcDet = abcMatrix.determinant();
+    if (abcDet == 0)
+    {
+      throw std::runtime_error("Determinant for view frustum is 0.");
+    }
+
+    initializeMatrix<T>(dbcMatrix, dVec, bVec, cVec);
+    initializeMatrix<T>(adcMatrix, aVec, dVec, cVec);
+    initializeMatrix<T>(abdMatrix, aVec, bVec, dVec);
+
+    T dbcDet = dbcMatrix.determinant();
+    T adcDet = adcMatrix.determinant();
+    T abdDet = abdMatrix.determinant();
+
+    std::vector<T> intersection;
+    intersection.push_back(dbcDet/abcDet);
+    intersection.push_back(adcDet/abcDet);
+    intersection.push_back(abdDet/abcDet);
+
+    return intersection;
+  }
+
+  /**
+   * Initialize the matrix with the plane coefficient vectors.
+   * @param matrix The matrix to initialze.
+   * @param vec0 The first vector.
+   * @param vec1 The second vector.
+   * @param vec2 The third vector.
+   */
+  template<typename T>
+  void ViewFrustum::initializeMatrix(Mantid::Kernel::Matrix<T>& matrix, std::vector<T> vec0, std::vector<T> vec1, std::vector<T> vec2) const
+  {
+    std::pair<size_t, size_t> size = matrix.size();
+
+    if (size.first != 3 || size.second != 3)
+    {
+      throw std::runtime_error("Matrix for view frustum calculation has the wrong dimensionality.");
+    }
+    matrix.setColumn(0, vec0);
+    matrix.setColumn(1, vec1);
+    matrix.setColumn(2, vec2);
+  }
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h
new file mode 100644
index 0000000000000000000000000000000000000000..e59d30815622ebabe9d038a630dfbeee2de27238
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h
@@ -0,0 +1,72 @@
+#ifndef MANTID_VATES_PeaksFilter_H
+#define MANTID_VATES_PeaksFilter_H
+
+#include "MantidKernel/System.h"
+#include "MantidKernel/V3D.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/ProgressAction.h"
+#include <string>
+
+class vtkUnstructuredGrid;
+
+namespace Mantid
+{
+namespace VATES
+{
+
+  /**
+    Class that selects only those data points which lie within the geometry of a peak. 
+    
+    @date 17/02/2015
+
+    Copyright &copy; 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source
+
+    This file is part of Mantid.
+
+    Mantid is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    Mantid is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+    File change history is stored at: <https://github.com/mantidproject/mantid>
+    Code Documentation is available at: <http://doxygen.mantidproject.org>
+  */
+
+  class DLLExport vtkDataSetToPeaksFilteredDataSet
+  {
+    public:
+      vtkDataSetToPeaksFilteredDataSet(vtkUnstructuredGrid *input, vtkUnstructuredGrid *output);
+      virtual ~vtkDataSetToPeaksFilteredDataSet();
+      /// Set the name of the peaks workspace
+      void initialize(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces, double radiusNoShape, int radiusType, int coordinateSystem);
+      /// Apply the peak filtering
+      void execute(ProgressAction& progressUpdating);
+      /// Get radius of no shape
+      double getRadiusNoShape();
+      /// Get radius factor
+      double getRadiusFactor();
+    private:
+      vtkDataSetToPeaksFilteredDataSet& operator=(const vtkDataSetToPeaksFilteredDataSet& other);
+      std::vector<std::pair<Mantid::Kernel::V3D, double>> getPeaksInfo(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces);
+      void addSinglePeak(Mantid::API::IPeak* peak, const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem, std::vector<std::pair<Mantid::Kernel::V3D, double>>& peaksInfo);
+      vtkUnstructuredGrid *m_inputData; ///< Data to peak filter
+      vtkUnstructuredGrid *m_outputData; ///< Peak filtered data
+      std::vector<Mantid::API::IPeaksWorkspace_sptr> m_peaksWorkspaces; ///< A list of peaks workspace names.
+      bool m_isInitialised; ///<Flag if the filter is initialized
+      double m_radiusNoShape; ///< The radius for peaks with no peak shape.
+      int m_radiusType;
+      double m_radiusFactor;///< By how much we want to trim the data set.
+      double m_defaultRadius; ///< A default radius.
+      int m_coordinateSystem;///< A coordinate system.
+  };
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h
new file mode 100644
index 0000000000000000000000000000000000000000..c049b20e4820e31c693c31a0a2283982e0b750f6
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkEllipsoidTransformer.h
@@ -0,0 +1,56 @@
+#ifndef MANTID_VATES_VTKELLIPSOIDTRANSFORMER_H_
+#define MANTID_VATES_VTKELLIPSOIDTRANSFORMER_H_
+
+#include "MantidKernel/System.h"
+#include <vtkSmartPointer.h>
+#include <vector>
+class vtkTransform;
+namespace Mantid
+{
+namespace Kernel
+{
+  class V3D;
+}
+}
+
+namespace Mantid
+{
+namespace VATES
+{
+/** 
+ * Creates a vtkTransform for ellipsoids to rotate them into the correct direction.
+ @date 122/02/2015
+
+ Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source
+
+ This file is part of Mantid.
+
+ Mantid is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Mantid is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+ File change history is stored at: <https://github.com/mantidproject/mantid>
+ Code Documentation is available at: <http://doxygen.mantidproject.org>
+ */
+
+class DLLExport vtkEllipsoidTransformer
+{
+public:
+  vtkEllipsoidTransformer();
+  ~vtkEllipsoidTransformer();
+  vtkSmartPointer<vtkTransform> generateTransform(std::vector<Mantid::Kernel::V3D> directions);
+private:
+  Mantid::Kernel::V3D rotateVector(Mantid::Kernel::V3D original, Mantid::Kernel::V3D rotationAxis, double angle);
+};
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h
index c523a6859d83afd866f0f087a33443b7555d30ae..6f7cba3bbc0917e41a132bcd0719a3b4ff546270 100644
--- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkPeakMarkerFactory.h
@@ -35,6 +35,8 @@
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
 
+class vtkPolyData;
+
 namespace Mantid
 {
 namespace VATES
@@ -70,7 +72,7 @@ public:
   virtual void initialize(Mantid::API::Workspace_sptr workspace);
 
   /// Factory method
-  vtkDataSet* create(ProgressAction& progressUpdating) const;
+  vtkPolyData* create(ProgressAction& progressUpdating) const;
 
   virtual std::string getFactoryTypeName() const
   {
@@ -88,7 +90,6 @@ protected:
   virtual void validate() const;
 
 private:
-
   void validateWsNotNull() const;
 
   void validateDimensionsPresent() const;
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h
new file mode 100644
index 0000000000000000000000000000000000000000..a51f32bb1f0d2301130713c1ade8bbe87dc35d27
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSinglePeakMarker.h
@@ -0,0 +1,47 @@
+#ifndef MANTID_VATES_SINGLEPEAKMARKER_H_
+#define MANTID_VATES_SINGLEPEAKMARKER_H_
+
+#include "MantidKernel/System.h"
+/**
+  Creates a single marker at a given position
+
+  @date 23/02/2015
+
+  Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge National Laboratory & European Spallation Source
+
+  This file is part of Mantid.
+
+  Mantid is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 3 of the License, or
+  (at your option) any later version.
+
+  Mantid is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+  File change history is stored at: <https://github.com/mantidproject/mantid>
+  Code Documentation is available at: <http://doxygen.mantidproject.org>
+ */
+
+
+class vtkPolyData;
+
+namespace Mantid
+{
+namespace VATES
+{
+  class DLLExport vtkSinglePeakMarker
+  {
+  public:
+    vtkSinglePeakMarker();
+    ~vtkSinglePeakMarker();
+    vtkPolyData* createSinglePeakMarker(double x, double y, double z, double radius);
+  };
+}
+}
+#endif
diff --git a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
index 3ad5c3ef481d8d9911204acc6c10a6b9e7759bdc..b793eae000e3e1216cfe1b8a6546d801d8a46e9b 100644
--- a/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
+++ b/Code/Mantid/Vates/VatesAPI/inc/MantidVatesAPI/vtkSplatterPlotFactory.h
@@ -9,6 +9,9 @@
 #include "MantidMDEvents/MDEventWorkspace.h"
 #include "MantidVatesAPI/ThresholdRange.h"
 #include "MantidVatesAPI/vtkDataSetFactory.h"
+#include "MantidVatesAPI/MetaDataExtractorUtils.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
 #include <vtkPoints.h>
 #include <boost/shared_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -91,6 +94,9 @@ public:
   /// Getter for the instrument
   virtual const std::string& getInstrument();
 
+  /// Set the appropriate field data
+  virtual void setMetadata(vtkFieldData* fieldData, vtkDataSet* dataSet);
+
 private:
 
   template<typename MDE, size_t nd>
@@ -108,6 +114,9 @@ private:
   /// Template Method pattern to validate the factory before use.
   virtual void validate() const;
 
+  /// Add metadata
+  void addMetadata() const;
+
   /// Threshold range strategy.
   ThresholdRange_scptr m_thresholdRange;
 
@@ -158,6 +167,12 @@ private:
 
   /// Meta data extractor
   boost::scoped_ptr<MetaDataExtractorUtils> m_metaDataExtractor;
+
+  /// Meata data json manager
+  boost::scoped_ptr<MetadataJsonManager> m_metadataJsonManager;
+
+  /// Vates configuration
+  boost::scoped_ptr<VatesConfigurations> m_vatesConfigurations;
 };
 
 }
diff --git a/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp b/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..83220f7a9d5265ae0773698e7b6c0e4536b9b731
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/CompositePeaksPresenterVsi.cpp
@@ -0,0 +1,151 @@
+#include "MantidVatesAPI/CompositePeaksPresenterVsi.h"
+#include "MantidVatesAPI/PeaksPresenterVsi.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+
+#include <vector>
+#include <map>
+namespace Mantid
+{
+namespace VATES
+{
+  /// Constructor
+  CompositePeaksPresenterVsi::CompositePeaksPresenterVsi(){}                                                                                                  
+
+  /// Destructor
+  CompositePeaksPresenterVsi::~CompositePeaksPresenterVsi(){}
+
+  /**
+   * Update the view frustum
+   * @param frustum The view frustum
+   */
+  void CompositePeaksPresenterVsi::updateViewFrustum(ViewFrustum frustum)
+  {
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      (*it)->updateViewFrustum(frustum);
+    }
+  }
+
+    /**
+   * Get the viewable peaks. Essentially copied from the slice viewer.
+   * @retruns A vector indicating which of the peaks are viewable.
+   */
+  std::vector<bool> CompositePeaksPresenterVsi::getViewablePeaks()
+  {
+    return std::vector<bool>();
+  }
+
+  /**
+   * Get the name of all peaks workspaces as a vector
+   * @returns A vector of all peaks workspace names.
+   */
+  std::vector<std::string> CompositePeaksPresenterVsi::getPeaksWorkspaceNames() {
+    std::vector<std::string> peaksWorkspaceNames;
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      peaksWorkspaceNames.push_back((*it)->getPeaksWorkspaceName());
+    }
+    return peaksWorkspaceNames;
+  }
+
+  /**
+   * Extract the peak information regarding position and radius of the peak.
+   * @param peaksWorkspace A pointer to the peaks workspace
+   * @param position A reference to extract the position.
+   * @param radius A reference to extract the radius.
+   */
+  void CompositePeaksPresenterVsi::getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius) {
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      if ((*it)->getPeaksWorkspace() == peaksWorkspace) {
+        (*it)->getPeaksInfo(peaksWorkspace, row, position, radius);
+      }
+    }
+  }
+
+  /**
+   * Get the frame in which the peak workspaces are evaluated. Note that all will have the same frame, so only the first
+   * workspace needs to be probed.
+   * @returns The coordinate frame.
+   */
+  std::string CompositePeaksPresenterVsi::getFrame() {
+    std::string frame;
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      frame = (*it)->getFrame();
+      break;
+    }
+    return frame;
+  }
+
+  /**
+   * Add a new peaks workspace presenter
+   * @param presenter Add a new presenter to the composite.
+   */
+  void CompositePeaksPresenterVsi::addPresenter(PeaksPresenterVsi_sptr presenter) {
+    m_peaksPresenters.push_back(presenter);
+  }
+
+  /**
+   * Get a vector with peak workspace pointers for which presenters exist.
+   * @returns A vector with peaks workspace pointers
+   */
+  std::vector<Mantid::API::IPeaksWorkspace_sptr> CompositePeaksPresenterVsi::getPeaksWorkspaces() {
+    std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces;
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      peaksWorkspaces.push_back((*it)->getPeaksWorkspace());
+    }
+    return peaksWorkspaces;
+  }
+
+  /**
+   * Get the initialized viewable peaks. For each presenter return a vector with true for each peak
+   * @returns A vector of bool-vectors for each peaks presenter.
+   */
+  std::map<std::string, std::vector<bool>> CompositePeaksPresenterVsi::getInitializedViewablePeaks(){
+    std::map<std::string, std::vector<bool>> viewablePeaks;
+    for (std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin(); it != m_peaksPresenters.end(); ++it) {
+      viewablePeaks.insert(std::pair<std::string, std::vector<bool>>((*it)->getPeaksWorkspace()->getName(), std::vector<bool>((*it)->getPeaksWorkspace()->getNumberPeaks(), true)));
+    }
+    return viewablePeaks;
+  }
+
+  /**
+   * Remove the presenters which are based on a certain peaks workspace.
+   * @param peaksWorkspaceName
+   */
+  void CompositePeaksPresenterVsi::removePresenter(std::string peaksWorkspaceName) {
+    std::vector<PeaksPresenterVsi_sptr>::iterator it = m_peaksPresenters.begin();
+    for (; it != m_peaksPresenters.end();) {
+      if ((*it)->getPeaksWorkspaceName() == peaksWorkspaceName) {
+        it = m_peaksPresenters.erase(it);
+      } else {
+        ++it;
+      }
+    }
+  }
+
+  /**
+   * Update the presenters by checking if a presenter is still present, which is not needed any longer.
+   * @param peaksWorkspaceNames The names of all currently active peak sources.
+   */
+  void CompositePeaksPresenterVsi::updateWorkspaces(std::vector<std::string>peaksWorkspaceNames) {
+    std::vector<std::string> storedPeaksWorkspaces = getPeaksWorkspaceNames();
+    for (std::vector<std::string>::iterator it = storedPeaksWorkspaces.begin(); it != storedPeaksWorkspaces.end(); ++it) {
+      size_t count = std::count(peaksWorkspaceNames.begin(), peaksWorkspaceNames.end(), *it);
+      if (count == 0) {
+        removePresenter(*it);
+      }
+    }
+  }
+
+  /**
+   * Check if there are any peaks availble.
+   * @returns If there are any peaks availbale.
+   */
+  bool CompositePeaksPresenterVsi::hasPeaks(){
+    if (m_peaksPresenters.size() > 0) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp b/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..65ea5a5bac646ebce5c500f2918f9ab3238a09bd
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/ConcretePeaksPresenterVsi.cpp
@@ -0,0 +1,183 @@
+#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidAPI/AlgorithmManager.h"
+#include "MantidDataObjects/NoShape.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidKernel/SpecialCoordinateSystem.h"
+#include "MantidAPI/IPeak.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+namespace Mantid
+{
+namespace VATES
+{
+  /**
+   * Constructor
+   * @param peaksWorkspace The peaks workspace.
+   * @param frustum The view frustum
+   * @param frame The coordinate frame
+   */
+  ConcretePeaksPresenterVsi::ConcretePeaksPresenterVsi(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace,
+                                                       ViewFrustum frustum,
+                                                       std::string frame) : m_viewableRegion(frustum),
+                                                                            m_peaksWorkspace(peaksWorkspace),
+                                                                            m_frame(frame)                                                                                                     
+  {
+  }
+
+  ///Destructor
+  ConcretePeaksPresenterVsi::~ConcretePeaksPresenterVsi()
+  {
+  }
+
+  /**
+   * Update the view frustum
+   * @param frustum The view frustum.
+   */
+  void ConcretePeaksPresenterVsi::updateViewFrustum(ViewFrustum frustum)
+  {
+    m_viewableRegion = frustum;
+  }
+
+  /**
+   * Get the viewable peaks. Essentially copied from the slice viewer.
+   * @retruns A vector indicating which of the peaks are viewable.
+   */
+  std::vector<bool> ConcretePeaksPresenterVsi::getViewablePeaks()
+  {
+    //Need to apply a transform.
+    // Don't bother to find peaks in the region if there are no peaks to find.
+    Mantid::API::ITableWorkspace_sptr outTable;
+
+    if (this->m_peaksWorkspace->getNumberPeaks() >= 1) 
+    {
+      double effectiveRadius = 1e-2;
+      std::string viewable = m_viewableRegion.toExtentsAsString();
+      Mantid::API::IPeaksWorkspace_sptr peaksWS =  m_peaksWorkspace;
+      
+      Mantid::API::IAlgorithm_sptr alg = Mantid::API::AlgorithmManager::Instance().create("PeaksInRegion");
+      alg->setChild(true);
+      alg->setRethrows(true);
+      alg->initialize();
+      alg->setProperty("InputWorkspace", peaksWS);
+      alg->setProperty("OutputWorkspace", peaksWS->name() + "_peaks_in_region");
+      alg->setProperty("Extents", viewable);
+      alg->setProperty("CheckPeakExtents", true);
+      alg->setProperty("PeakRadius", effectiveRadius);
+      alg->setPropertyValue("CoordinateFrame", m_frame);
+      alg->execute();
+      outTable = alg->getProperty("OutputWorkspace");
+      std::vector<bool> viewablePeaks(outTable->rowCount());
+      for (size_t i = 0; i < outTable->rowCount(); ++i) {
+        viewablePeaks[i] = outTable->cell<Mantid::API::Boolean>(i, 1);
+      }
+      m_viewablePeaks = viewablePeaks;
+    }
+    else{
+      // No peaks will be viewable
+      m_viewablePeaks = std::vector<bool>();
+    }
+    
+    return m_viewablePeaks;
+  }
+
+  /**
+   * Get the underlying peaks workspace
+   * @returns A pointer to the underlying peaks workspace.
+   */
+  Mantid::API::IPeaksWorkspace_sptr ConcretePeaksPresenterVsi::getPeaksWorkspace()
+  {
+    return m_peaksWorkspace;
+  }
+
+  /**
+   * Get the frame
+   * @returns The frame.
+   */
+  std::string ConcretePeaksPresenterVsi::getFrame()
+  {
+    return m_frame;
+  }
+
+  /**
+   * Get the name of the underlying peaks workspace.
+   * @returns The name of the peaks workspace.
+   */
+  std::string ConcretePeaksPresenterVsi::getPeaksWorkspaceName()
+  {
+    return m_peaksWorkspace->getName();
+  }
+
+  /**
+   * Get the peaks info for a single peak, defined by the row in the peaks table.
+   * @param peaksWorkspace A pointer to a peaks workspace.
+   * @param row The row in the peaks table.
+   * @param position A reference which holds the position of the peak.
+   * @param radius A reference which holds the radius of the peak.
+   */
+  void ConcretePeaksPresenterVsi::getPeaksInfo(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row, Mantid::Kernel::V3D& position, double& radius)
+  {
+    // Extract the position
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = peaksWorkspace->getSpecialCoordinateSystem();
+
+    switch(coordinateSystem)
+    {
+      case(Mantid::Kernel::SpecialCoordinateSystem::QLab):
+        position = peaksWorkspace->getPeak(row).getQLabFrame();
+        break;
+      case(Mantid::Kernel::SpecialCoordinateSystem::QSample):
+        position = peaksWorkspace->getPeak(row).getQSampleFrame();
+        break;
+      case(Mantid::Kernel::SpecialCoordinateSystem::HKL):
+        position = peaksWorkspace->getPeak(row).getHKL();
+        break;
+      default:
+        throw std::invalid_argument("The coordinate system is invalid.\n");
+    }
+
+    // Peak radius
+    Mantid::Geometry::PeakShape_sptr shape(peaksWorkspace->getPeakPtr(row)->getPeakShape().clone());
+    radius = getMaxRadius(shape);
+  }
+
+  /**
+   * Get the maximal radius
+   * @param shape The shape of a peak.
+   * @param The maximal radius of the peak.
+   */
+  double ConcretePeaksPresenterVsi::getMaxRadius(Mantid::Geometry::PeakShape_sptr shape)
+  {
+    const double defaultRadius = 1.0;
+    boost::shared_ptr<Mantid::DataObjects::NoShape> nullShape = boost::dynamic_pointer_cast<Mantid::DataObjects::NoShape>(shape);
+    boost::shared_ptr<Mantid::DataObjects::PeakShapeEllipsoid> ellipsoidShape = boost::dynamic_pointer_cast<Mantid::DataObjects::PeakShapeEllipsoid>(shape);
+    boost::shared_ptr<Mantid::DataObjects::PeakShapeSpherical> sphericalShape = boost::dynamic_pointer_cast<Mantid::DataObjects::PeakShapeSpherical>(shape);
+
+    if (nullShape)
+    {
+      return defaultRadius;
+    }
+    else if (ellipsoidShape)
+    {
+      std::vector<double> radius = ellipsoidShape->abcRadii();
+      return *(std::max_element(radius.begin(),radius.end()));
+    }
+    else if (sphericalShape)
+    {
+      if (double radius = sphericalShape->radius())
+      {
+        return radius;
+      }
+      else
+      {
+        return defaultRadius;
+      }
+    }
+    else
+    {
+      return defaultRadius;
+    }
+  }
+
+}
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp
index 97796ff8e705da963664f8e41af9e3ff8346578d..8eecf215dbb592f815e0c26326dc8588b597d220 100644
--- a/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp
+++ b/Code/Mantid/Vates/VatesAPI/src/MDEWInMemoryLoadingPresenter.cpp
@@ -118,6 +118,9 @@ namespace Mantid
 
       // Set the instrument which is associated with the workspace.
       m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(eventWs));
+      
+      // Set the special coordinates
+      m_metadataJsonManager->setSpecialCoordinates(m_specialCoords);
 
       //Call base-class extraction method.
       this->extractMetadata(eventWs);
diff --git a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
index 82023d01a58636ed53077e2d86a57a101a5ba14e..961a2baab4a5177cc86385f2db083e932afde2c6 100644
--- a/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
+++ b/Code/Mantid/Vates/VatesAPI/src/MDHWInMemoryLoadingPresenter.cpp
@@ -120,6 +120,9 @@ namespace Mantid
       // Set the instrument which is associated with the workspace.
       m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(histoWs));
 
+      // Set the special coordinates
+      m_metadataJsonManager->setSpecialCoordinates(m_specialCoords);
+
       //Call base-class extraction method.
       this->extractMetadata(histoWs);
     }
diff --git a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp
index 11fba10cb877d71f98bd3ac81a2840aa3261fdd1..250ba22b74c71a6dd5b9032852577a92c4066c70 100644
--- a/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp
+++ b/Code/Mantid/Vates/VatesAPI/src/MetadataJsonManager.cpp
@@ -1,14 +1,14 @@
 #include "MantidVatesAPI/MetadataJsonManager.h"
-#include <jsoncpp/json/json.h>
-#include <jsoncpp/json/writer.h>
-#include <jsoncpp/json/reader.h>
+#include <json/json.h>
+#include <json/writer.h>
+#include <json/reader.h>
 
 namespace Mantid
 {
   namespace VATES
   {
     // Note that we need to have a non-empty default string
-    MetadataJsonManager::MetadataJsonManager() : instrument("_EMPTY_"), minValue(0.0), maxValue(1.0)
+    MetadataJsonManager::MetadataJsonManager() : instrument("_EMPTY_"), minValue(0.0), maxValue(1.0), specialCoordinates(-1)
     {
       
     }
@@ -29,6 +29,7 @@ namespace Mantid
       metadataContainer["instrument"] = instrument;
       metadataContainer["minValue"] = minValue;
       metadataContainer["maxValue"] = maxValue;
+      metadataContainer["specialCoordinates"] = specialCoordinates;
 
       return writer.write(metadataContainer);
     }
@@ -75,6 +76,16 @@ namespace Mantid
         {
           instrument = "_EMPTY_";
         }
+
+        // Set the instrument
+        if (metadataContainer.isObject() && metadataContainer.isMember("specialCoordinates"))
+        {
+          specialCoordinates = metadataContainer["specialCoordinates"].asInt();
+        }
+        else 
+        {
+          specialCoordinates = -1;
+        }
       }
     }
 
@@ -132,5 +143,23 @@ namespace Mantid
     {
       return instrument;
     }
+
+    /**
+     * Set the special coordinates.
+     * @param specialCoordinates. The special coordinates.
+     */
+    void MetadataJsonManager::setSpecialCoordinates(int specialCoordinates)
+    {
+      this->specialCoordinates = specialCoordinates;
+    }
+
+    /**
+     * Get the special coordinates
+     * @returns The special coordinates.
+     */
+    int MetadataJsonManager::getSpecialCoordinates()
+    {
+      return specialCoordinates;
+    }
   }
 }
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp b/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad1a7317e4f7081b10ac40e29c97f0892b6d8d66
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/ViewFrustum.cpp
@@ -0,0 +1,129 @@
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidKernel/Matrix.h"
+#include <sstream> 
+#include <cmath>
+#include <cfloat>
+
+namespace Mantid
+{
+namespace VATES
+{
+  /**
+   * Represents a view frustum. It contains the parameters for the six plane equations that define the view frustum. Note that the plane 
+   * normals point into the box
+   * @param leftPlane The left plane.
+   * @param rightPlane The right plane.
+   * @param topPlane The top plane.
+   * @param bottomPlane The bottom plane.
+   * @param farPlane The far plane.
+   * @param nearPlane The near plane.
+   */
+  ViewFrustum::ViewFrustum(const LeftPlane leftPlane, const RightPlane rightPlane, const BottomPlane bottomPlane,
+                            const TopPlane topPlane, const FarPlane farPlane,  const NearPlane nearPlane) : m_leftPlane(leftPlane),
+                                                                                                                    m_rightPlane(rightPlane),
+                                                                                                                    m_topPlane(topPlane),
+                                                                                                                    m_bottomPlane(bottomPlane),
+                                                                                                                    m_farPlane(farPlane),
+                                                                                                                    m_nearPlane(nearPlane){}
+  /**
+   * Copy constructor for the view frustum.
+   * @param other The initializing view frustum.
+   */
+  ViewFrustum::ViewFrustum(const ViewFrustum& other): m_leftPlane(other.m_leftPlane),
+                                                      m_rightPlane(other.m_rightPlane),
+                                                      m_topPlane(other.m_topPlane),
+                                                      m_bottomPlane(other.m_bottomPlane),
+                                                      m_farPlane(other.m_farPlane),
+                                                      m_nearPlane(other.m_nearPlane){}
+  /// Destructor
+  ViewFrustum::~ViewFrustum(){}
+
+  /**
+   * Assignment operator
+   * @param other The assigned view frustum.
+   */
+  ViewFrustum& ViewFrustum::operator=(const ViewFrustum& other)
+  {
+    if (&other != this)
+    {
+      m_leftPlane = other.m_leftPlane;
+      m_rightPlane  = other.m_rightPlane;
+      m_topPlane = other.m_topPlane;
+      m_bottomPlane = other.m_bottomPlane;
+      m_farPlane = other.m_farPlane;
+      m_nearPlane = other.m_nearPlane;
+    }
+
+    return *this;
+  }
+
+  /**
+   * Get the extents of the View frustum. We take the minimal rectangular box which in contains the 
+   * view frustum fully.
+   * @returns A vector with the extents
+   */
+  std::vector<std::pair<double, double>> ViewFrustum::toExtents() const
+  {
+    // Get the eight corner points of the view frustum
+    std::vector<std::vector<double>> frustumPoints;
+    frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, TOPPLANE, FARPLANE, double>(m_leftPlane, m_topPlane, m_farPlane));
+    frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, TOPPLANE, NEARPLANE, double>(m_leftPlane, m_topPlane, m_nearPlane));
+
+    frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, BOTTOMPLANE, FARPLANE, double>(m_leftPlane, m_bottomPlane, m_farPlane));
+    frustumPoints.push_back(getIntersectionPointThreePlanes<LEFTPLANE, BOTTOMPLANE, NEARPLANE, double>(m_leftPlane, m_bottomPlane, m_nearPlane));
+
+    frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, TOPPLANE, FARPLANE, double>(m_rightPlane, m_topPlane, m_farPlane));
+    frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, TOPPLANE, NEARPLANE, double>(m_rightPlane, m_topPlane, m_nearPlane));
+
+    frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, BOTTOMPLANE, FARPLANE, double>(m_rightPlane, m_bottomPlane, m_farPlane));
+    frustumPoints.push_back(getIntersectionPointThreePlanes<RIGHTPLANE, BOTTOMPLANE, NEARPLANE, double>(m_rightPlane, m_bottomPlane, m_nearPlane));
+
+    std::vector<std::pair<double, double>> extents;
+
+    for (int i = 0; i < 3; ++i)
+    {
+      std::pair<double, double> minMax(DBL_MAX, -DBL_MAX);
+      for (std::vector<std::vector<double>>::iterator it = frustumPoints.begin(); it != frustumPoints.end(); ++it)
+      {
+        if ((*it)[i] < minMax.first)
+        {
+          minMax.first = (*it)[i];
+        }
+
+        if ((*it)[i] > minMax.second)
+        {
+          minMax.second = (*it)[i];
+        }
+      }
+
+      extents.push_back(minMax);
+    }
+
+    return extents;
+  }
+
+  /**
+   * Get the extents as a concatenated string.
+   * @returns The extens of the view frustum as a concatenated string
+   */
+  std::string ViewFrustum::toExtentsAsString() const
+  {
+    std::vector<std::pair<double, double>> extents = toExtents();
+    
+    std::stringstream ss;
+
+    for (std::vector<std::pair<double, double>>::iterator it = extents.begin(); it != extents.end(); ++it)
+    {
+      ss << it->first << "," << it->second;
+
+      if ((it+1)!= extents.end())
+      {
+        ss << ",";
+      }
+    }
+
+    return ss.str();
+  }
+
+}
+}
diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..833aa6ff9c370dbd2c453130ee6ae25cbdd28ee6
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/vtkDataSetToPeaksFilteredDataSet.cpp
@@ -0,0 +1,308 @@
+#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h"
+#include "MantidAPI/IPeak.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidDataObjects/NoShape.h"
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include "MantidKernel/SpecialCoordinateSystem.h"
+#include "MantidKernel/V3D.h"
+#include "MantidKernel/ReadLock.h"
+#include "MantidKernel/WarningSuppressions.h"
+#include "MantidVatesAPI/ProgressAction.h"
+
+#include <vtkExtractSelection.h>
+#include <vtkIdTypeArray.h>
+#include <vtkNew.h>
+#include <vtkPoints.h>
+#include <vtkSelection.h>
+#include <vtkSelectionNode.h>
+#include <vtkSmartPointer.h>
+#include <vtkUnstructuredGrid.h>
+#include <vtkFieldData.h>
+#include <vtkIdList.h>
+#include <vtkFieldData.h>
+
+#include <boost/shared_ptr.hpp>
+#include <stdexcept>
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <cmath>
+
+
+namespace Mantid
+{
+namespace VATES
+{
+  /**
+    * Standard constructor for object.
+    * @param input : The dataset to peaks filter
+    * @param output : The resulting peaks filtered dataset
+    */
+  vtkDataSetToPeaksFilteredDataSet::vtkDataSetToPeaksFilteredDataSet(vtkUnstructuredGrid *input,
+                                                                     vtkUnstructuredGrid *output) :
+                                                                    m_inputData(input),
+                                                                    m_outputData(output),
+                                                                    m_isInitialised(false),
+                                                                    m_radiusNoShape(0.2),
+                                                                    m_radiusType(0),
+                                                                    m_radiusFactor(2),
+                                                                    m_defaultRadius(0.1),
+                                                                    m_coordinateSystem(0)
+  {
+    if (NULL == m_inputData)
+    {
+      throw std::runtime_error("Cannot construct vtkDataSetToPeaksFilteredDataSet with NULL input vtkUnstructuredGrid");
+    }
+    if (NULL == m_outputData)
+    {
+      throw std::runtime_error("Cannot construct vtkDataSetToPeaksFilteredDataSet with NULL output vtkUnstructuredGrid");
+    }
+  }
+
+
+  vtkDataSetToPeaksFilteredDataSet::~vtkDataSetToPeaksFilteredDataSet()
+  {
+    
+  }
+
+  /**
+    * Set the value for the underlying peaks workspace
+    * @param peaksWorkspaces : A list of peak workspace names.
+    * @param radiusNoShape : The peak radius for no shape.
+    * @param radiusType : The type of the radius: Radius(0), Outer Radius(10, Inner Radius(1)
+    * @param coordinateSystem: A coordinate system.
+    */
+  void vtkDataSetToPeaksFilteredDataSet::initialize(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces, double radiusNoShape, int radiusType, int coordinateSystem)
+  {
+    m_peaksWorkspaces = peaksWorkspaces;
+    m_radiusNoShape = radiusNoShape;
+    m_radiusType = radiusType;
+    m_isInitialised = true;
+    m_coordinateSystem = coordinateSystem;
+  }
+
+  /**
+    * Process the input data. First, get all the peaks and their associated geometry. Then filter 
+    * through the input to find the peaks which lie within a peak. Then apply then to the output data.
+    * Then update the metadata. See http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/ExtractSelection
+    * @param progressUpdating The handle for the progress bar.
+    */
+  void vtkDataSetToPeaksFilteredDataSet::execute(ProgressAction& progressUpdating)
+  {
+    if (!m_isInitialised)
+    {
+      throw std::runtime_error("vtkDataSetToPeaksFilteredDataSet needs initialize run before executing");
+    }
+
+    // Get the peaks location and the radius information
+    std::vector<std::pair<Mantid::Kernel::V3D, double>> peaksInfo = getPeaksInfo(m_peaksWorkspaces);
+
+    // Compare each element of the vtk data set and check which ones to keep
+    vtkPoints *points = m_inputData->GetPoints();
+
+    vtkSmartPointer<vtkIdTypeArray> ids = vtkSmartPointer<vtkIdTypeArray>::New();
+    ids->SetNumberOfComponents(1);
+
+    double progressFactor = 1.0/double(points->GetNumberOfPoints());
+    for(int i = 0; i < points->GetNumberOfPoints(); i++)
+    {
+      progressUpdating.eventRaised(double(i)*progressFactor);
+      double point[3];
+      points->GetPoint(i, point);
+
+      // Compare to Peaks
+      const size_t numberOfPeaks = peaksInfo.size();
+      size_t counter = 0;
+      while (counter < numberOfPeaks)
+      {
+        // Calcuate the differnce between the vtkDataSet point and the peak. Needs to be smaller than the radius
+        double squaredDifference = 0;
+        for (int k = 0; k <3; k++)
+        {
+          squaredDifference += (point[k] - peaksInfo[counter].first[k])* (point[k] - peaksInfo[counter].first[k]);
+        }
+
+        if (squaredDifference <= (peaksInfo[counter].second*peaksInfo[counter].second))
+        {
+          ids->InsertNextValue(i);
+          break;
+        }
+        counter++;
+      }
+    }
+
+    // Now we have all ids for the points,  we need to retrieve the ids of the cells
+    std::map<vtkIdType, vtkIdType> uniqueCellTester;
+    vtkSmartPointer<vtkIdTypeArray> cellIds = vtkSmartPointer<vtkIdTypeArray>::New();
+
+    for (int i = 0; i < ids->GetNumberOfTuples(); i++) {
+      vtkIdType pId = ids->GetValue(i);
+
+      vtkSmartPointer<vtkIdList> cIdList = vtkSmartPointer<vtkIdList>::New();
+      cIdList->Initialize();
+  
+      m_inputData->GetPointCells(pId, cIdList);
+      
+      if (cIdList->GetNumberOfIds() == 0) {
+        continue;
+      }
+
+      vtkIdType cId = cIdList->GetId(0);
+
+      if (uniqueCellTester.count(cId) == 0) {
+        cellIds->InsertNextValue(cId);
+        uniqueCellTester.insert(std::pair<vtkIdType, vtkIdType>(cId, cId));
+      }
+    }
+
+    // Create the selection node and tell it the type of selection
+    vtkSmartPointer<vtkSelectionNode> selectionNode = vtkSmartPointer<vtkSelectionNode>::New();
+    selectionNode->SetFieldType(vtkSelectionNode::CELL);
+    selectionNode->SetContentType(vtkSelectionNode::INDICES);
+    selectionNode->SetSelectionList(cellIds);
+
+    vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New();
+    selection->AddNode(selectionNode);
+
+    // We are not setting up a pipeline here, cannot access vtkAlgorithmOutput
+    vtkSmartPointer<vtkExtractSelection> extractSelection = vtkSmartPointer<vtkExtractSelection>::New();
+    extractSelection->SetInputData(0,m_inputData);
+    extractSelection->SetInputData(1, selection);
+    extractSelection->Update();
+    
+    //Extract
+    m_outputData->ShallowCopy(extractSelection->GetOutput());
+  }
+
+  /**
+   * Get the peaks information which is the position and the largest radius of the peak.
+   * @param A list of peaks workspaces
+   * @returns A list of pair information which contains the position and the radius.
+   */
+  std::vector<std::pair<Mantid::Kernel::V3D, double>> vtkDataSetToPeaksFilteredDataSet::getPeaksInfo(std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksWorkspaces)
+  {
+    std::vector<std::pair<Mantid::Kernel::V3D, double>> peaksInfo;
+    // Iterate over all peaksworkspaces and add the their info to the output vector
+    for (std::vector<Mantid::API::IPeaksWorkspace_sptr>::iterator it = peaksWorkspaces.begin(); it != peaksWorkspaces.end(); ++it)
+    {
+      const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = static_cast<Mantid::Kernel::SpecialCoordinateSystem>(m_coordinateSystem);
+      int numPeaks = (*it)->getNumberPeaks();
+       
+      // Iterate over all peaks for the workspace
+      for (int i = 0; i < numPeaks ; i++)
+      {
+        Mantid::API::IPeak* peak = (*it)->getPeakPtr(i);
+
+        addSinglePeak(peak, coordinateSystem, peaksInfo);
+      }
+    }
+    return peaksInfo;
+  }
+
+GCC_DIAG_OFF(strict-aliasing)
+  /**
+   * Add information for a single peak to the peakInfo vector.
+   * @param peak The peak from which the information will be extracted.
+   * @param coordinateSystem The coordinate system in which the peaks position should be retrieved.
+   * @param peaksInfo A reference to the vector containing peak information.
+   * @param index The index of the peak in the peaksInfo vector.
+   */
+  void vtkDataSetToPeaksFilteredDataSet::addSinglePeak(Mantid::API::IPeak* peak, const Mantid::Kernel::SpecialCoordinateSystem coordinateSystem, std::vector<std::pair<Mantid::Kernel::V3D, double>>& peaksInfo)
+  {
+    double radius = m_defaultRadius;
+    const Mantid::Geometry::PeakShape& shape = peak->getPeakShape();
+    std::string shapeName = shape.shapeName();
+
+    // Get the radius and the position for the correct peak shape
+    if (shapeName == Mantid::DataObjects::PeakShapeSpherical::sphereShapeName())
+    {
+      const Mantid::DataObjects::PeakShapeSpherical& sphericalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeSpherical&>(shape);
+      if (m_radiusType == 0)
+      {
+        radius = sphericalShape.radius();
+      }
+      else if (m_radiusType == 1)
+      {
+          boost::optional<double> radOut = sphericalShape.backgroundOuterRadius();
+          if (radOut.is_initialized()) {
+            radius = radOut.get();
+          }
+      }
+      else if (m_radiusType == 2)
+      {
+          boost::optional<double> radIn = sphericalShape.backgroundInnerRadius();
+          if (radIn.is_initialized()) { 
+           radius = radIn.get();
+          }
+      }
+      else 
+      {
+        throw std::invalid_argument("The shperical peak shape does not have a radius. \n");
+      }
+    }
+    else if (shapeName == Mantid::DataObjects::PeakShapeEllipsoid::ellipsoidShapeName())
+    {
+      const Mantid::DataObjects::PeakShapeEllipsoid& ellipticalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeEllipsoid&>(shape);
+      if (m_radiusType == 0)
+      {
+        std::vector<double> radii(ellipticalShape.abcRadii());
+        radius = *(std::max_element(radii.begin(), radii.end()));
+      }
+      else if (m_radiusType == 1)
+      {
+        std::vector<double> radii(ellipticalShape.abcRadiiBackgroundOuter());
+        radius = *(std::max_element(radii.begin(), radii.end()));
+      }
+      else if (m_radiusType == 2)
+      {
+        std::vector<double> radii(ellipticalShape.abcRadiiBackgroundInner());
+        radius = *(std::max_element(radii.begin(), radii.end()));
+      }
+      else 
+      {
+        throw std::invalid_argument("The ellipsoidal peak shape does not have a radius. \n");
+      }
+    }
+    else
+    {
+      radius = m_radiusNoShape;
+    }
+
+    // Get the position in the correct frame.
+    switch(coordinateSystem)
+    {
+      case(Mantid::Kernel::SpecialCoordinateSystem::HKL):
+        peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getHKL(), radius*m_radiusFactor));
+        break;
+      case(Mantid::Kernel::SpecialCoordinateSystem::QLab):
+        peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getQLabFrame(), radius*m_radiusFactor));
+        break;
+      case(Mantid::Kernel::SpecialCoordinateSystem::QSample):
+        peaksInfo.push_back(std::pair<Mantid::Kernel::V3D, double>(peak->getQSampleFrame(), radius*m_radiusFactor));
+        break;
+      default:
+        throw std::invalid_argument("The special coordinate systems don't match.");
+    }
+  }
+//GCC_DIAG_ON(strict-aliasing)
+  /**
+   * Get the radiys for no shape
+   * @returns The shape of the radius.
+   */
+  double vtkDataSetToPeaksFilteredDataSet::getRadiusNoShape(){
+    return m_radiusNoShape;
+  }
+
+  /**
+   * Get the radius factor which is used to calculate the radius of the culled data set around each peak
+   * The culling radius is the radius of the peak times the radius factor.
+   * @returns The radius factor.
+   */
+  double vtkDataSetToPeaksFilteredDataSet::getRadiusFactor() {
+    return m_radiusFactor;
+  }
+}
+}
+
diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6437744474d87fbe1539ae8c8c8abb288518c840
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/vtkEllipsoidTransformer.cpp
@@ -0,0 +1,78 @@
+#include "MantidVatesAPI/vtkEllipsoidTransformer.h"
+#include "MantidKernel/V3D.h"
+
+#include <vtkSmartPointer.h>
+#include <vtkTransform.h>
+#include <vector>
+#include <cmath>
+
+namespace Mantid
+{
+namespace VATES
+{
+  vtkEllipsoidTransformer::vtkEllipsoidTransformer(){}
+
+  vtkEllipsoidTransformer::~vtkEllipsoidTransformer(){}
+
+  /**
+  * Generates a transform based on the directions of the ellipsoid
+  * @param directions The directions of the ellipsoid.
+  * @returns A transform for the ellipsoid.
+  */
+  vtkSmartPointer<vtkTransform> vtkEllipsoidTransformer::generateTransform(std::vector<Mantid::Kernel::V3D> directions)
+  {
+    // The original ellipsoid is set to have its principal axis along the x axis and the first minor axis along the y axis.
+    Mantid::Kernel::V3D principalAxisOriginal(1.0, 0.0, 0.0);
+    Mantid::Kernel::V3D principalAxisTransformed(directions[0]);
+    Mantid::Kernel::V3D minorAxisOriginal(0.0, 1.0, 0.0);
+    Mantid::Kernel::V3D minorAxisTransformed(directions[1]);
+
+    // Compute the axis of rotation. This is the normal between the original and the transformed direction
+    Mantid::Kernel::V3D rotationAxis1 = principalAxisOriginal.cross_prod(principalAxisTransformed);
+    rotationAxis1 = rotationAxis1/rotationAxis1.norm();
+
+    // Compute the angle of rotation, i.e. the angle between the original and the transformed axis.
+    double angle1 = acos(principalAxisOriginal.scalar_prod(principalAxisTransformed)
+                    /principalAxisOriginal.norm()/principalAxisTransformed.norm());
+
+    // After the prinicpal axis is rotated into its right position we need to rotate the (rotated) minor axis
+    // into its right position. The rotation axis is given by the new prinicipal rotation axis
+    Mantid::Kernel::V3D minorAxisOriginalRotated(rotateVector(minorAxisOriginal, rotationAxis1, angle1));
+
+    Mantid::Kernel::V3D rotationAxis2(minorAxisOriginalRotated.cross_prod(minorAxisTransformed));
+    rotationAxis2 = rotationAxis2/rotationAxis2.norm();
+    double angle2 = acos(minorAxisOriginalRotated.scalar_prod(minorAxisTransformed)
+                     /minorAxisOriginalRotated.norm()/minorAxisTransformed.norm());
+
+    vtkSmartPointer<vtkTransform> transform = vtkSmartPointer<vtkTransform>::New();
+
+    double angle1Degree = angle1*180/M_PI;
+    double angle2Degree = angle2*180/M_PI;
+
+    // The total transform is T = T_rot2*T_rot1. Note that we need to add the last operation first!
+    transform->RotateWXYZ(angle2Degree, rotationAxis2[0], rotationAxis2[1], rotationAxis2[2]);
+    transform->RotateWXYZ(angle1Degree, rotationAxis1[0], rotationAxis1[1], rotationAxis1[2]);
+
+    return transform;
+  }
+
+  /**
+  * Rotate the a given vector around a specified axis by a specified angle. See http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
+  * @param original The original vector
+  * @param rotationAxis The axis around which to rotate.
+  * @param angle The rotation angle.
+  * @returns The rotated vector.
+  */
+  Mantid::Kernel::V3D vtkEllipsoidTransformer::rotateVector(Mantid::Kernel::V3D original, Mantid::Kernel::V3D rotationAxis, double angle)
+  {
+    Mantid::Kernel::V3D cross(rotationAxis.cross_prod(original));
+    double scalar = rotationAxis.scalar_prod(original);
+    double cos = std::cos(angle);
+    double sin = std::sin(angle);
+
+    Mantid::Kernel::V3D rotated = original*cos + cross*sin + rotationAxis*(scalar)*(1-cos);
+
+    return rotated;
+  }
+}
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp
index 6171b6c9ac604ed0e38f72d089129064b791c7db..be22450371ac2316f269c44710fa64f2cb66e35a 100644
--- a/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp
+++ b/Code/Mantid/Vates/VatesAPI/src/vtkPeakMarkerFactory.cpp
@@ -1,17 +1,35 @@
 #include "MantidVatesAPI/vtkPeakMarkerFactory.h"
 #include "MantidVatesAPI/ProgressAction.h"
+#include "MantidVatesAPI/vtkEllipsoidTransformer.h"
 #include <boost/math/special_functions/fpclassify.hpp>
 #include "MantidAPI/Workspace.h"
 #include "MantidAPI/IPeaksWorkspace.h"
 #include "MantidAPI/IPeak.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
 #include "MantidKernel/V3D.h"
+#include "MantidKernel/ReadLock.h"
+
+#include <vtkAxes.h>
+#include "vtkParametricEllipsoid.h"
+#include "vtkParametricFunctionSource.h"
+#include <vtkPolyDataAlgorithm.h>
+#include <vtkAppendPolyData.h>
 #include <vtkVertex.h>
 #include <vtkGlyph3D.h>
 #include <vtkSphereSource.h>
 #include <vtkUnstructuredGrid.h>
 #include <vtkFloatArray.h>
 #include <vtkCellData.h>
-#include "MantidKernel/ReadLock.h"
+#include <vtkPolyData.h>
+#include <vtkTransform.h>
+#include <vtkTransformPolyDataFilter.h>
+#include <vtkPVGlyphFilter.h>
+#include <vtkSmartPointer.h>
+
+#include <vtkLineSource.h>
+#include <cmath>
 
 using Mantid::API::IPeaksWorkspace;
 using Mantid::API::IPeak;
@@ -91,12 +109,12 @@ namespace VATES
   }
 
 
-  /**
+    /**
   Create the vtkStructuredGrid from the provided workspace
   @param progressUpdating: Reporting object to pass progress information up the stack.
   @return vtkPolyData glyph.
   */
-  vtkDataSet* vtkPeakMarkerFactory::create(ProgressAction& progressUpdating) const
+  vtkPolyData* vtkPeakMarkerFactory::create(ProgressAction& progressUpdating) const
   {
     validate();
 
@@ -105,28 +123,32 @@ namespace VATES
    // Acquire a scoped read-only lock to the workspace (prevent segfault from algos modifying ws)
     Mantid::Kernel::ReadLock lock(*m_workspace);
 
-    // Points generator
-    vtkPoints *points = vtkPoints::New();
-    points->Allocate(static_cast<int>(numPeaks));
-
-    vtkFloatArray * signal = vtkFloatArray::New();
-    signal->Allocate(numPeaks);
-    signal->SetName(m_scalarName.c_str());
-    signal->SetNumberOfComponents(1);
-
-    // What we'll return
-    vtkUnstructuredGrid *visualDataSet = vtkUnstructuredGrid::New();
-    visualDataSet->Allocate(numPeaks);
-    visualDataSet->SetPoints(points);
-    visualDataSet->GetCellData()->SetScalars(signal);
+    vtkEllipsoidTransformer ellipsoidTransformer;
 
+    const int resolution = 8;
     double progressFactor = 1.0/double(numPeaks);
 
+    vtkAppendPolyData* appendFilter = vtkAppendPolyData::New();
     // Go peak-by-peak
     for (int i=0; i < numPeaks; i++)
     {
       progressUpdating.eventRaised(double(i)*progressFactor);
 
+      // Point
+      vtkPoints *peakPoint = vtkPoints::New();
+      peakPoint->Allocate(1);
+
+      vtkFloatArray * peakSignal = vtkFloatArray::New();
+      peakSignal->Allocate(1);
+      peakSignal->SetName(m_scalarName.c_str());
+      peakSignal->SetNumberOfComponents(1);
+
+      // What we'll return
+      vtkUnstructuredGrid *peakDataSet = vtkUnstructuredGrid::New();
+      peakDataSet->Allocate(1);
+      peakDataSet->SetPoints(peakPoint);
+      peakDataSet->GetCellData()->SetScalars(peakSignal);
+
       IPeak & peak = m_workspace->getPeak(i);
 
       // Choose the dimensionality of the position to show
@@ -152,23 +174,115 @@ namespace VATES
 
       // One point per peak
       vtkVertex * vertex = vtkVertex::New();
-      vtkIdType id_xyz =    points->InsertNextPoint(x,y,z);
+      vtkIdType id_xyz = peakPoint->InsertNextPoint(x,y,z);
       vertex->GetPointIds()->SetId(0, id_xyz);
 
-      visualDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds());
+      peakDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds());
 
       // The integrated intensity = the signal on that point.
-      signal->InsertNextValue(static_cast<float>( peak.getIntensity() ));
+      peakSignal->InsertNextValue(static_cast<float>( peak.getIntensity() ));
+      peakPoint->Squeeze();
+      peakDataSet->Squeeze();
 
-    } // for each peak
+      // Add a glyph and append to the appendFilter
+      const Mantid::Geometry::PeakShape& shape = m_workspace->getPeakPtr(i)->getPeakShape();
 
-    points->Squeeze();
-    visualDataSet->Squeeze();
+      // Pick the radius up from the factory if possible, otherwise use the user-provided value.
+      vtkPolyDataAlgorithm* shapeMarker = NULL;
+      if(shape.shapeName() == Mantid::DataObjects::PeakShapeSpherical::sphereShapeName())
+      {
+        const Mantid::DataObjects::PeakShapeSpherical& sphericalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeSpherical&>(shape);
+        double peakRadius = sphericalShape.radius();
+        vtkSphereSource *sphere = vtkSphereSource::New();
+        sphere->SetRadius(peakRadius);
+        sphere->SetPhiResolution(resolution);
+        sphere->SetThetaResolution(resolution);
+        shapeMarker = sphere;
+      }
+      else if (shape.shapeName() == Mantid::DataObjects::PeakShapeEllipsoid::ellipsoidShapeName())
+      {
+        const Mantid::DataObjects::PeakShapeEllipsoid& ellipticalShape = dynamic_cast<const Mantid::DataObjects::PeakShapeEllipsoid&>(shape);
+        std::vector<double> radii = ellipticalShape.abcRadii();
+        std::vector<Mantid::Kernel::V3D> directions;
+         
+        switch (m_dimensionToShow)
+        {
+          case Peak_in_Q_lab:
+            directions = ellipticalShape.directions();
+            break;
+          case Peak_in_Q_sample:
+          {
+            Mantid::Kernel::Matrix<double> goniometerMatrix = peak.getGoniometerMatrix();
+            if (goniometerMatrix.Invert())
+            {
+              directions = ellipticalShape.getDirectionInSpecificFrame(goniometerMatrix);
+            }
+            else
+            {
+              directions = ellipticalShape.directions();
+            }
+          }
+          break;
+        case Peak_in_HKL:
+          directions = ellipticalShape.directions();
+          break;
+        default:
+          directions = ellipticalShape.directions();
+        }
+
+        vtkParametricEllipsoid* ellipsoid = vtkParametricEllipsoid::New();
+        ellipsoid->SetXRadius(radii[0]);
+        ellipsoid->SetYRadius(radii[1]);
+        ellipsoid->SetZRadius(radii[2]);
+
+        vtkParametricFunctionSource* ellipsoidSource = vtkParametricFunctionSource::New();
+        ellipsoidSource->SetParametricFunction(ellipsoid);
+        ellipsoidSource->SetUResolution(resolution);
+        ellipsoidSource->SetVResolution(resolution);
+        ellipsoidSource->SetWResolution(resolution);
+        ellipsoidSource->Update();
+
+        vtkSmartPointer<vtkTransform> transform = ellipsoidTransformer.generateTransform(directions);
+
+        vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
+        transformFilter->SetTransform(transform);
+        transformFilter->SetInputConnection(ellipsoidSource->GetOutputPort());
+        transformFilter->Update();
+        shapeMarker = transformFilter;
+      }
+      else
+      {
+        vtkAxes* axis = vtkAxes::New();
+        axis->SymmetricOn();
+        axis->SetScaleFactor(0.3);
+
+        vtkTransform* transform = vtkTransform::New();
+        const double rotationDegrees = 45;
+        transform->RotateX(rotationDegrees);
+        transform->RotateY(rotationDegrees);
+        transform->RotateZ(rotationDegrees);
+
+        vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
+        transformFilter->SetTransform(transform);
+        transformFilter->SetInputConnection(axis->GetOutputPort());
+        transformFilter->Update();
+        shapeMarker = transformFilter;
+      }
 
-    return visualDataSet;
-  }
+      vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New();
+      glyphFilter->SetInputData(peakDataSet);
+      glyphFilter->SetSourceConnection(shapeMarker->GetOutputPort());
+      glyphFilter->Update();
+      vtkPolyData *glyphed = glyphFilter->GetOutput();
 
+      appendFilter->AddInputData(glyphed);
+    } // for each peak
 
+    appendFilter->Update();
+    vtkPolyData* polyData = appendFilter->GetOutput();
+
+    return polyData;
+  }
 
   vtkPeakMarkerFactory::~vtkPeakMarkerFactory()
   {
diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9b4ae5ba2c90a53472d093c21f34132beefe84c6
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/src/vtkSinglePeakMarker.cpp
@@ -0,0 +1,76 @@
+#include "MantidVatesAPI/vtkSinglePeakMarker.h"
+#include <vtkPolyData.h>
+#include "vtkFloatArray.h"
+#include "vtkPoints.h"
+#include "vtkUnstructuredGrid.h"
+#include "vtkVertex.h"
+#include "vtkPVGlyphFilter.h"
+#include "vtkCellData.h"
+#include "vtkSphereSource.h"
+#include "vtkTransform.h"
+#include "vtkTransformPolyDataFilter.h"
+
+namespace Mantid
+{
+namespace VATES 
+{
+  vtkSinglePeakMarker::vtkSinglePeakMarker(){
+  }
+
+  vtkSinglePeakMarker::~vtkSinglePeakMarker(){
+  }
+
+  vtkPolyData* vtkSinglePeakMarker::createSinglePeakMarker(double x, double y, double z, double radius){
+
+    // Point
+    vtkPoints *peakPoint = vtkPoints::New();
+    peakPoint->Allocate(1);
+
+    vtkFloatArray * peakSignal = vtkFloatArray::New();
+    peakSignal->Allocate(1);
+    peakSignal->SetName("signal");
+    peakSignal->SetNumberOfComponents(1);
+
+    // What we'll return
+    vtkUnstructuredGrid *peakDataSet = vtkUnstructuredGrid::New();
+    peakDataSet->Allocate(1);
+    peakDataSet->SetPoints(peakPoint);
+    peakDataSet->GetCellData()->SetScalars(peakSignal);
+
+    // One point per peak
+    vtkVertex * vertex = vtkVertex::New();
+    vtkIdType id_xyz = peakPoint->InsertNextPoint(x,y,z);
+    vertex->GetPointIds()->SetId(0, id_xyz);
+
+    peakDataSet->InsertNextCell(VTK_VERTEX, vertex->GetPointIds());
+
+    // The integrated intensity = the signal on that point.
+    peakSignal->InsertNextValue(static_cast<float>(1.0));
+    peakPoint->Squeeze();
+    peakDataSet->Squeeze();
+
+    //Get the position info and create the glyph which is to be displayed.
+    vtkSphereSource* sphere = vtkSphereSource::New();
+    const int resolution = 16;
+    sphere->SetRadius(radius);
+    sphere->SetPhiResolution(resolution);
+    sphere->SetThetaResolution(resolution);
+
+    vtkTransform* transform = vtkTransform::New();
+    transform->Translate(0, 0, 0);
+
+    vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
+    transformFilter->SetTransform(transform);
+    transformFilter->SetInputConnection(sphere->GetOutputPort());
+    transformFilter->Update();
+
+    vtkPVGlyphFilter *glyphFilter = vtkPVGlyphFilter::New();
+    glyphFilter->SetInputData(peakDataSet);
+    glyphFilter->SetSourceConnection(transformFilter->GetOutputPort());
+    glyphFilter->Update();
+    vtkPolyData *glyphed = glyphFilter->GetOutput();
+
+    return glyphed;
+  }
+}
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
index 91606a695251cb06b5ebd2ebb1ef2d82ea4985f2..02c12390c53328d517d0c26b3c816e678de65180 100644
--- a/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
+++ b/Code/Mantid/Vates/VatesAPI/src/vtkSplatterPlotFactory.cpp
@@ -9,6 +9,12 @@
 #include "MantidGeometry/MDGeometry/MDHistoDimension.h"
 #include "MantidVatesAPI/ProgressAction.h"
 #include "MantidVatesAPI/Common.h"
+#include "MantidVatesAPI/MetadataToFieldData.h"
+#include "MantidVatesAPI/FieldDataToMetadata.h"
+#include "MantidVatesAPI/MetaDataExtractorUtils.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
+#include "MantidVatesAPI/VatesXMLDefinitions.h"
 
 #include <vtkCellData.h>
 #include <vtkFloatArray.h>
@@ -59,7 +65,9 @@ namespace VATES
   m_buildSortedList(true), m_wsName(""), dataSet(NULL),
   slice(false), sliceMask(NULL), sliceImplicitFunction(NULL),
   m_time(0.0),
-  m_metaDataExtractor(new MetaDataExtractorUtils())
+  m_metaDataExtractor(new MetaDataExtractorUtils()),
+  m_metadataJsonManager(new MetadataJsonManager()),
+  m_vatesConfigurations(new VatesConfigurations())
   {
   }
 
@@ -576,6 +584,9 @@ namespace VATES
       delete this->sliceImplicitFunction;
     }
 
+    // Add metadata in json format
+    this->addMetadata();
+
     // The macro does not allow return calls, so we used a member variable.
     return this->dataSet;
   }
@@ -618,6 +629,66 @@ namespace VATES
     }
   }
 
+  /**
+   * Add meta data to the visual data set.
+   */ 
+  void vtkSplatterPlotFactory::addMetadata() const {
+    const double defaultValue = 0.1;
+
+    if (this->dataSet)
+    {
+      double* range = NULL;
+      range = dataSet->GetScalarRange();
+
+      if (range)
+      {
+        m_minValue = range[0];
+        m_maxValue = range[1];
+      }
+      else
+      {
+        m_minValue = defaultValue;
+        m_maxValue = defaultValue;
+      }
+
+      m_metadataJsonManager->setMinValue(m_minValue);
+      m_metadataJsonManager->setMaxValue(m_maxValue);
+      m_metadataJsonManager->setInstrument(m_metaDataExtractor->extractInstrument(m_workspace));
+      m_metadataJsonManager->setSpecialCoordinates(static_cast<int>(m_workspace->getSpecialCoordinateSystem()));
+
+      // Append metadata
+      std::string jsonString = m_metadataJsonManager->getSerializedJson();
+      vtkFieldData* outputFD = vtkFieldData::New();
+
+      //Add metadata to dataset.
+      MetadataToFieldData convert;
+      convert(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str());
+      dataSet->SetFieldData(outputFD);
+
+      outputFD->Delete();
+    } 
+  }
+
+  /**
+  * Write the xml metadata from the underlying source into the vktArray of the 
+  * @param fieldData The field data from the underlying source
+  * @param dataSet The splatterplot data set.
+  */
+  void vtkSplatterPlotFactory::setMetadata(vtkFieldData* fieldData, vtkDataSet* dataSet) {
+    // Extract the xml-metadata part of the fieldData and the json-metadata from the dataset
+    FieldDataToMetadata convertFtoM;
+    std::string xmlString = convertFtoM(fieldData, XMLDefinitions::metaDataId());
+    std::string jsonString = convertFtoM(dataSet->GetFieldData(), m_vatesConfigurations->getMetadataIdJson().c_str());
+
+    // Create a new field data array 
+    MetadataToFieldData convertMtoF;
+    vtkFieldData* outputFD = vtkFieldData::New();
+    convertMtoF(outputFD, xmlString, XMLDefinitions::metaDataId().c_str());
+    convertMtoF(outputFD, jsonString, m_vatesConfigurations->getMetadataIdJson().c_str());
+    dataSet->SetFieldData(outputFD);
+    outputFD->Delete();
+ }
+
   /**
    * Sets the number of points to show
    * @param points : The total number of points to plot.
diff --git a/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a237129ebf5a1bb0f24e777e2ebbc645639f36b8
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/CompositePeaksPresenterVsiTest.h
@@ -0,0 +1,116 @@
+#ifndef COMOPOSITE_PEAKS_PRESENTER_VSI_TEST_H_
+#define COMOPOSITE_PEAKS_PRESENTER_VSI_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidVatesAPI/CompositePeaksPresenterVsi.h"
+#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+
+#include <boost/shared_ptr.hpp>
+#include <stdexcept>
+
+#include "MockObjects.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+
+#include <string>
+
+using namespace ::testing;
+using namespace Mantid::VATES;
+
+class MockPeaksWorkspaceComposite : public Mantid::DataObjects::PeaksWorkspace
+{
+public:
+};
+
+class CompositePeaksPresenterVsiTest : public CxxTest::TestSuite {
+public:
+  void testSetupPresenterCorrectly() {
+
+  }
+
+  void testThatGettingPeaksWorkspaceDirectlyIsNotAllowed() {
+    // Arrange
+    CompositePeaksPresenterVsi presenter;
+    // Assert
+    TS_ASSERT_THROWS(presenter.getPeaksWorkspace(), std::runtime_error);
+  }
+
+  void testThatGettingPeaksWorkspaceNameDirectlyIsNotAllowed() {
+    // Arrange
+    CompositePeaksPresenterVsi presenter;
+    // Assert
+    TS_ASSERT_THROWS(presenter.getPeaksWorkspaceName(), std::runtime_error);
+  }
+
+  void testThatGetListOfNamesOfSubPresenters() {
+    // Arrange
+    CompositePeaksPresenterVsi presenter;
+
+    std::string frame = "testFrame";
+    
+    LeftPlane left(1.0, 0.0, 0.0, 1.0);
+
+    RightPlane right(-1.0, 0.0, 0.0, 1.0);
+    BottomPlane bottom(0.0, 1.0, 0.0, 1.0);
+    TopPlane top(0.0, -1.0, 0.0, 1.0);
+    FarPlane farPlane(0.0, 0.0, 1.0, 1.0);
+    NearPlane nearPlane(0.0, 0.0, -1.0,1.0);
+    ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane);
+
+    boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr(new MockPeaksWorkspaceComposite());
+    std::string name = "pw1";
+    PeaksPresenterVsi_sptr p1(new ConcretePeaksPresenterVsi(pw_ptr, frustum, frame));
+
+
+    boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr2(new MockPeaksWorkspaceComposite());
+    std::string name2 = "pw2";
+    PeaksPresenterVsi_sptr p2(new ConcretePeaksPresenterVsi(pw_ptr2, frustum, frame));
+
+    presenter.addPresenter(p1);
+    presenter.addPresenter(p2);
+
+    // Act
+    std::vector<std::string> wsNames = presenter.getPeaksWorkspaceNames();
+
+    // Assert, cannot mock the getName function as it is not virtual
+    TSM_ASSERT_EQUALS("Should have two entries", wsNames.size(), 2);
+  }
+
+  void testThatGetsAllPeaksWorkspaces() {
+    // Arrange
+    CompositePeaksPresenterVsi presenter;
+
+    std::string frame = "testFrame";
+    
+    LeftPlane left(1.0, 0.0, 0.0, 1.0);
+
+    RightPlane right(-1.0, 0.0, 0.0, 1.0);
+    BottomPlane bottom(0.0, 1.0, 0.0, 1.0);
+    TopPlane top(0.0, -1.0, 0.0, 1.0);
+    FarPlane farPlane(0.0, 0.0, 1.0, 1.0);
+    NearPlane nearPlane(0.0, 0.0, -1.0,1.0);
+    ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane);
+
+    boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr(new MockPeaksWorkspaceComposite());
+    std::string name = "pw1";
+    PeaksPresenterVsi_sptr p1(new ConcretePeaksPresenterVsi(pw_ptr, frustum, frame));
+
+    boost::shared_ptr<MockPeaksWorkspaceComposite> pw_ptr2(new MockPeaksWorkspaceComposite());
+    std::string name2 = "pw2";
+    PeaksPresenterVsi_sptr p2(new ConcretePeaksPresenterVsi(pw_ptr2, frustum, frame));
+
+    presenter.addPresenter(p1);
+    presenter.addPresenter(p2);
+
+    // Act
+    std::vector<Mantid::API::IPeaksWorkspace_sptr> ws = presenter.getPeaksWorkspaces();
+
+    // Assert
+    TSM_ASSERT_EQUALS("Should have two entries", ws.size(), 2);
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..5391f01e92b4303b311ce6e9dbbf627a9e6a6877
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/ConcretePeaksPresenterVsiTest.h
@@ -0,0 +1,107 @@
+#ifndef CONCRETE_PEAKS_PRESENTER_VSI_TEST_H_
+#define CONCRETE_PEAKS_PRESENTER_VSI_TEST_H_
+
+#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidDataObjects/NoShape.h"
+#include "MantidKernel/V3D.h"
+#include "MockObjects.h"
+#include <boost/shared_ptr.hpp>
+
+#include <cxxtest/TestSuite.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+
+#include <string>
+
+using namespace ::testing;
+using namespace Mantid::VATES;
+
+class MockPeakConcrete : public Mantid::DataObjects::Peak
+{
+public:
+  MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D (void));
+  MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D (void));
+  MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D (void));
+};
+
+class MockPeaksWorkspaceConcrete : public Mantid::DataObjects::PeaksWorkspace
+{
+public:
+  MOCK_CONST_METHOD0(getSpecialCoordinateSystem, Mantid::Kernel::SpecialCoordinateSystem());
+  MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum));
+  MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum));
+};
+
+class ConcretePeaksPresenterVsiTest : public CxxTest::TestSuite {
+public:
+  void testSetupPresenterCorrectly() {
+    // Arrange
+    std::string frame = "testFrame";
+    std::string name = "name";
+    
+    LeftPlane left(1.0, 0.0, 0.0, 1.0);
+
+    RightPlane right(-1.0, 0.0, 0.0, 1.0);
+    BottomPlane bottom(0.0, 1.0, 0.0, 1.0);
+    TopPlane top(0.0, -1.0, 0.0, 1.0);
+    FarPlane farPlane(0.0, 0.0, 1.0, 1.0);
+    NearPlane nearPlane(0.0, 0.0, -1.0,1.0);
+    ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane);
+
+    boost::shared_ptr<MockPeaksWorkspaceConcrete> pw_ptr(new MockPeaksWorkspaceConcrete());
+    // Act
+    ConcretePeaksPresenterVsi presenter(pw_ptr, frustum, frame);
+
+    // Assert
+    TSM_ASSERT_EQUALS("Should have recorded the frame", presenter.getFrame(), frame);
+  }
+
+  void testCorrectPeaksInfoIsExtractedForValidRow() {
+    // Arrange
+    std::string frame = "Q_SAMPLE";
+    
+    LeftPlane left(1.0, 0.0, 0.0, 1.0);
+    RightPlane right(-1.0, 0.0, 0.0, 1.0);
+    BottomPlane bottom(0.0, 1.0, 0.0, 1.0);
+    TopPlane top(0.0, -1.0, 0.0, 1.0);
+    FarPlane farPlane(0.0, 0.0, 1.0, 1.0);
+    NearPlane nearPlane(0.0, 0.0, -1.0,1.0);
+    ViewFrustum frustum(left, right, bottom, top, farPlane, nearPlane);
+
+    Mantid::Kernel::V3D coordinate(1,0,0);
+    double peakRadius = 10;
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample;
+    Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1));
+    MockPeakConcrete peak;
+    peak.setPeakShape(shape);
+    EXPECT_CALL(peak, getQLabFrame()).Times(0);
+    EXPECT_CALL(peak, getHKL()).Times(0);
+    EXPECT_CALL(peak, getQSampleFrame()).WillOnce(Return(coordinate));
+
+
+    boost::shared_ptr<MockPeaksWorkspaceConcrete> pw_ptr(new MockPeaksWorkspaceConcrete());
+    MockPeaksWorkspaceConcrete & pw = *pw_ptr;
+
+    EXPECT_CALL(pw, getSpecialCoordinateSystem()).WillOnce(Return(coordinateSystem));
+    EXPECT_CALL(pw, getPeak(_)).Times(2).WillRepeatedly(ReturnRef(peak));
+
+    // Act
+    ConcretePeaksPresenterVsi presenter(pw_ptr, frustum, frame);
+    double radius = 0;
+    Mantid::Kernel::V3D coord(0,0,0);
+    presenter.getPeaksInfo(pw_ptr,0,coord, radius);
+
+    //Assert
+    TSM_ASSERT_EQUALS("Should have a radius of 10", radius, peakRadius);
+    TSM_ASSERT_EQUALS("Should have the same coordinate", coord, coordinate);
+  }
+};
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h
index e021b3bdce6585d78c65ab72a1bf010e9a3a0a49..078c6a009b89e5af1a8214000e9abcb55928179c 100644
--- a/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h
+++ b/Code/Mantid/Vates/VatesAPI/test/MetadataJsonManagerTest.h
@@ -10,7 +10,7 @@
 #include <cxxtest/TestSuite.h>
 #include "MantidVatesAPI/MetadataJsonManager.h"
 #include <string>
-#include <jsoncpp/json/reader.h>
+#include <json/reader.h>
 
 
 using Mantid::VATES::MetadataJsonManager;
diff --git a/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h b/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..cade331b0d37876b912f35887d449bf7ac803d60
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/NullPeaksPresenterVsiTest.h
@@ -0,0 +1,39 @@
+#ifndef NULL_PEAKS_PRESENTER_VSI_TEST_H_
+#define NULL_PEAKS_PRESENTER_VSI_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidVatesAPI/NullPeaksPresenterVsi.h"
+#include "MantidKernel/V3D.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include <stdexcept>
+
+using namespace Mantid::VATES;
+
+class NullPeaksPresenterVsiTest : public CxxTest::TestSuite
+{
+public:
+  void testGettingPeaksWorkspaceThrows() {
+     NullPeaksPresenterVsi presenter;
+     TSM_ASSERT_THROWS("Should not implement this method", presenter.getPeaksWorkspace(), std::runtime_error);
+  }
+
+  void testGettingUsablePeaksThrows() {
+    NullPeaksPresenterVsi presenter;
+    TSM_ASSERT_THROWS("Should not implement this method", presenter.getViewablePeaks(), std::runtime_error);
+  }
+
+  void testGettingPeaksWorkspaceNameThrows() {
+    NullPeaksPresenterVsi presenter;
+    TSM_ASSERT_THROWS("Should not implement this method", presenter.getViewablePeaks(), std::runtime_error);
+  }
+
+  void testGettingPeaksInfoThrows() {
+    NullPeaksPresenterVsi presenter;
+    int row = 0;
+    double radius;
+    Mantid::Kernel::V3D position;
+    Mantid::API::IPeaksWorkspace_sptr peaksWorkspace;
+    TSM_ASSERT_THROWS("Should not implement this method", presenter.getPeaksInfo(peaksWorkspace,row,position,radius), std::runtime_error);
+  }
+};
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h b/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4f2357e2d4963f0fb31a93563ea840d9fd19702
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/ViewFrustumTest.h
@@ -0,0 +1,91 @@
+#ifndef VIEWFRUSTUM_TEST_H_
+#define VIEWFRUSTUM_TEST_H_
+
+#include <cxxtest/TestSuite.h>
+#include "MantidVatesAPI/ViewFrustum.h"
+
+using namespace Mantid::VATES;
+
+class ViewFrustumTest: public CxxTest::TestSuite
+{
+public:
+  void testThatExtentsAreFoundForStandardFrustum()
+  {
+    // Arrange
+    // Create a standard cube
+    LeftPlane left(1.0, 0.0, 0.0, 1.0);
+    RightPlane right(-1.0, 0.0, 0.0, 1.0);
+
+    BottomPlane bottom(0.0, 1.0, 0.0, 1.0);
+    TopPlane top(0.0, -1.0, 0.0, 1.0);
+
+    FarPlane far(0.0, 0.0, 1.0, 1.0);
+    NearPlane near(0.0, 0.0, -1.0,1.0);
+
+    ViewFrustum frustum(left, right, bottom, top, far, near);
+
+    //Act 
+    std::vector<std::pair<double, double>> extents;
+    TSM_ASSERT_THROWS_NOTHING("Frustum is well defined, should not throw.", extents = frustum.toExtents());
+
+    //Assert
+    TSM_ASSERT_EQUALS("Extents should exist for x, y and z.", 3, extents.size());
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have xmin = -1", -1.0, extents[0].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have xmax = 1", 1.0, extents[0].second);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", -1.0, extents[1].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", 1.0, extents[1].second);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have zmin = -1", -1.0, extents[2].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have zmax = 1", 1.0, extents[2].second);
+  }
+
+  void testThatExtentsAreFoundForFrustumWithRotation()
+  {
+    // Arrange
+    // Create skewed cube
+    LeftPlane left(1.0, -0.5, 0.0, 1.0);
+    RightPlane right(-1.0, 0.5, 0.0, 1.0);
+
+    BottomPlane bottom(1.0, 0.5, 0.0, 1.0);
+    TopPlane top(-1.0, -0.5, 0.0, 1.0);
+
+    FarPlane far(0.0, 0.0, 1.0, 1.0);
+    NearPlane near(0.0, 0.0, -1.0,1.0);
+
+    ViewFrustum frustum(left, right, bottom, top, far, near);
+
+    //Act 
+    std::vector<std::pair<double, double>> extents;
+    TSM_ASSERT_THROWS_NOTHING("Frustum is well defined, should not throw.", extents = frustum.toExtents());
+
+    //Assert
+    TSM_ASSERT_EQUALS("Extents should exist for x, y and z.", 3, extents.size());
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have xmin = -1", -1.0, extents[0].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have xmax = 1", 1.0, extents[0].second);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", -2.0, extents[1].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have ymin = -1", 2.0, extents[1].second);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have zmin = -1", -1.0, extents[2].first);
+    TSM_ASSERT_EQUALS("Frustum is well defined and should have zmax = 1", 1.0, extents[2].second);
+  }
+
+  void testThatWrongPlanesThrowErrors()
+  {
+    // Arrange
+    // Just have one plane type. This should fail the calculation of intersection points 
+    LeftPlane left(1.0, -0.5, 0.0, 1.0);
+    RightPlane right(1.0, -0.5, 0.0, 1.0);
+
+    BottomPlane bottom(1.0, -0.5, 0.0, 1.0);
+    TopPlane top(1.0, -0.5, 0.0, 1.0);
+
+    FarPlane far(1.0, -0.5, 0.0, 1.0);
+    NearPlane near(1.0, -0.5, 0.0, 1.0);
+
+    ViewFrustum frustum(left, right, bottom, top, far, near);
+
+    //Assert
+    TSM_ASSERT_THROWS("Frustum is not well defined, should throw error",frustum.toExtents(), std::runtime_error);
+  }
+
+};
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..1e5e1080b6b3d3330592e1eae0da3a9907ca356b
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/vtkDataSetToPeaksFilteredDataSetTest.h
@@ -0,0 +1,361 @@
+#ifndef MANTID_VATESAPI_VTKDATASETTOPEAKSFILTEREDDATASETTEST_H_
+#define MANTID_VATESAPI_VTKDATASETTOPEAKSFILTEREDDATASETTEST_H_
+
+#include "MantidTestHelpers/MDEventsTestHelper.h"
+#include "MantidVatesAPI/FieldDataToMetadata.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
+#include "MantidVatesAPI/MetadataToFieldData.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
+#include "MantidVatesAPI/NoThresholdRange.h"
+#include "MantidVatesAPI/vtkDataSetToPeaksFilteredDataSet.h"
+#include "MantidVatesAPI/vtkSplatterPlotFactory.h"
+#include "MantidVatesAPI/UserDefinedThresholdRange.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidDataObjects/PeaksWorkspace.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+#include "MantidDataObjects/PeakShapeSpherical.h"
+#include "MantidDataObjects/PeakShapeEllipsoid.h"
+#include "MantidDataObjects/NoShape.h"
+#include "MantidKernel/V3D.h"
+
+#include "MockObjects.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include <cxxtest/TestSuite.h>
+
+#include <vtkCellData.h>
+#include <vtkDataSet.h>
+#include <vtkFieldData.h>
+#include <vtkFloatArray.h>
+#include <vtkUnsignedCharArray.h>
+#include <vtkUnstructuredGrid.h>
+
+#include <boost/shared_ptr.hpp>
+
+
+using namespace Mantid::MDEvents;
+using namespace Mantid::VATES;
+using namespace ::testing;
+
+class MockPeakFilter : public Mantid::DataObjects::Peak
+{
+public:
+  MOCK_CONST_METHOD0(getHKL, Mantid::Kernel::V3D (void));
+  MOCK_CONST_METHOD0(getQLabFrame, Mantid::Kernel::V3D (void));
+  MOCK_CONST_METHOD0(getQSampleFrame, Mantid::Kernel::V3D (void));
+};
+
+class MockPeaksWorkspaceFilter : public Mantid::DataObjects::PeaksWorkspace
+{
+public:
+  MOCK_CONST_METHOD0(getNumberPeaks, int());
+  MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum));
+  MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum));
+};
+
+struct PeaksFilterDataContainer {
+  double radius;
+  double radiusFactor;
+  Mantid::Kernel::V3D position;
+};
+
+class vtkDataSetToPeaksFilteredDataSetTest : public CxxTest::TestSuite
+{
+private:
+  vtkUnstructuredGrid* makeSplatterSourceGrid()
+  {
+    FakeProgressAction progressUpdate;
+    Mantid::MDEvents::MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeMDEW<3>(10, -10.0, 10.0, 1);
+    vtkSplatterPlotFactory factory(ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    factory.initialize(ws);
+    vtkDataSet* product = NULL;
+    TS_ASSERT_THROWS_NOTHING(product = factory.create(progressUpdate));
+    vtkUnstructuredGrid* splatData =  vtkUnstructuredGrid::SafeDownCast(product);
+    return splatData;
+  }
+
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static vtkDataSetToPeaksFilteredDataSetTest *createSuite() { return new vtkDataSetToPeaksFilteredDataSetTest(); }
+  static void destroySuite( vtkDataSetToPeaksFilteredDataSetTest *suite ) { delete suite; }
+
+  void do_test_peak_inSphere(vtkPoints* points,int numberOfPoints, int& inside, int& outside, bool testingOutput, std::vector<PeaksFilterDataContainer> peakData)
+  {
+    for (int i = 0; i < numberOfPoints; i++)
+    {
+      double point[3];
+      points->GetPoint(static_cast<vtkIdType>(i), point);
+
+      bool isInSphere = false;
+      // Check if the point is any of the peaks
+      for (std::vector<PeaksFilterDataContainer>::iterator it = peakData.begin(); it != peakData.end(); ++it) {
+        double diffSquared = 0;
+        for (int k = 0; k <3; k++) {
+          diffSquared += (it->position[k]-point[k])*(it->position[k]-point[k]);
+        }
+
+        isInSphere = ((it->radius*it->radius*it->radiusFactor*it->radiusFactor - diffSquared) >= 0) ? true : false;
+        // If the point is in a sphere, stop comparing
+        if (isInSphere) {
+          break;
+        }
+      }
+
+      // Count if the point is in a sphere or not
+      isInSphere ? (inside++) : (outside++);
+
+      // We expect only for the output, that all points are within the sphere
+      if (testingOutput)
+      {
+        TSM_ASSERT("Should be insinde the sphere.", isInSphere);
+      }
+    }
+  }
+
+  void do_test_peaks(vtkUnstructuredGrid* in, vtkUnstructuredGrid* out, std::vector<PeaksFilterDataContainer> peakData)
+  {
+    vtkPoints* inPoints = in->GetPoints();
+    vtkPoints* outPoints = out->GetPoints();
+    
+    int numberOfInPoints = static_cast<int>(inPoints->GetNumberOfPoints());
+    int numberOfOutPoints = static_cast<int>(outPoints->GetNumberOfPoints());
+
+
+    int insideSphereInput = 0;
+    int outsideSphereInput = 0;
+    do_test_peak_inSphere(inPoints, numberOfInPoints, insideSphereInput , outsideSphereInput, false, peakData);
+
+    int insideSphereOutput = 0;
+    int outsideSphereOutput = 0;
+    do_test_peak_inSphere(outPoints, numberOfOutPoints, insideSphereOutput , outsideSphereOutput, true, peakData);
+
+    TSM_ASSERT("The number of elements inside the sphere should be the same for input and output.", insideSphereInput == insideSphereOutput);
+  }
+
+  void do_test_execute(vtkDataSetToPeaksFilteredDataSet peaksFilter, std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> peakWsData, Mantid::Kernel::SpecialCoordinateSystem coordinateSystem) {
+    std::vector<Mantid::API::IPeaksWorkspace_sptr> peaksContainer;
+    for (std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>>::iterator it = peakWsData.begin(); it != peakWsData.end(); ++it) {
+      // Set up the peak
+      switch(coordinateSystem)
+      {
+        case(Mantid::Kernel::SpecialCoordinateSystem::QLab):
+          EXPECT_CALL(*(it->first), getQLabFrame()).WillOnce(Return(it->second));
+          EXPECT_CALL(*(it->first), getHKL()).Times(0);
+          EXPECT_CALL(*(it->first), getQSampleFrame()).Times(0);
+          break;
+        case(Mantid::Kernel::SpecialCoordinateSystem::HKL):
+          EXPECT_CALL(*(it->first), getQLabFrame()).Times(0);
+          EXPECT_CALL(*(it->first), getHKL()).WillOnce(Return(it->second));
+          EXPECT_CALL(*(it->first), getQSampleFrame()).Times(0);
+          break;
+        case(Mantid::Kernel::SpecialCoordinateSystem::QSample):
+          EXPECT_CALL(*(it->first), getQLabFrame()).Times(0);
+          EXPECT_CALL(*(it->first), getHKL()).Times(0);
+          EXPECT_CALL(*(it->first), getQSampleFrame()).WillOnce(Return(it->second));
+          break;
+        default:
+          break;
+      }
+
+      // Set up the peaks workspace
+      boost::shared_ptr<MockPeaksWorkspaceFilter> pw_ptr(new MockPeaksWorkspaceFilter());
+      MockPeaksWorkspaceFilter & pw = *pw_ptr;
+
+      EXPECT_CALL(pw, getNumberPeaks()).Times(1).WillRepeatedly(Return(1));
+      EXPECT_CALL(pw, getPeak(_)).WillOnce(ReturnRef(*(it->first)));
+      peaksContainer.push_back(pw_ptr);
+    }
+
+    peaksFilter.initialize(peaksContainer, 0.5, 0, static_cast<int>(coordinateSystem));
+    FakeProgressAction updateProgress;
+    TSM_ASSERT_THROWS_NOTHING("Should execute regularly.", peaksFilter.execute(updateProgress));
+  }
+
+  void testThrowIfInputNull()
+  {
+    vtkUnstructuredGrid *in = NULL;
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    TS_ASSERT_THROWS(vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out), std::runtime_error);
+  }
+
+  void testThrowIfOutputNull()
+  {
+    vtkUnstructuredGrid *in = vtkUnstructuredGrid::New();
+    vtkUnstructuredGrid *out = NULL;
+    TS_ASSERT_THROWS(vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out), std::runtime_error);
+  }
+
+  void testExecThrowIfNoInit()
+  {
+    vtkUnstructuredGrid *in = vtkUnstructuredGrid::New();
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out);
+    FakeProgressAction updateProgress;
+    TS_ASSERT_THROWS(peaksFilter.execute(updateProgress), std::runtime_error);
+  }
+
+  void testExecutionWithSingleSphericalPeakInQSample()
+  {
+    // Arrange
+    vtkUnstructuredGrid *in = makeSplatterSourceGrid();
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out);
+
+    Mantid::Kernel::V3D coordinate(0,0,0);
+    // Note that the peak radius is not a 1-1 measure for which peaks will be culled and which not. 
+    // The actual radius is multiplied by the radius factor.
+    double peakRadius = 5;
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample;
+    Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1));
+    boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter());
+    peak->setPeakShape(shape);
+
+    std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces;
+    fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate));
+
+    std::vector<PeaksFilterDataContainer> peakData;
+    PeaksFilterDataContainer data1;
+    data1.position = coordinate;
+    data1.radius = peakRadius;
+    data1.radiusFactor = peaksFilter.getRadiusFactor();
+    peakData.push_back(data1);
+
+     // Act
+    do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem);
+
+    // Assert
+    do_test_peaks(in, out, peakData);
+
+    in->Delete();
+    out->Delete();
+  }
+
+  void testExecutionWithSingleEllipsoidPeakInQSample()
+  {
+    // Arrange
+    vtkUnstructuredGrid *in = makeSplatterSourceGrid();
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out);
+
+    Mantid::Kernel::V3D coordinate(0,0,0);
+    double peakRadiusMax = 7;
+    std::vector<double> radii;
+    radii.push_back(peakRadiusMax);
+    radii.push_back(6);
+    radii.push_back(5);
+
+    std::vector<Mantid::Kernel::V3D> directions;
+    directions.push_back(Mantid::Kernel::V3D(0.0,1.0,0.0));
+    directions.push_back(Mantid::Kernel::V3D(1.0,0.0,0.0));
+    directions.push_back(Mantid::Kernel::V3D(0.0,0.0,1.0));
+
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample;
+    Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeEllipsoid(directions, radii, radii, radii , coordinateSystem, "test", 1));
+    boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter());
+    peak->setPeakShape(shape);
+
+    std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces;
+    fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate));
+
+    std::vector<PeaksFilterDataContainer> peakData;
+    PeaksFilterDataContainer data1;
+    data1.position = coordinate;
+    data1.radius = peakRadiusMax;
+    data1.radiusFactor = peaksFilter.getRadiusFactor();
+    peakData.push_back(data1);
+
+     // Act
+    do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem);
+
+    // Assert
+    do_test_peaks(in, out, peakData);
+
+    in->Delete();
+    out->Delete();
+  }
+
+  void testExecutionWithSingleNoShapePeakInQSample()
+  {
+    // Arrange
+    vtkUnstructuredGrid *in = makeSplatterSourceGrid();
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out);
+
+    Mantid::Kernel::V3D coordinate(0,0,0);
+
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample;
+    double radius = peaksFilter.getRadiusNoShape();
+    Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::NoShape());
+    boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter());
+    peak->setPeakShape(shape);
+
+    std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces;
+    fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate));
+
+    std::vector<PeaksFilterDataContainer> peakData;
+    PeaksFilterDataContainer data1;
+    data1.position = coordinate;
+    data1.radius = radius;
+    data1.radiusFactor = peaksFilter.getRadiusFactor();
+    peakData.push_back(data1);
+
+    // Act
+    do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem);
+
+    // Assert
+    do_test_peaks(in, out, peakData);
+
+    in->Delete();
+    out->Delete();
+  }
+
+  void testExecutionWithTwoWorkspacesWithSingleSphericalShapesInQSample() {
+     // Arrange
+    vtkUnstructuredGrid *in = makeSplatterSourceGrid();
+    vtkUnstructuredGrid *out = vtkUnstructuredGrid::New();
+    vtkDataSetToPeaksFilteredDataSet peaksFilter(in, out);
+
+    // Peak 1
+    Mantid::Kernel::V3D coordinate(0,0,0);
+    double peakRadius = 5;
+    Mantid::Kernel::SpecialCoordinateSystem coordinateSystem = Mantid::Kernel::SpecialCoordinateSystem::QSample;
+    Mantid::Geometry::PeakShape_sptr shape(new Mantid::DataObjects::PeakShapeSpherical(peakRadius, coordinateSystem, "test", 1));
+    boost::shared_ptr<MockPeakFilter> peak(new MockPeakFilter());
+    peak->setPeakShape(shape);
+
+    // Peak 2
+    Mantid::Kernel::V3D coordinate2(12,0,0);
+    double peakRadius2 = 5;
+    Mantid::Geometry::PeakShape_sptr shape2(new Mantid::DataObjects::PeakShapeSpherical(peakRadius2, coordinateSystem, "test", 1));
+    boost::shared_ptr<MockPeakFilter> peak2(new MockPeakFilter());
+    peak2->setPeakShape(shape2);
+
+    std::vector<PeaksFilterDataContainer> peakData;
+    PeaksFilterDataContainer data1;
+    data1.position = coordinate;
+    data1.radius =peakRadius;
+    data1.radiusFactor = peaksFilter.getRadiusFactor();
+    PeaksFilterDataContainer data2;
+    data2.position = coordinate2;
+    data2.radius = peakRadius2;
+    data2.radiusFactor = peaksFilter.getRadiusFactor();
+
+    peakData.push_back(data1);
+    peakData.push_back(data2);
+
+    std::vector<std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>> fakeSinglePeakPeakWorkspaces;
+    fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak, coordinate));
+    fakeSinglePeakPeakWorkspaces.push_back(std::pair<boost::shared_ptr<MockPeakFilter>, Mantid::Kernel::V3D>(peak2, coordinate2));
+
+    // Act
+    do_test_execute(peaksFilter, fakeSinglePeakPeakWorkspaces, coordinateSystem);
+
+    // Assert
+    do_test_peaks(in, out, peakData);
+
+    in->Delete();
+    out->Delete();
+  }
+};
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..680e75fac56261dc5a70ace78b17de8a250cfc65
--- /dev/null
+++ b/Code/Mantid/Vates/VatesAPI/test/vtkEllipsoidTransformerTest.h
@@ -0,0 +1,252 @@
+#ifndef VTK_VATES_API_ELLIPSOIDTRANSFORMER_TEST
+#define VTK_VATES_API_ELLIPSOIDTRANSFORMER_TEST
+
+#include <cxxtest/TestSuite.h>
+#include "MantidVatesAPI/vtkEllipsoidTransformer.h"
+
+#include "MantidVatesAPI/vtkEllipsoidTransformer.h"
+#include "MantidKernel/V3D.h"
+
+#include "MockObjects.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <vtkTransform.h>
+#include <vtkSmartPointer.h>
+#include <vtkLineSource.h>
+#include <vtkTransformPolyDataFilter.h>
+#include <vector>
+#include <cmath>
+
+using namespace Mantid::VATES;
+
+class vtkEllipsoidTransformerTest : public CxxTest::TestSuite
+{
+public:
+  void do_test(std::vector<Mantid::Kernel::V3D> directions,
+               std::vector<std::vector<double>> majorAxis,
+               std::vector<std::vector<double>> minorAxis, 
+               std::vector<std::vector<double>> majorExpected,
+               std::vector<std::vector<double>> minorExpected)
+  {
+    // Arrange 
+    vtkSmartPointer<vtkLineSource> major =  vtkSmartPointer<vtkLineSource>::New();
+    double majorPoint1[3] = {majorAxis[0][0], majorAxis[0][1], majorAxis[0][2]};
+    double majorPoint2[3] = {majorAxis[1][0], majorAxis[1][1], majorAxis[1][2]};
+    major->SetPoint1(majorPoint1);
+    major->SetPoint2(majorPoint2);
+    major->Update();
+
+    vtkSmartPointer<vtkLineSource> minor =  vtkSmartPointer<vtkLineSource>::New();
+    double minorPoint1[3] = {minorAxis[0][0], minorAxis[0][1], minorAxis[0][2]};
+    double minorPoint2[3] = {minorAxis[1][0], minorAxis[1][1], minorAxis[1][2]};
+    minor->SetPoint1(minorPoint1);
+    minor->SetPoint2(minorPoint2);
+    minor->Update();
+    
+    // Act
+    vtkEllipsoidTransformer transformer;
+    vtkSmartPointer<vtkTransform> transform = transformer.generateTransform(directions);
+
+    vtkTransformPolyDataFilter* transformFilter = vtkTransformPolyDataFilter::New();
+
+    transformFilter->SetTransform(transform);
+    transformFilter->SetInputConnection(major->GetOutputPort());
+    transformFilter->Update();
+    vtkPolyData* out = transformFilter->GetOutput();
+    
+    double majorPoint1Rotated[3] = {0.0,0.0,0.0};
+    double majorPoint2Rotated[3] = {0.0,0.0,0.0};
+    out->GetPoint(0, majorPoint1Rotated);
+    out->GetPoint(1, majorPoint2Rotated);
+
+    transformFilter->SetInputConnection(minor->GetOutputPort());
+    transformFilter->Update();
+    out = transformFilter->GetOutput();
+    double minorPoint1Rotated[3] = {0.0,0.0,0.0};
+    double minorPoint2Rotated[3] = {0.0,0.0,0.0};
+    out->GetPoint(0, minorPoint1Rotated);
+    out->GetPoint(1, minorPoint2Rotated);
+    
+    // Assert
+    const double delta = 1e-5;
+
+    TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[0], majorExpected[0][0], delta);
+    TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[1], majorExpected[0][1], delta);
+    TSM_ASSERT_DELTA("Point 1 of the major axis should not change", majorPoint1Rotated[2], majorExpected[0][2], delta);
+    
+    TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[0], majorExpected[1][0], delta);
+    TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[1], majorExpected[1][1], delta);
+    TSM_ASSERT_DELTA("Point 2 of the major axis should have changed", majorPoint2Rotated[2], majorExpected[1][2], delta);
+
+    TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[0], minorExpected[0][0], delta);
+    TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[1], minorExpected[0][1], delta);
+    TSM_ASSERT_DELTA("Point 1 of the minor axis should not change", minorPoint1Rotated[2], minorExpected[0][2], delta);
+
+    TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[0], minorExpected[1][0], delta);
+    TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[1], minorExpected[1][1], delta);
+    TSM_ASSERT_DELTA("Point 2 of the minor axis should have changed", minorPoint2Rotated[2], minorExpected[1][2], delta);
+  }
+
+  void testGenerateTransformTiltedByNinetyDegrees()
+  {
+    // Arrange
+    Mantid::Kernel::V3D axis1(0.0,1.0,0.0);
+    Mantid::Kernel::V3D axis2(-1.0,0.0,0.0);
+    Mantid::Kernel::V3D axis3(0.0,0.0,1.0);
+
+    std::vector<Mantid::Kernel::V3D> directions;
+    directions.push_back(axis1);
+    directions.push_back(axis2);
+    directions.push_back(axis3);
+
+    // Major Axis 
+    std::vector<double> point1Major;
+    point1Major.push_back(0.0);
+    point1Major.push_back(0.0);
+    point1Major.push_back(0.0);
+
+    std::vector<double> point2Major;
+    point2Major.push_back(1.0);
+    point2Major.push_back(0.0);
+    point2Major.push_back(0.0);
+
+    std::vector<std::vector<double>> major;
+    major.push_back(point1Major);
+    major.push_back(point2Major);
+
+    // Minor Axis
+    std::vector<double> point1Minor;
+    point1Minor.push_back(0.0);
+    point1Minor.push_back(0.0);
+    point1Minor.push_back(0.0);
+
+    std::vector<double> point2Minor;
+    point2Minor.push_back(0.0);
+    point2Minor.push_back(1.0);
+    point2Minor.push_back(0.0);
+
+    std::vector<std::vector<double>> minor;
+    minor.push_back(point1Minor);
+    minor.push_back(point2Minor);
+    
+    std::vector<double> point1MajorExpected;
+    point1MajorExpected.push_back(0.0);
+    point1MajorExpected.push_back(0.0);
+    point1MajorExpected.push_back(0.0);
+    
+    std::vector<double> point2MajorExpected;
+    point2MajorExpected.push_back(0.0);
+    point2MajorExpected.push_back(1.0);
+    point2MajorExpected.push_back(0.0);
+
+    std::vector<std::vector<double>> majorExpected;
+    majorExpected.push_back(point1MajorExpected);
+    majorExpected.push_back(point2MajorExpected);
+
+    // Minor Axis
+    std::vector<double> point1MinorExpected;
+    point1MinorExpected.push_back(0.0);
+    point1MinorExpected.push_back(0.0);
+    point1MinorExpected.push_back(0.0);
+
+    std::vector<double> point2MinorExpected;
+    point2MinorExpected.push_back(-1.0);
+    point2MinorExpected.push_back(0.0);
+    point2MinorExpected.push_back(0.0);
+
+    std::vector<std::vector<double>> minorExpected;
+    minorExpected.push_back(point1MinorExpected);
+    minorExpected.push_back(point2MinorExpected);
+
+    // Act + Assert
+    do_test(directions, major, minor, majorExpected, minorExpected);
+  }
+
+  void testGenerateTransformInRandomDirection()
+  {
+    // Arrange
+    double xMajor = 1.3/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5);
+    double yMajor = -1.1/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5);
+    double zMajor = 0.5/sqrt(1.3*1.3 + 1.1*1.1 + 0.5*0.5);
+
+    double xMinor = 1.1/1.3/sqrt(1*1 + (1.1/1.3)*(1.1/1.3));
+    double yMinor = 1.0/sqrt(1*1 + (1.1/1.3)*(1.1/1.3));
+    double zMinor = 0.0;
+
+    Mantid::Kernel::V3D axis1(xMajor, yMajor, zMajor);
+    Mantid::Kernel::V3D axis2(xMinor,yMinor, zMinor);
+    // The third direction is not valid, but we don't need it for our calculations.
+    Mantid::Kernel::V3D axis3(0.0,0.0,1.0); 
+
+    std::vector<Mantid::Kernel::V3D> directions;
+    directions.push_back(axis1);
+    directions.push_back(axis2);
+    directions.push_back(axis3);
+
+    // Major Axis 
+    std::vector<double> point1Major;
+    point1Major.push_back(0.0);
+    point1Major.push_back(0.0);
+    point1Major.push_back(0.0);
+
+    std::vector<double> point2Major;
+    point2Major.push_back(1.0);
+    point2Major.push_back(0.0);
+    point2Major.push_back(0.0);
+
+    std::vector<std::vector<double>> major;
+    major.push_back(point1Major);
+    major.push_back(point2Major);
+
+    // Minor Axis
+    std::vector<double> point1Minor;
+    point1Minor.push_back(0.0);
+    point1Minor.push_back(0.0);
+    point1Minor.push_back(0.0);
+
+    std::vector<double> point2Minor;
+    point2Minor.push_back(0.0);
+    point2Minor.push_back(1.0);
+    point2Minor.push_back(0.0);
+
+    std::vector<std::vector<double>> minor;
+    minor.push_back(point1Minor);
+    minor.push_back(point2Minor);
+    
+    std::vector<double> point1MajorExpected;
+    point1MajorExpected.push_back(0.0);
+    point1MajorExpected.push_back(0.0);
+    point1MajorExpected.push_back(0.0);
+    
+    std::vector<double> point2MajorExpected;
+    point2MajorExpected.push_back(xMajor);
+    point2MajorExpected.push_back(yMajor);
+    point2MajorExpected.push_back(zMajor);
+
+    std::vector<std::vector<double>> majorExpected;
+    majorExpected.push_back(point1MajorExpected);
+    majorExpected.push_back(point2MajorExpected);
+
+    // Minor Axis
+    std::vector<double> point1MinorExpected;
+    point1MinorExpected.push_back(0.0);
+    point1MinorExpected.push_back(0.0);
+    point1MinorExpected.push_back(0.0);
+
+    std::vector<double> point2MinorExpected;
+    point2MinorExpected.push_back(xMinor);
+    point2MinorExpected.push_back(yMinor);
+    point2MinorExpected.push_back(zMinor);
+
+    std::vector<std::vector<double>> minorExpected;
+    minorExpected.push_back(point1MinorExpected);
+    minorExpected.push_back(point2MinorExpected);
+
+    // Act + Assert
+    do_test(directions, major, minor, majorExpected, minorExpected);
+  }
+};
+
+
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h
index 78406aba6e0e017bfdfe1c912e2f9c59dca87979..f71d3cd86a481c50d3ec3bf8d02bbf20381fc6ff 100644
--- a/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h
+++ b/Code/Mantid/Vates/VatesAPI/test/vtkPeakMarkerFactoryTest.h
@@ -5,6 +5,9 @@
 #include "MantidDataObjects/PeaksWorkspace.h"
 #include "MantidVatesAPI/vtkPeakMarkerFactory.h"
 #include "MockObjects.h"
+
+#include <vtkPolyData.h>
+
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
@@ -29,14 +32,13 @@ class MockPeaksWorkspace : public PeaksWorkspace
 {
 public:
   MOCK_METHOD1(setInstrument, void (Mantid::Geometry::Instrument_const_sptr inst));
-  MOCK_CONST_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ());
+  //MOCK_METHOD0(getInstrument, Mantid::Geometry::Instrument_const_sptr ());
   MOCK_CONST_METHOD0(clone, Mantid::DataObjects::PeaksWorkspace*());
   MOCK_CONST_METHOD0(getNumberPeaks, int());
   MOCK_METHOD1(removePeak, void (int peakNum) );
   MOCK_METHOD1(addPeak, void (const IPeak& ipeak));
   MOCK_METHOD1(getPeak, Mantid::DataObjects::Peak & (int peakNum));
   MOCK_CONST_METHOD1(getPeak, const Mantid::DataObjects::Peak & (int peakNum));
-  MOCK_CONST_METHOD2(createPeak, Mantid::API::IPeak* (Mantid::Kernel::V3D QLabFrame, boost::optional<double> detectorDistance));
 };
 
 //=====================================================================================
@@ -59,12 +61,13 @@ public:
 
     vtkPeakMarkerFactory factory("signal", dims);
     factory.initialize(pw_ptr);
-    vtkDataSet * set = factory.create(updateProgress);
+    vtkPolyData * set = factory.create(updateProgress);
+
+    // As the marker type are three axes(2 points), we expect 5*2*3 points
+    // The angle is 45degrees and the size is 0.3
+
     TS_ASSERT(set);
-    TS_ASSERT_EQUALS( set->GetNumberOfPoints(), 5);
-    TS_ASSERT_EQUALS(set->GetPoint(0)[0], 1.0);
-    TS_ASSERT_EQUALS(set->GetPoint(0)[1], 2.0);
-    TS_ASSERT_EQUALS(set->GetPoint(0)[2], 3.0);
+    TS_ASSERT_EQUALS(set->GetNumberOfPoints(), 30);
 
     TS_ASSERT(testing::Mock::VerifyAndClearExpectations(&pw));
     TS_ASSERT(testing::Mock::VerifyAndClearExpectations(&peak1));
@@ -91,11 +94,10 @@ public:
 
     vtkPeakMarkerFactory factory("signal", vtkPeakMarkerFactory::Peak_in_Q_lab);
     factory.initialize(pw_ptr);
-    vtkDataSet * set = factory.create(mockProgress);
+    vtkPolyData * set = factory.create(mockProgress);
     set->Delete();
 
     TSM_ASSERT("Progress Updates not used as expected.", Mock::VerifyAndClearExpectations(&mockProgress));
-
   }
 
   void test_q_lab()
diff --git a/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h b/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
index 58c4a57432c29fdeccf056faf9971c1d8bb65975..ac5e17b344fdee8bd8d0a8ddfdfdd996386b85a2 100644
--- a/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
+++ b/Code/Mantid/Vates/VatesAPI/test/vtkSplatterPlotFactoryTest.h
@@ -8,6 +8,10 @@
 #include "MantidTestHelpers/MDEventsTestHelper.h"
 #include "MantidVatesAPI/UserDefinedThresholdRange.h"
 #include "MantidVatesAPI/vtkSplatterPlotFactory.h"
+#include "MantidVatesAPI/MetadataToFieldData.h"
+#include "MantidVatesAPI/FieldDataToMetadata.h"
+#include "MantidVatesAPI/VatesConfigurations.h"
+#include "MantidVatesAPI/MetadataJsonManager.h"
 #include "MockObjects.h"
 #include <cxxtest/TestSuite.h>
 #include <gmock/gmock.h>
@@ -161,6 +165,45 @@ public:
     product->Delete();
   }
 
+  void test_MetadataIsAddedCorrectly() 
+  {
+    // Arrange 
+    vtkFieldData* fakeInputFieldDataWithXML = vtkFieldData::New();
+    std::string xmlString = "myXmlString";
+    MetadataToFieldData converterMtoF;
+    converterMtoF(fakeInputFieldDataWithXML, xmlString, XMLDefinitions::metaDataId().c_str());
+
+
+    FakeProgressAction progressUpdate;
+    Mantid::MDEvents::MDEventWorkspace3Lean::sptr ws = MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1);
+    vtkSplatterPlotFactory factory(ThresholdRange_scptr(new UserDefinedThresholdRange(0, 1)), "signal");
+    factory.initialize(ws);
+    vtkDataSet* product = NULL;
+
+    // Act
+    TS_ASSERT_THROWS_NOTHING(product = factory.create(progressUpdate));
+    TS_ASSERT_THROWS_NOTHING(factory.setMetadata(fakeInputFieldDataWithXML, product));
+
+    // Assert
+    FieldDataToMetadata converterFtoM;
+    vtkFieldData* fd = product->GetFieldData();
+    std::string xmlOut; 
+    std::string jsonOut;
+    VatesConfigurations vatesConfigurations;
+
+    TSM_ASSERT_EQUALS("One array expected on field data, one for XML and one for JSON!", 2, product->GetFieldData()->GetNumberOfArrays());
+
+    TSM_ASSERT_THROWS_NOTHING("There is XML metadata!", xmlOut = converterFtoM(fd, XMLDefinitions::metaDataId().c_str()));
+    TSM_ASSERT_THROWS_NOTHING("There is JSON metadata!", jsonOut = converterFtoM(fd, vatesConfigurations.getMetadataIdJson().c_str()));
+
+    TSM_ASSERT("The xml string should be retrieved", xmlOut == xmlString);
+
+    MetadataJsonManager manager;
+    manager.readInSerializedJson(jsonOut);
+    TSM_ASSERT("The instrument should be empty", manager.getInstrument().empty());
+    TSM_ASSERT_EQUALS("The max value is 1", 1.0, manager.getMaxValue());
+    TSM_ASSERT_EQUALS("The min value is 1", 1.0, manager.getMinValue());
+  }
 };
 
 #endif
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt
index 01b95a20f3fdaf8d840e1787b714a72f4f8490b0..278a8015e40de9a2a2b631f9d86a845a854ea999 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/CMakeLists.txt
@@ -3,6 +3,7 @@ project( MantidVatesSimpleGuiViewWidgets )
 # These are the C++ files to be compiled.
 set( INCLUDE_FILES
   inc/MantidVatesSimpleGuiViewWidgets/AutoScaleRangeGenerator.h
+  inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h
   inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h
   inc/MantidVatesSimpleGuiViewWidgets/ColorMapManager.h
   inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h
@@ -11,6 +12,9 @@ set( INCLUDE_FILES
   inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
   inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h
   inc/MantidVatesSimpleGuiViewWidgets/RebinAlgorithmDialogProvider.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h
   inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h
   inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h
   inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
@@ -23,6 +27,7 @@ set( INCLUDE_FILES
 
 set( SOURCE_FILES
   src/AutoScaleRangeGenerator.cpp
+  src/CameraManager.cpp
   src/BackgroundRgbProvider.cpp
   src/ColorMapManager.cpp
   src/ColorSelectionWidget.cpp
@@ -30,6 +35,9 @@ set( SOURCE_FILES
   src/MdViewerWidget.cpp
   src/MultisliceView.cpp
   src/RebinAlgorithmDialogProvider.cpp
+  src/PeaksTableControllerVsi.cpp
+  src/PeaksTabWidget.cpp
+  src/PeaksWidget.cpp
   src/SaveScreenshotReaction.cpp
   src/RebinnedSourcesManager.cpp
   src/StandardView.cpp
@@ -49,6 +57,9 @@ qt4_wrap_cpp( MOC_SOURCES
   inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.h
   inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
   inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h
   inc/MantidVatesSimpleGuiViewWidgets/SaveScreenshotReaction.h
   inc/MantidVatesSimpleGuiViewWidgets/RebinnedSourcesManager.h
   inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
@@ -64,6 +75,8 @@ qt4_wrap_ui( UI_BUILT_SOURCES
   inc/MantidVatesSimpleGuiViewWidgets/ColorSelectionWidget.ui
   inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.ui
   inc/MantidVatesSimpleGuiViewWidgets/MultisliceView.ui
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui
+  inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui
   inc/MantidVatesSimpleGuiViewWidgets/StandardView.ui
   inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui
   inc/MantidVatesSimpleGuiViewWidgets/ThreesliceView.ui
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h
index 4aa78d305fba7a059e364a459b93e36e76b09715..387ea81f8f73b6827082d810029032f1015452d9 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/BackgroundRgbProvider.h
@@ -95,9 +95,9 @@ namespace Mantid
           /**
            * Callback function for background color changing events
            *@param caller Calling object.
-           *@param eventId Not used.
-           *@param clientData Not used.
-           *@parma callData Not used.
+           *@param vtkNotUsed(eventId) Not used.
+           *@param vtkNotUsed(clientData) Not used.
+           *@param vtkNotUsed(callData) Not used.
            */
           static void backgroundColorChangeCallbackFunction(vtkObject* caller, long unsigned int vtkNotUsed(eventId), void* vtkNotUsed(clientData), void* vtkNotUsed(callData));
 
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f0c5f9cdba1f3738e983b1ec7b3e91e874db78e
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/CameraManager.h
@@ -0,0 +1,57 @@
+#ifndef CAMERAMANAGER_H_
+#define CAMERAMANAGER_H_
+
+#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+
+
+/**
+ *
+  This class handles the camera of the view.
+
+  @date 14/1/2015
+
+  Copyright &copy; 2011 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_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS CameraManager
+{
+public:
+  CameraManager();
+
+  ~CameraManager();
+  
+  Mantid::VATES::ViewFrustum getCurrentViewFrustum();
+
+  void setCameraToPeak(double xpos, double ypos, double zpos, double peakRadius);
+};
+
+}
+}
+}
+
+#endif 
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
index e24689aaecb588e58c90bdfad6cae19f1cb8bd2b..fcd8880ecfd02421d393af3a07effee553fef3bc 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/MdViewerWidget.h
@@ -199,8 +199,6 @@ private:
   void resetCurrentView(int workspaceType, const std::string& instrumentName);
   /// Render rebinned workspace
   void prepareRebinnedWorkspace(const std::string rebinnedWorkspaceName, std::string sourceType); 
-  /// Set visibility listener
-  void setVisibilityListener();
   /// Handle drag and drop of peaks workspcaes
   void handleDragAndDropPeaksWorkspaces(QEvent* e, QString text, QStringList& wsNames);
   /// Set up the default color for the background of the view.
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..f24b54f7321f053936c870d08da15e3d837b6334
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h
@@ -0,0 +1,47 @@
+#ifndef VSI_PEAKSTABWIDGET_H
+#define VSI_PEAKSTABWIDGET_H
+
+#include "ui_PeaksTabWidget.h"
+#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+
+#include <QWidget>
+#include <string>
+#include <vector>
+#include <map>
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+  class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksTabWidget : public QWidget
+  {
+    Q_OBJECT
+  public:
+    PeaksTabWidget(std::vector<Mantid::API::IPeaksWorkspace_sptr> ws, const std::string& coordinateSystem, QWidget *parent = 0);
+    ~PeaksTabWidget();
+    void setupMvc(std::map<std::string, std::vector<bool>> visiblePeaks);
+    void addNewPeaksWorkspace(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::vector<bool> visiblePeaks);
+    void updateTabs(std::map<std::string, std::vector<bool>> visiblePeaks);
+  signals:
+    void zoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row);
+  public slots:
+    void onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row);
+  private:
+    /// Update a certain tab.
+    void updateTab(std::vector<bool> visiblePeaks, int index);
+    /// Adds a new tab to the tab widget.
+    void addNewTab(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::string tabName, std::vector<bool> visiblePeaks);
+    /// Auto-generated UI controls.
+    Ui::PeaksTabWidget ui;
+    /// Peaks workspace to view.
+    std::vector<Mantid::API::IPeaksWorkspace_sptr> m_ws;
+    /// Coordinate system.
+    const std::string m_coordinateSystem;
+  };
+} //namespace
+}
+}
+#endif // PEAKSWORKSPACEWIDGET_H
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..85322c8384fa453a252cee3b9c72adbdd56d91f9
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.ui
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PeaksTabWidget</class>
+ <widget class="QWidget" name="PeaksTabWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>200</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2" stretch="0">
+   <property name="spacing">
+    <number>0</number>
+   </property>
+   <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>
+    <layout class="QHBoxLayout" name="tabLayout">
+     <property name="spacing">
+      <number>0</number>
+     </property>
+     <item>
+      <widget class="QTabWidget" name="tabWidget">
+       <property name="currentIndex">
+        <number>-1</number>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..aaaac0a728ec97da188f75c2b24cb576e543b130
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h
@@ -0,0 +1,62 @@
+#ifndef PeaksTableControllerVSI_H_
+#define PeaksTableControllerVSI_H_
+
+#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h"
+#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h"
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h"
+#include "MantidVatesAPI/CompositePeaksPresenterVsi.h"
+#include "MantidAPI/PeakTransformSelector.h"
+#include "MantidGeometry/Crystal/PeakShape.h"
+
+#include <QWidget>
+#include <QPointer>
+#include <boost/shared_ptr.hpp>
+
+class pqPipelineSource;
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksTableControllerVsi : public QWidget
+{
+  Q_OBJECT
+public:
+  PeaksTableControllerVsi(boost::shared_ptr<CameraManager> cameraManager, QWidget *parent=0);
+  ~PeaksTableControllerVsi();
+  std::vector<bool> getViewablePeaks();
+  bool hasPeaks();
+  void showFullTable();
+  void removeTable();
+  std::string getConcatenatedWorkspaceNames(std::string delimiter);
+  void updatePeaksWorkspaces(QList<QPointer<pqPipelineSource>> peakSources, pqPipelineSource* splatSource);
+signals:
+  void setRotationToPoint(double x, double y, double z);
+public slots:
+  void updateViewableArea();
+  void onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row);
+  void destroySinglePeakSource();
+  void onPeakMarkerDestroyed();
+private:
+  void addWorkspace(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource);
+  std::vector<std::string> extractFrameFromSource(QPointer<pqPipelineSource> splatSource);
+  void generateSinglePeaksSource(double position1, double position2, double position3, double radius);
+  void resetSinglePeaksSource(double position1, double position2, double position3, double radius);
+  bool checkMatchingSources(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource);
+  double getMaxRadius(Mantid::Geometry::PeakShape_sptr shape);
+  void removeLayout(QWidget *widget);
+  void createTable(bool full);
+  boost::shared_ptr<CameraManager> m_cameraManager;
+  boost::shared_ptr<Mantid::VATES::CompositePeaksPresenterVsi> m_presenter;
+  /// Object for choosing a PeakTransformFactory based on the workspace type.
+  Mantid::API::PeakTransformSelector m_peakTransformSelector;
+  PeaksTabWidget* m_peaksTabWidget;
+  pqPipelineSource* m_peakMarker;
+};
+
+}
+}
+}
+#endif
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ef643246e1011c9c5d7b4046a7e5f664992070d
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.h
@@ -0,0 +1,44 @@
+#ifndef VSI_PEAKSWORKWIDGET_H
+#define VSI_PEAKSWORKWIDGET_H
+
+#include "ui_PeaksWidget.h"
+#include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+
+#include <QWidget>
+#include <string>
+#include <vector>
+#include <map>
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+  class EXPORT_OPT_MANTIDVATES_SIMPLEGUI_VIEWWIDGETS PeaksWidget : public QWidget
+  {
+    Q_OBJECT
+  public:
+    PeaksWidget(Mantid::API::IPeaksWorkspace_sptr ws, const std::string& coordinateSystem, QWidget *parent = 0);
+    void setupMvc(std::vector<bool> visiblePeaks);
+    void updateModel(std::vector<bool> visiblePeaks);
+  signals:
+    void zoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row);
+  public slots:
+    void onCurrentChanged(QModelIndex current, QModelIndex);
+  private:
+    /// Auto-generated UI controls.
+    Ui::PeaksWidget ui;
+    /// Peaks workspace to view.
+    Mantid::API::IPeaksWorkspace_sptr m_ws;
+    /// Coordinate system.
+    const std::string m_coordinateSystem;
+    /// Table width
+    int m_originalTableWidth;
+  };
+
+} //namespace
+}
+}
+#endif // PEAKSWORKSPACEWIDGET_H
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui
new file mode 100644
index 0000000000000000000000000000000000000000..4c1aa03e838cf079f246280a4f6244571f3b2088
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/PeaksWidget.ui
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>PeaksWidget</class>
+ <widget class="QWidget" name="PeaksWidget">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>474</width>
+    <height>156</height>
+   </rect>
+  </property>
+  <property name="sizePolicy">
+   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+    <horstretch>0</horstretch>
+    <verstretch>0</verstretch>
+   </sizepolicy>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>16777215</width>
+    <height>16777215</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2" stretch="1">
+   <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>
+    <layout class="QHBoxLayout" name="tableLayout">
+     <item>
+      <widget class="QTableView" name="tblPeaks">
+       <property name="enabled">
+        <bool>true</bool>
+       </property>
+       <property name="frameShape">
+        <enum>QFrame::StyledPanel</enum>
+       </property>
+       <property name="autoScrollMargin">
+        <number>7</number>
+       </property>
+       <property name="alternatingRowColors">
+        <bool>true</bool>
+       </property>
+       <property name="selectionMode">
+        <enum>QAbstractItemView::SingleSelection</enum>
+       </property>
+       <property name="selectionBehavior">
+        <enum>QAbstractItemView::SelectRows</enum>
+       </property>
+       <property name="sortingEnabled">
+        <bool>true</bool>
+       </property>
+       <attribute name="horizontalHeaderStretchLastSection">
+        <bool>true</bool>
+       </attribute>
+       <attribute name="verticalHeaderVisible">
+        <bool>false</bool>
+       </attribute>
+       <attribute name="verticalHeaderStretchLastSection">
+        <bool>false</bool>
+       </attribute>
+      </widget>
+     </item>
+    </layout>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h
index 7c44cfcb49acc6735f4c76346e95b89f96937a03..22312e91fa9e9ef8b2c5dc4db1e215db51e7a1e6 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h
@@ -4,11 +4,16 @@
 #include "ui_SplatterPlotView.h"
 #include "MantidVatesSimpleGuiViewWidgets/ViewBase.h"
 #include "MantidVatesSimpleGuiViewWidgets/WidgetDllOption.h"
+#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h"
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h"
+#include <boost/shared_ptr.hpp>
 
+#include <string>
 #include <QList>
 #include <QPointer>
 
 class QWidget;
+class QAction;
 
 class pqPipelineRepresentation;
 class pqPipelineSource;
@@ -85,6 +90,10 @@ public:
    * ViewBase::resetDisplay()
    */
   void resetDisplay();
+  /**
+   * Destroy all sources in the view. 
+   */
+  virtual void destroyAllSourcesInView();
 
 signals:
   /// Reset to the Standard View
@@ -95,8 +104,10 @@ signals:
 public slots:
   /// Check the coordinates for the peaks overlay if necessary
   void checkPeaksCoordinates();
-  /// Listen to destruction of peak sources
-  void onPeakSourceDestroyed();
+  /// Remove the visible peaks table.
+  void onRemovePeaksTable();
+  /// Show all peaks in table.
+  void onShowAllPeaksTable();
 
 protected slots:
   /// Check state of toggle button with respect to peak coordinates.
@@ -107,6 +118,10 @@ protected slots:
    * Create and apply a threshold filter to the data.
    */
   void onThresholdButtonClicked();
+  /// On peaks filter destroyed
+  void onPeaksFilterDestroyed();
+  /// On peaks source destroyed
+  void onPeakSourceDestroyed();
 
 private:
   Q_DISABLE_COPY(SplatterPlotView)
@@ -119,6 +134,20 @@ private:
   bool eventFilter(QObject *obj, QEvent *ev);
   /// Read the coordinates and send to service.
   void readAndSendCoordinates();
+  /// Setup the buttons for the visible peaks
+  void setupVisiblePeaksButtons();
+  /// Create the peaks filter
+  void createPeaksFilter();
+  /// Set the state of the peak button
+  void setPeakButton(bool state);
+  /// Set the frame for the peaks
+  void setPeakSourceFrame(pqPipelineSource* source);
+  /// Check if a peaks workspace is already part of the recorded peaks sources.
+  bool checkIfPeaksWorkspaceIsAlreadyBeingTracked(pqPipelineSource* source);
+  /// Update the peaks filter
+  void updatePeaksFilter(pqPipelineSource* filter);
+  /// Destroy splatter plot specific sources and filters
+  void destroyFiltersForSplatterPlotView();
 
   bool noOverlay; ///< Flag to respond to overlay situation correctly
   QList<QPointer<pqPipelineSource> > peaksSource; ///< A list of peaks sources
@@ -126,8 +155,14 @@ private:
   QPointer<pqPipelineRepresentation> splatRepr; ///< The splatter plot representation
   QPointer<pqPipelineSource> splatSource; ///< The splatter plot source
   QPointer<pqPipelineSource> threshSource; ///< The thresholding filter source
+  QPointer<pqPipelineSource> m_peaksFilter; ///< The peaks filter
   Ui::SplatterPlotView ui; ///< The splatter plot view'a UI form
   QPointer<pqRenderView> view; ///< The main view area
+  boost::shared_ptr<CameraManager> m_cameraManager; ///< The camera manager
+  PeaksTableControllerVsi* m_peaksTableController; ///< The peaks table controller
+  QAction* m_allPeaksAction;///<The action for showing all peaks in the table.
+  QAction* m_removePeaksAction; ///<The action for removing the peaks table.
+  std::string m_peaksWorkspaceNameDelimiter;///<Delimiter for peaks workspace strings.
 };
 
 } // SimpleGui
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui
index d7b47a221a77f5d58bd8f8cdc523872f972a9e9a..49505fefb1c0d8addbb296cd4a0026556a0c41b1 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/SplatterPlotView.ui
@@ -14,6 +14,15 @@
    <string>Form</string>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
+   <property name="leftMargin">
+    <number>9</number>
+   </property>
+   <property name="rightMargin">
+    <number>9</number>
+   </property>
+   <property name="bottomMargin">
+    <number>9</number>
+   </property>
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
@@ -59,6 +68,28 @@
        </property>
       </widget>
      </item>
+     <item>
+      <widget class="QToolButton" name="peaksButton">
+       <property name="minimumSize">
+        <size>
+         <width>75</width>
+         <height>23</height>
+        </size>
+       </property>
+       <property name="baseSize">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+       <property name="text">
+        <string>Peaks</string>
+       </property>
+       <property name="arrowType">
+        <enum>Qt::NoArrow</enum>
+       </property>
+      </widget>
+     </item>
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
index 403df62c7576e76049cac09f4c0393eb8f2a61e3..4dee0413a3c6797aef47595c0f78f483773af357 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/StandardView.h
@@ -91,8 +91,6 @@ protected slots:
   void onBinMD();
   /// On SliceMD button clicked
   void onSliceMD();
-  /// On CutMD button clicked
-  void onCutMD();
 
 private:
   Q_DISABLE_COPY(StandardView)
@@ -109,7 +107,6 @@ private:
 
   QAction* m_binMDAction;
   QAction* m_sliceMDAction;
-  QAction* m_cutMDAction;
   QAction* m_unbinAction;
 };
 
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h
index 51a5607306f8fff67990f7d076d6b386c8f26b58..93ce9a1c73b272875bf8a520b493c812a2b33027 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/inc/MantidVatesSimpleGuiViewWidgets/ViewBase.h
@@ -129,6 +129,14 @@ public:
   enum Direction {X, Y, Z};
   /// Update settings
   virtual void updateSettings();
+  // Destroy all sources in the view.
+  virtual void destroyAllSourcesInView();
+  // Destroy all sources in a single linear pipeline.
+  virtual void destroySinglePipeline(pqPipelineSource * source);
+   /// Set visibility listener
+  void setVisibilityListener();
+  /// Undo visibiltiy listener
+  void removeVisibilityListener();
 
   QPointer<pqPipelineSource> origSrc; ///< The original source
   QPointer<pqPipelineRepresentation> origRep; ///< The original source representation
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp
index 82101590b1bed5c5d0cd7612591385fc84f5ac89..b82e74ce8f4de0ea46f8052eb9ab006c0096139f 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/AutoScaleRangeGenerator.cpp
@@ -165,6 +165,13 @@ namespace SimpleGui
     // Set the color scale output
     VsiColorScale vsiColorScale;
 
+    // If either the min or max value are at the end of the double spectrum, we might only have a peak Ws visible, 
+    // we need to hedge for that
+    if (minValue == DBL_MAX || maxValue == -DBL_MAX) {
+      minValue = defaultValue;
+      maxValue = defaultValue;
+    }
+
     // Account for possible negative data. If min value is negative and max value is larger than 100, then set to default
     // else set to three orders of magnitude smaller than the max value
     if (minValue < 0 && maxValue > 100)
@@ -201,7 +208,9 @@ namespace SimpleGui
     // Check if source is custom filter
     if (QString(proxy->GetXMLName()).contains("MantidParaViewScaleWorkspace") ||
         QString(proxy->GetXMLName()).contains("MDEWRebinningCutter") ||
-        QString(proxy->GetXMLName()).contains("MantidParaViewSplatterPlot"))
+        QString(proxy->GetXMLName()).contains("MantidParaViewSplatterPlot") ||
+        QString(proxy->GetXMLName()).contains("MantidParaViewPeaksFilter"))
+
     {
       minValue = vtkSMPropertyHelper(proxy,"MinValue").GetAsDouble();
       maxValue = vtkSMPropertyHelper(proxy,"MaxValue").GetAsDouble();
@@ -220,7 +229,8 @@ namespace SimpleGui
     }
 
     // Check if Peak Workspace. This workspace should not contribute to colorscale
-    if (QString(proxy->GetXMLName()).contains("Peaks Source"))
+    if (QString(proxy->GetXMLName()).contains("Peaks Source") ||
+        QString(proxy->GetXMLName()).contains("SinglePeakMarkerSource"))
     {
       minValue = DBL_MAX;
       maxValue = -DBL_MAX;
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..74010d9a7049d985c60b7d10daac9f4cf9d1215d
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/CameraManager.cpp
@@ -0,0 +1,143 @@
+#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include <stdexcept>
+// Have to deal with ParaView warnings and Intel compiler the hard way.
+#if defined(__INTEL_COMPILER)
+  #pragma warning disable 1170
+#endif
+
+#include <pqView.h>
+#include <pqActiveView.h>
+#include <vtkSMRenderViewProxy.h>
+#include <vtkCamera.h>
+#include <vtkRenderer.h>
+#include <vtkRenderWindow.h>
+
+namespace Mantid
+{
+  namespace Vates
+  {
+    namespace SimpleGui
+    {
+      CameraManager::CameraManager()
+      {
+      }
+
+      CameraManager::~CameraManager()
+      {
+      }
+      /**
+       * Get the plane equation for the view frustum.
+       * @param left The left plane.
+       * @param right The right plane.
+       * @param bottom The bottom plane.
+       * @param top The top plane.
+       * @param far The far plane.
+       * @param near The near plane.
+       */
+      Mantid::VATES::ViewFrustum CameraManager::getCurrentViewFrustum()
+      {
+        double left[4];
+        double right[4];
+        double bottom[4];
+        double top[4];
+        double far[4];
+        double near[4];
+
+        pqView * view = pqActiveView::instance().current();
+
+        vtkSMRenderViewProxy* proxy = NULL;
+
+        if (view)
+        {
+          proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy());
+        }
+
+        if (!proxy)
+        {
+          // no active view, or active view is not a render view.
+          throw std::invalid_argument("Invalid vtkSMRenderViewProxy.");
+        }
+
+        // Get the aspect ratio of the renderer
+        vtkRenderer* renderer = proxy->GetRenderer();
+        if (!renderer)
+        {
+          throw std::invalid_argument("Invalid vtkRenderer.");
+        }
+
+        double aspectDimensions[2];
+        renderer->GetAspect(aspectDimensions);
+        double aspectRatio = aspectDimensions[0]/aspectDimensions[1];
+
+        // Get the active camera 
+        vtkCamera* camera = proxy->GetActiveCamera();
+
+        if (!camera)
+        {
+          throw std::invalid_argument("Invalid vtkCamera.");
+        }
+
+        double planes[24];
+        camera->GetFrustumPlanes(aspectRatio, planes);
+
+        for (int k = 0; k < 4; ++k)
+        {
+          left[k] = planes[k];
+          right[k] = planes[k + 4];
+
+          bottom[k] = planes[k + 8];
+          top[k] = planes[k + 12];
+
+          near[k] = planes[k + 16];
+          far[k] = planes[k + 20];
+        }
+        Mantid::VATES::ViewFrustum frustum(Mantid::VATES::LeftPlane(left[0], left[1], left[2], left[3]),
+                                           Mantid::VATES::RightPlane(right[0], right[1], right[2], right[3]),
+                                           Mantid::VATES::BottomPlane(bottom[0], bottom[1], bottom[2], bottom[3]),
+                                           Mantid::VATES::TopPlane(top[0], top[1], top[2], top[3]),
+                                           Mantid::VATES::FarPlane(far[0], far[1], far[2], far[3]),
+                                           Mantid::VATES::NearPlane(near[0], near[1], near[2], near[3]));
+
+        return frustum;
+      }
+    
+      /**
+      * Set the view onto a peak
+      * @param xpos X position of the peak.
+      * @param ypos Y position of the peak.
+      * @param zpos Z position of the peak.
+      * @param peakRadius The radius of the peak.
+      */
+      void CameraManager::setCameraToPeak(double xpos, double ypos, double zpos, double peakRadius)
+      {
+        pqView * view = pqActiveView::instance().current();
+        vtkSMRenderViewProxy* proxy = NULL;
+
+        if (view)
+        {
+          proxy = vtkSMRenderViewProxy::SafeDownCast(view->getViewProxy());
+        }
+
+        if (!proxy)
+        {
+          // no active view, or active view is not a render view.
+          throw std::invalid_argument("Invalid vtkSMRenderViewProxy.");
+        }
+
+        // Get the active camera 
+        vtkCamera* camera = proxy->GetActiveCamera();
+
+        // Setup the focal point of the camera. we want this to be on the peak
+        camera->SetFocalPoint(xpos, ypos, zpos);
+
+        // Setup the position of the camera. We want this to be 
+        double zposCamera = zpos + peakRadius*3;
+        camera->SetPosition(xpos, ypos, zposCamera);
+        camera->SetViewUp(0.0, 1.0, 0.0);
+
+        view->forceRender();
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
index 6e8b6a79854972d426e4b78fdbcd11fc29d5479a..5b5fdd2c7dbe435b9295230b3e9e09052df3f15d 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/MdViewerWidget.cpp
@@ -975,7 +975,7 @@ void MdViewerWidget::renderAndFinalSetup()
   this->currentView->checkView(this->initialView);
   this->currentView->updateAnimationControls();
   this->setDestroyedListener();
-  this->setVisibilityListener();
+  this->currentView->setVisibilityListener();
   this->currentView->onAutoScale(this->ui.colorSelectionWidget);
 }
 
@@ -1056,7 +1056,7 @@ void MdViewerWidget::switchViews(ModeControlWidget::Views v)
   this->updateAppState();
   this->initialView = v; 
   this->setDestroyedListener();
-  this->setVisibilityListener();
+  this->currentView->setVisibilityListener();
 }
 
 /**
@@ -1093,10 +1093,7 @@ bool MdViewerWidget::eventFilter(QObject *obj, QEvent *ev)
 
       this->ui.colorSelectionWidget->reset();
       this->currentView->setColorScaleState(this->ui.colorSelectionWidget);
-
-      pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
-      builder->destroySources();
-
+      this->currentView ->destroyAllSourcesInView();
       this->currentView->updateSettings();
       this->currentView->hide();
 
@@ -1381,6 +1378,9 @@ void MdViewerWidget::preDeleteHandle(const std::string &wsName,
       removeRebinning(src, true);
       return;
     }
+    
+    // Remove all visibility listeners
+    this->currentView->removeVisibilityListener();
 
     emit this->requestClose();
   }
@@ -1437,29 +1437,12 @@ void MdViewerWidget::setDestroyedListener()
   }
 }
 
-/**
- * Set the listener for the visibility of the representations
- */
-void MdViewerWidget::setVisibilityListener()
-{
-  // Set the connection to listen to a visibility change of the representation.
-  pqServer *server = pqActiveObjects::instance().activeServer();
-  pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
-  QList<pqPipelineSource *> sources;
-  sources = smModel->findItems<pqPipelineSource *>(server);
 
-  // Attach the visibilityChanged signal for all sources.
-  for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source)
-  {
-    QObject::connect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)),
-                     this->currentView, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)),
-                     Qt::UniqueConnection);
-  }
-}
+
 
 /**
  * Dectect when a PeaksWorkspace is dragged into the VSI.
- * @param A drag event.
+ * @param e A drag event.
  */
 void MdViewerWidget::dragEnterEvent(QDragEnterEvent *e) {
   QString name = e->mimeData()->objectName();
@@ -1475,7 +1458,7 @@ void MdViewerWidget::dragEnterEvent(QDragEnterEvent *e) {
 
 /**
  * React to dropping a PeaksWorkspace ontot the VSI.
- * @param e A drop event.
+ * @param e Drop event.
  */
 void MdViewerWidget::dropEvent(QDropEvent *e) {
   QString name = e->mimeData()->objectName();
@@ -1494,7 +1477,7 @@ void MdViewerWidget::dropEvent(QDropEvent *e) {
   * Handle the drag and drop events of peaks workspaces.
   * @param e The event.
   * @param text String containing information regarding the workspace name.
-  * @param wsNames A reference to a list of workspaces names, which are being extracted.
+  * @param wsNames  Reference to a list of workspaces names, which are being extracted.
   */
  void MdViewerWidget::handleDragAndDropPeaksWorkspaces(QEvent* e, QString text, QStringList& wsNames)
  {
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..de208face716d97c26c6c7d7a3d386c50bac27fc
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTabWidget.cpp
@@ -0,0 +1,112 @@
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h"
+
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidQtSliceViewer/QPeaksTableModel.h"
+#include "MantidVatesSimpleGuiViewWidgets/PeaksWidget.h"
+
+#include <QWidget>
+#include <QItemSelectionModel>
+#include <QModelIndex>
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+/**
+Constructor
+
+@param ws : Peaks Workspace (MODEL)
+@param coordinateSystem : Name of coordinate system used
+@param parent : parent widget
+*/
+PeaksTabWidget::PeaksTabWidget(std::vector<Mantid::API::IPeaksWorkspace_sptr> ws, const std::string &coordinateSystem, QWidget *parent)  : QWidget(parent), m_ws(ws), m_coordinateSystem(coordinateSystem){
+  ui.setupUi(this);
+}
+
+/// Destructor 
+PeaksTabWidget::~PeaksTabWidget(){
+}
+
+/**
+ * Setup the Table model 
+ * @param visiblePeaks : A vector of lists of visible peaks for each peak workspace
+ */
+void PeaksTabWidget::setupMvc(std::map<std::string, std::vector<bool>> visiblePeaks) {
+  for (std::vector<Mantid::API::IPeaksWorkspace_sptr>::iterator it = m_ws.begin(); it != m_ws.end(); ++it) {
+    // Create new tab
+    std::string name((*it)->getName().c_str());
+
+    // Get visible peaks
+    if (visiblePeaks.count((*it)->getName()) > 0) {
+      addNewTab(*it, name, visiblePeaks[(*it)->getName()]);
+    }
+  }
+}
+
+void PeaksTabWidget::addNewTab(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::string tabName, std::vector<bool> visiblePeaks) {
+  PeaksWidget* widget = new PeaksWidget(peaksWorkspace, m_coordinateSystem, this);
+  widget->setupMvc(visiblePeaks);
+  
+  // Connect to the output of the widget
+  QObject::connect(widget, SIGNAL(zoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)),
+                   this, SLOT(onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)));
+
+  // Add as a new tab
+  this->ui.tabWidget->addTab(widget, QString(tabName.c_str()));
+}
+
+/**
+ * Zoom to the peak of interest
+ * @param ws The workspace pointer.
+ * @param row The row in the table.
+ */
+void PeaksTabWidget::onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr ws, int row){
+  emit zoomToPeak(ws, row);
+}
+
+/**
+ * Update the models and remove the model if it is not required anymore.
+ * @param visiblePeaks A map with visible peaks for each workspace.
+ */
+void PeaksTabWidget::updateTabs(std::map<std::string, std::vector<bool>> visiblePeaks) {
+  // Iterate over all tabs
+  for (int i = 0; i < this->ui.tabWidget->count(); i++) {
+    QString label = this->ui.tabWidget->label(i);
+    
+    // Check if the peaks workspace still exists, if it does update, else delete the tab.
+    if (visiblePeaks.count(label.toStdString()) > 0) {
+      updateTab(visiblePeaks[label.toStdString()], i);
+    }
+    else
+    {
+      this->ui.tabWidget->removeTab(i);
+    }
+  }
+}
+
+/**
+ * Update the tab 
+ * @param visbiblePeaks Vector which determines which peaks are visible.
+ * @param index The tab index.
+ */
+void PeaksTabWidget::updateTab(std::vector<bool> visiblePeaks, int index) {
+   PeaksWidget* widget = qobject_cast<PeaksWidget*>(this->ui.tabWidget->widget(index));
+   widget->updateModel(visiblePeaks);
+}
+
+/**
+ * Add a new tabs widget
+ * @param peaksWorkspace A pointer to a peaksWorkspace
+ */
+void PeaksTabWidget::addNewPeaksWorkspace(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, std::vector<bool> visiblePeaks) {
+  m_ws.push_back(peaksWorkspace);     
+  addNewTab(peaksWorkspace, peaksWorkspace->getName(), visiblePeaks);
+}
+}
+} // namespace
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..88dafd6383256bf1ad1f06b887f29ee5afe71f1d
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksTableControllerVsi.cpp
@@ -0,0 +1,504 @@
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h"
+
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTabWidget.h"
+#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidAPI/IMDEventWorkspace.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/PeakTransformHKL.h"
+#include "MantidAPI/PeakTransformQSample.h"
+#include "MantidAPI/PeakTransformQLab.h"
+#include "MantidKernel/V3D.h"
+#include "MantidVatesAPI/PeaksPresenterVsi.h"
+#include "MantidVatesAPI/NullPeaksPresenterVsi.h"
+#include "MantidVatesAPI/ConcretePeaksPresenterVsi.h"
+#include "MantidVatesAPI/CompositePeaksPresenterVsi.h"
+#include "MantidQtAPI/PlotAxis.h"
+#include "MantidGeometry/MDGeometry/IMDDimension.h"
+#include "MantidKernel/Logger.h"
+
+// Have to deal with ParaView warnings and Intel compiler the hard way.
+#if defined(__INTEL_COMPILER)
+  #pragma warning disable 1170
+#endif
+#include <pqActiveObjects.h>
+#include <pqApplicationCore.h>
+#include <pqObjectBuilder.h>
+#include <pqPipelineSource.h>
+#include <pqPipelineFilter.h>
+#include <pqServer.h>
+#include <vtkSMSourceProxy.h>
+#include <vtkSMPropertyHelper.h>
+#include <vtkSMProxy.h>
+
+#if defined(__INTEL_COMPILER)
+  #pragma warning enable 1170
+#endif
+
+#include <QString>
+#include <QPointer>
+#include <QVBoxLayout>
+#include <QLayout>
+#include <QLayoutItem>
+
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <stdexcept>
+#include <algorithm>
+#include <map>
+#include <sstream>
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+
+namespace
+{
+  Mantid::Kernel::Logger g_log("PeakViewerVsi");
+}
+
+  /**
+   * Constructor
+   * @param cameraManager A cameraManager pointer.
+   * @param parent A pointer to a QWidget parent.
+   */
+  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_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformHKLFactory>());
+    m_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformQSampleFactory>());
+    m_peakTransformSelector.registerCandidate(boost::make_shared<Mantid::API::PeakTransformQLabFactory>());
+  }
+
+  PeaksTableControllerVsi::~PeaksTableControllerVsi()
+  {
+    destroySinglePeakSource();
+  }
+
+  /**
+   * Check for viewable peaks.
+   * @returns A vector of the peak indices which are visible and which are not visible.
+   */ 
+  std::vector<bool> PeaksTableControllerVsi::getViewablePeaks()
+  {
+    std::vector<bool> viewablePeaks;
+    if (m_presenter)
+    {
+      // Get the up to date area
+      updateViewableArea();
+
+      //Get a list with viewable peak coordinates
+      try
+      {
+        viewablePeaks = m_presenter->getViewablePeaks();
+      }
+      catch(...)
+      {
+        g_log.warning() << "The viewable peaks could not be retrieved. \n"; 
+      }
+    }
+    return viewablePeaks;
+  }
+
+  /**
+   * Add a new workspace
+   * @param source A new peaks source
+   * @param splatSource A pointer to the splatter source
+   */
+  void PeaksTableControllerVsi::addWorkspace(pqPipelineSource* source, QPointer<pqPipelineSource> splatSource)
+  {
+    try
+    {
+      if (!source || !splatSource)
+      {
+        throw std::invalid_argument("The pqPipelineSource of the peaks workspace does not exist.");
+      }
+      
+      // Get the pointer to the peaks workspace 
+      std::string wsName(vtkSMPropertyHelper(source->getProxy(), "WorkspaceName", true).GetAsString());
+      std::string peaksFrame(vtkSMPropertyHelper(source->getProxy(), "Peak Dimensions", true).GetAsString());
+
+      // Get dimensions from splattersource
+      std::vector<std::string> dimInfo = extractFrameFromSource(splatSource);
+      if (dimInfo.size() < 2)
+      {
+        throw std::invalid_argument("The workspace needs to have at least two dimensions");
+      }
+
+      std::string dimCompare = dimInfo[0];
+      std::transform(dimCompare.begin(), dimCompare.end(),dimCompare.begin(), ::toupper);
+      std::transform(peaksFrame.begin(), peaksFrame.end(),peaksFrame.begin(), ::toupper);
+      // Check if frames match
+      if (dimCompare.find(peaksFrame) == std::string::npos)
+      {
+        throw std::runtime_error("The workspaces do not match.");
+      }
+
+      Mantid::API::IPeaksWorkspace_sptr peaksWorkspace = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IPeaksWorkspace>(wsName);
+
+      Mantid::API::PeakTransformFactory_sptr transformFactory = m_peakTransformSelector.makeChoice(dimInfo[0], dimInfo[1]);
+      Mantid::API::PeakTransform_sptr transform = transformFactory->createTransform(dimInfo[0], dimInfo[1]);
+      std::string frame = transform->getFriendlyName();
+
+      m_presenter->addPresenter(boost::make_shared<Mantid::VATES::ConcretePeaksPresenterVsi>(peaksWorkspace, m_cameraManager->getCurrentViewFrustum(), frame));
+      
+      // If the tab widget is visible, then update it
+      if (m_peaksTabWidget) {
+        std::map<std::string, std::vector<bool>> viewablePeaks = m_presenter->getInitializedViewablePeaks();
+        m_peaksTabWidget->addNewPeaksWorkspace(peaksWorkspace, viewablePeaks[peaksWorkspace->getName()]);
+        m_peaksTabWidget->updateTabs(viewablePeaks);
+      }
+    }
+    catch(Mantid::Kernel::Exception::NotFoundError&)
+    {
+      g_log.warning() << "Could not retrieve the peaks workspace.\n";
+      throw;
+    }
+    catch(std::invalid_argument &ex)
+    {
+      g_log.warning() << ex.what();
+      throw;
+    }
+    catch(std::runtime_error &ex)
+    {
+      g_log.warning() << ex.what();
+      throw;
+    }
+  }
+
+  /**
+   * Update the view region for the presenters
+   */
+  void PeaksTableControllerVsi::updateViewableArea()
+  {
+    Mantid::VATES::ViewFrustum frustum = m_cameraManager->getCurrentViewFrustum();
+    m_presenter->updateViewFrustum(frustum);
+  }
+
+  /**
+   * Extract the frame from the source
+   * @param splatSource A pointer to a splatter plot source.
+   */
+  std::vector<std::string> PeaksTableControllerVsi::extractFrameFromSource(QPointer<pqPipelineSource> splatSource)
+  {
+    pqPipelineFilter* filter = qobject_cast<pqPipelineFilter*>(splatSource);
+    
+    if (!filter)
+    {
+      throw std::invalid_argument("The splatter source is not a filter.");
+    }
+
+    // Check the original source
+    pqPipelineSource* originalSource = filter->getInput(0); 
+    if (!originalSource)
+    {
+      throw std::invalid_argument("The original source cannot be found.");
+    }
+
+    std::string xmlName(originalSource->getProxy()->GetXMLName());
+    if (!(xmlName.find("MDEW") != std::string::npos))
+    {
+      throw std::invalid_argument("The original source cannot be found.");
+    }
+
+    std::string wsName(vtkSMPropertyHelper(originalSource->getProxy(), "WorkspaceName", true).GetAsString());
+    Mantid::API::IMDEventWorkspace_sptr eventWorkspace = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::IMDEventWorkspace>(wsName);
+
+    std::vector<std::string> dimensionInfo;
+    for (size_t i = 0; i < eventWorkspace->getNumDims(); i++)
+    {
+      dimensionInfo.push_back(MantidQt::API::PlotAxis(*(eventWorkspace->getDimension(i))).title().toStdString());
+    }
+    
+    return dimensionInfo;
+  }
+
+  /**
+   * Check if the peaks viewer has a peaks workspace loaded.
+   * @returns If the a peaks workspace is loaded.
+   */
+  bool PeaksTableControllerVsi::hasPeaks()
+  {
+    if (!m_presenter || !m_presenter->hasPeaks())
+    {
+      return false;
+    }
+    else
+    {
+      return true;
+    }
+  }
+
+  /**
+   * Show all peaks in the table.
+   */
+  void PeaksTableControllerVsi::showFullTable()
+  {
+    createTable(true);
+  }
+
+  /**
+   * Create the table
+   * @param full If the full table is to be displayed or only visible peaks.
+   */
+  void PeaksTableControllerVsi::createTable(bool full)
+  {
+    // Create the table if it does not exist
+    if (hasPeaks())
+    {
+      if (layout()) 
+      {
+        removeLayout(this);
+      }
+
+      // Create new widget
+      try
+      {
+        // Set the layout of the table
+        this->setLayout(new QVBoxLayout);
+
+        PeaksTabWidget* widget = new PeaksTabWidget(m_presenter->getPeaksWorkspaces(), m_presenter->getFrame(), this);
+        QObject::connect(widget, SIGNAL(zoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)),
+                         this, SLOT(onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr, int)));
+
+        // Initialize the viewablePeaks to be true
+        std::map<std::string, std::vector<bool>> viewablePeaks = m_presenter->getInitializedViewablePeaks();
+
+        if (!full)
+        {
+          //
+          //viewablePeaks = getViewablePeaks();
+        }
+
+        widget->setupMvc(viewablePeaks);
+        layout()->addWidget(widget);
+        m_peaksTabWidget = widget;
+      }
+      catch(std::runtime_error &ex)
+      {
+        g_log.warning() << "Could not setup the the peaks widget for the splatterplot: " << ex.what() << "\n";
+      }
+      catch(...)
+      {
+        g_log.warning() << "Could not setup the the peaks widget for the splatterplot.\n";
+      }
+    }
+  }
+
+  /**
+  * Remove the layout
+  * @param widget
+  */
+  void PeaksTableControllerVsi::removeLayout(QWidget *widget) {
+    QLayout *layout = widget->layout();
+    if (layout != 0) {
+      QLayoutItem *item;
+      while ((item = layout->takeAt(0)) != 0){
+        layout->removeItem(item);
+        delete item->widget();
+      }
+      delete layout;
+    }
+  }
+
+  /**
+   * Remove the table.
+   */
+  void PeaksTableControllerVsi::removeTable()
+  {
+    destroySinglePeakSource();
+    if (m_peaksTabWidget) {
+      m_peaksTabWidget->deleteLater();
+    }
+    m_peaksTabWidget = NULL;
+  }
+
+ /**
+  * Zoom to a specific peak
+  * @param peaksWorkspace The peaksworkspace which is currently being displayed.
+  * @param row The selected row.
+  */
+  void PeaksTableControllerVsi::onZoomToPeak(Mantid::API::IPeaksWorkspace_sptr peaksWorkspace, int row)
+  {
+    try
+    {
+      double radius;
+      Mantid::Kernel::V3D position;
+      m_presenter->getPeaksInfo(peaksWorkspace, row, position, radius);
+
+      // Reset camera
+      m_cameraManager->setCameraToPeak(position[0], position[1], position[2], radius);
+
+      // Place a marker glyph at the position
+      if (!m_peakMarker)
+      {
+        generateSinglePeaksSource(position[0], position[1], position[2], radius);
+      }
+      else 
+      {
+        resetSinglePeaksSource(position[0], position[1], position[2], radius);
+      }
+
+      emit setRotationToPoint(position[0], position[1], position[2]);
+    } 
+    catch (std::invalid_argument &ex)
+    {
+      g_log.warning() << ex.what();
+      emit setRotationToPoint(0.0, 0.0, 0.0);
+    }
+  }
+
+  /**
+   * Generate a single peak  glyph
+   * @param position1 Position 1 of the glyph.
+   * @param position2 Position 2 of the glyph.
+   * @param position3 Position 3 of the glyph.
+   * @param radius The radius of the peak.
+   */
+  void PeaksTableControllerVsi::generateSinglePeaksSource(double position1, double position2, double position3, double radius)
+  {
+    // Create the source from the plugin
+    pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
+    pqServer *server = pqActiveObjects::instance().activeServer();
+    pqPipelineSource *src = builder->createSource("sources", "SinglePeakMarkerSource", server);
+    vtkSMPropertyHelper(src->getProxy(), "Position1").Set(position1);
+    vtkSMPropertyHelper(src->getProxy(), "Position2").Set(position2);
+    vtkSMPropertyHelper(src->getProxy(), "Position3").Set(position3);
+    vtkSMPropertyHelper(src->getProxy(), "RadiusMarker").Set(radius);
+
+    vtkSMSourceProxy *srcProxy = vtkSMSourceProxy::SafeDownCast(src->getProxy());
+    srcProxy->UpdateVTKObjects();
+    srcProxy->Modified();
+    srcProxy->UpdatePipelineInformation();
+    src->updatePipeline();
+ 
+    pqDataRepresentation *drep = builder->createDataRepresentation(src->getOutputPort(0), pqActiveObjects::instance().activeView());
+    vtkSMPropertyHelper(drep->getProxy(), "Representation").Set("Surface");
+    srcProxy->UpdateVTKObjects();
+    srcProxy->Modified();
+    srcProxy->UpdatePipelineInformation();
+    src->updatePipeline();
+
+    pqActiveObjects::instance().activeView()->forceRender();
+
+    m_peakMarker = src;
+
+    //We need to make sure we detect when the source is destroyed, as the user can delete it in the pipeline browser
+    QObject::connect(m_peakMarker, SIGNAL(destroyed()),
+                     this, SLOT(onPeakMarkerDestroyed()));
+
+  }
+
+  /** 
+   * Destroy a single peaks source.
+   */
+  void PeaksTableControllerVsi::destroySinglePeakSource()
+  {
+    if (m_peakMarker)
+    {
+      pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
+      builder->destroy(m_peakMarker);
+
+      m_peakMarker = NULL;
+    }
+  }
+
+  /**
+   * On Single Peak Marker destroyed
+   */
+  void PeaksTableControllerVsi::onPeakMarkerDestroyed()
+  {
+    m_peakMarker = NULL;
+  }
+
+  /**
+   * Reset the single peak source
+   * @param position1 Position 1 of the glyph.
+   * @param position2 Position 2 of the glyph.
+   * @param position3 Position 3 of the glyph.
+   * @param radius The radius of the peak.
+   */
+  void PeaksTableControllerVsi::resetSinglePeaksSource(double position1, double position2, double position3, double radius)
+  {
+    vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position1").Set(position1);
+    vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position2").Set(position2);
+    vtkSMPropertyHelper(m_peakMarker->getProxy(), "Position3").Set(position3);
+    vtkSMPropertyHelper(m_peakMarker->getProxy(), "RadiusMarker").Set(radius);
+
+    vtkSMSourceProxy *srcProxy = vtkSMSourceProxy::SafeDownCast(m_peakMarker->getProxy());
+    srcProxy->UpdateVTKObjects();
+    srcProxy->Modified();
+    srcProxy->UpdatePipelineInformation();
+    m_peakMarker->updatePipeline();
+
+    pqActiveObjects::instance().activeView()->forceRender();
+  }
+
+  /**
+   * Get the workspace names as a concatenated string
+   * @param delimiter The delimiter to concatenate workspace names.
+   * @returns The concatenated workspace names.
+   */
+  std::string PeaksTableControllerVsi::getConcatenatedWorkspaceNames(std::string delimiter) {
+    std::vector<std::string> peaksWorkspaceNames = m_presenter->getPeaksWorkspaceNames();
+    std::stringstream stream;
+    for (size_t i = 0; i < peaksWorkspaceNames.size(); i++) {
+      stream << peaksWorkspaceNames[i];
+      // Don't add a delimiter after the last element
+      if (i != (peaksWorkspaceNames.size()-1)) {
+        stream << delimiter;
+      }
+    }
+    return stream.str();
+  }
+
+  /**
+   * Update the  presenters with the available peak workspaces
+   * @param peakSources A list with available peak sources
+   * @param splatSource The splatterplot source
+   */
+  void PeaksTableControllerVsi::updatePeaksWorkspaces(QList<QPointer<pqPipelineSource>> peakSources, pqPipelineSource* splatSource) {
+    // Check if the which presenters exist and which need to be added
+    std::vector<std::string> peaksWorkspaceNames;
+
+    std::vector<pqPipelineSource*> nonTrackedWorkspaces;
+    std::vector<std::string> trackedWorkspaceNames = m_presenter->getPeaksWorkspaceNames();
+    for (QList<QPointer<pqPipelineSource>>::Iterator it = peakSources.begin(); it != peakSources.end(); ++it) {
+      std::string workspaceName(vtkSMPropertyHelper((*it)->getProxy(), "WorkspaceName").GetAsString());
+
+      peaksWorkspaceNames.push_back(workspaceName);
+
+      int count = static_cast<int>(std::count(trackedWorkspaceNames.begin(), trackedWorkspaceNames.end(), workspaceName));
+
+      if (count == 0) {
+        nonTrackedWorkspaces.push_back(*it);
+      }
+    }
+
+    if (splatSource) {
+      // Add the workspaces which are missing in the presenter
+      for (std::vector<pqPipelineSource*>::iterator it = nonTrackedWorkspaces.begin(); it != nonTrackedWorkspaces.end(); ++it) {
+        addWorkspace(*it, splatSource);
+      }
+    }
+
+    // Now update all the presenter 
+    m_presenter->updateWorkspaces(peaksWorkspaceNames);
+    if (!peakSources.empty() && m_peaksTabWidget) {
+       m_peaksTabWidget->updateTabs(m_presenter->getInitializedViewablePeaks());
+    }
+
+    // If there are no presenters left, we want to destroy the table
+    if (!hasPeaks()) {
+      removeTable();
+    }
+  }
+}
+}
+}
\ No newline at end of file
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..28b87daf264234bbcf2913bee27c075064bffae2
--- /dev/null
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/PeaksWidget.cpp
@@ -0,0 +1,99 @@
+#include "MantidVatesSimpleGuiViewWidgets/PeaksWidget.h"
+#include "MantidAPI/IPeaksWorkspace.h"
+#include "MantidQtSliceViewer/QPeaksTableModel.h"
+
+#include <QWidget>
+#include <QItemSelectionModel>
+#include <QModelIndex>
+#include <vector>
+#include <string>
+#include <map>
+
+namespace Mantid
+{
+namespace Vates
+{
+namespace SimpleGui
+{
+/**
+Constructor
+
+@param ws : Peaks Workspace (MODEL)
+@param coordinateSystem : Name of coordinate system used
+@param parent : parent widget
+*/
+PeaksWidget::PeaksWidget(Mantid::API::IPeaksWorkspace_sptr ws, const std::string &coordinateSystem, QWidget *parent)  : QWidget(parent), m_ws(ws), m_coordinateSystem(coordinateSystem){
+  ui.setupUi(this);
+}
+
+/**
+ * Setup the Table model 
+ * @param visiblePeaks : A vector of lists of visible peaks for each peak workspace
+ */
+void PeaksWidget::setupMvc(std::vector<bool> visiblePeaks)
+{
+  // Create new table view
+  MantidQt::SliceViewer::QPeaksTableModel* model = new  MantidQt::SliceViewer::QPeaksTableModel(m_ws);
+  ui.tblPeaks->setModel(model);
+  const std::vector<int> hideCols = model->defaultHideCols();
+  for (auto it = hideCols.begin(); it != hideCols.end(); ++it)
+    ui.tblPeaks->setColumnHidden(*it, true);
+  ui.tblPeaks->verticalHeader()->setResizeMode(QHeaderView::Interactive);
+  ui.tblPeaks->horizontalHeader()->setResizeMode(QHeaderView::Interactive);
+  m_originalTableWidth = ui.tblPeaks->horizontalHeader()->length();
+  // calculate the average width (in pixels) of numbers
+  QString allNums("0123456789");
+  double char_width =
+      static_cast<double>(
+          ui.tblPeaks->fontMetrics().boundingRect(allNums).width()) /
+      static_cast<double>(allNums.size());
+  // set the starting width of each column
+  for (int i = 0; i < m_originalTableWidth; ++i) {
+    double width =
+        static_cast<double>(model->numCharacters(i) + 3) * char_width;
+    ui.tblPeaks->horizontalHeader()->resizeSection(i, static_cast<int>(width));
+  }
+
+  // Set the visible rows 
+  for (size_t i = 0; i < visiblePeaks.size(); i++) {
+    if (visiblePeaks[i]){
+      ui.tblPeaks->showRow(static_cast<int>(i));
+    }
+    else
+    {
+      ui.tblPeaks->hideRow(static_cast<int>(i));
+    } 
+  }
+  QItemSelectionModel* selectionModel = ui.tblPeaks->selectionModel();
+  connect(selectionModel, SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(onCurrentChanged(QModelIndex, QModelIndex)));
+}
+
+/**
+ * Detects a newly selectedd peaks workspace.
+ * @param current The currently selected index.
+ */
+void PeaksWidget::onCurrentChanged(QModelIndex current, QModelIndex) {
+  if (current.isValid()) 
+  {
+    emit zoomToPeak(m_ws, current.row());
+  }
+}
+
+/**
+ * Update the visibility of the underlying model
+ * @param visiblePeaks A vector indicating which peaks are visible.
+ */
+void PeaksWidget::updateModel(std::vector<bool> visiblePeaks) {
+  for (size_t i = 0; i < visiblePeaks.size(); i++) {
+    if (visiblePeaks[i]){
+      ui.tblPeaks->showRow(static_cast<int>(i));
+    }
+    else
+    {
+      ui.tblPeaks->hideRow(static_cast<int>(i));
+    } 
+  }
+}
+} // namespace
+}
+}
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
index 346e4f949b46a62138c58ffd71a84fcbe4e597cd..494f211d022486ca654e544e3fe41bdd52bff83f 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinAlgorithmDialogProvider.cpp
@@ -125,6 +125,7 @@ namespace Mantid
        * @param algorithm The algorithm which is to be used.
        * @param inputWorkspace The name of the input workspace.
        * @param outputWorkspace The name of the output workspace.
+       * @param algorithmType The algorithm type.
        * @returns The algorithm dialog
        */
       MantidQt::API::AlgorithmDialog* RebinAlgorithmDialogProvider::createDialog(Mantid::API::IAlgorithm_sptr algorithm,
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
index f45d0c2f9be960545c6e934172096edfc4bdbf9f..19dda8218a3876aac992014e27710638b1742a96 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/RebinnedSourcesManager.cpp
@@ -94,7 +94,6 @@ namespace Mantid
       /**
        * Catch the deletion of either the rebinned or the original workspace.
        * @param wsName The name of the workspace.
-       * @param ws The handle to the workspace
        */
       void RebinnedSourcesManager::preDeleteHandle(const std::string &wsName, const boost::shared_ptr<Mantid::API::Workspace>)
       {
@@ -153,6 +152,7 @@ namespace Mantid
 
       /**
        * Get workspace name and type
+       * @param source The pipeline source.
        * @param workspaceName Reference to workspace name.
        * @param workspaceType Reference to workspace type.
        */
@@ -382,7 +382,7 @@ namespace Mantid
 
       /**
        * Stop keeping tabs on the specific workspace pair
-       * @param rebinnedWorspace The name of the rebinned workspace.
+       * @param rebinnedWorkspace The name of the rebinned workspace.
        */
       void RebinnedSourcesManager::untrackWorkspaces(std::string rebinnedWorkspace)
       {
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
index 7f357727b7d6bf85f1ac49565fde8f0fd2d2992a..9c9b9a27398d9aea6a7fab8ddb1b8b0534480f83 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/SplatterPlotView.cpp
@@ -1,9 +1,14 @@
 #include "MantidVatesSimpleGuiViewWidgets/SplatterPlotView.h"
-
+#include "MantidVatesSimpleGuiViewWidgets/CameraManager.h"
+#include "MantidVatesSimpleGuiViewWidgets/PeaksTableControllerVsi.h"
 #include "MantidAPI/IMDEventWorkspace.h"
 #include "MantidQtAPI/SelectionNotificationService.h"
 #include "MantidVatesAPI/ADSWorkspaceProvider.h"
 #include "MantidVatesAPI/vtkPeakMarkerFactory.h"
+#include "MantidVatesAPI/ViewFrustum.h"
+#include "MantidKernel/Logger.h"
+#include <boost/shared_ptr.hpp>
+#include <boost/make_shared.hpp>
 
 // Have to deal with ParaView warnings and Intel compiler the hard way.
 #if defined(__INTEL_COMPILER)
@@ -30,6 +35,9 @@
 
 #include <QKeyEvent>
 #include <QMessageBox>
+#include <QToolButton>
+#include <QMenu>
+#include <QAction>
 
 using namespace MantidQt::API;
 using namespace Mantid::VATES;
@@ -41,11 +49,29 @@ namespace Vates
 namespace SimpleGui
 {
 
-SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent)
+namespace
+{
+  Mantid::Kernel::Logger g_log("SplatterPlotView");
+}
+
+
+SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent),
+                                                      m_cameraManager(boost::make_shared<CameraManager>()),
+                                                      m_peaksTableController(NULL),
+                                                      m_peaksWorkspaceNameDelimiter(";")                         
 {
   this->noOverlay = false;
   this->ui.setupUi(this);
 
+ // Setup the peaks viewer
+  m_peaksTableController = new PeaksTableControllerVsi(m_cameraManager, this);
+  m_peaksTableController->setMaximumHeight(150);
+  //this->ui.tableLayout->addWidget(m_peaksTableController);
+  this->ui.verticalLayout->addWidget(m_peaksTableController);
+  m_peaksTableController->setVisible(true);
+  QObject::connect(m_peaksTableController, SIGNAL(setRotationToPoint(double, double, double)),
+                   this, SLOT(onResetCenterToPoint(double, double, double)));
+
   // Set the threshold button to create a threshold filter on data
   QObject::connect(this->ui.thresholdButton, SIGNAL(clicked()),
                    this, SLOT(onThresholdButtonClicked()));
@@ -64,6 +90,9 @@ SplatterPlotView::SplatterPlotView(QWidget *parent) : ViewBase(parent)
 
   this->view = this->createRenderView(this->ui.renderFrame);
   this->installEventFilter(this);
+
+  setupVisiblePeaksButtons();
+  
 }
 
 SplatterPlotView::~SplatterPlotView()
@@ -100,24 +129,10 @@ bool SplatterPlotView::eventFilter(QObject *obj, QEvent *ev)
 
 void SplatterPlotView::destroyView()
 {
+  destroyFiltersForSplatterPlotView();
+
+  // Destroy the view.
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
-  if (!this->peaksSource.isEmpty())
-  {
-    this->destroyPeakSources();
-    pqActiveObjects::instance().setActiveSource(this->origSrc);
-  }
-  if (this->probeSource)
-  {
-    builder->destroy(this->probeSource);
-  }
-  if (this->threshSource)
-  {
-    builder->destroy(this->threshSource);
-  }
-  if (this->splatSource)
-  {
-    builder->destroy(this->splatSource);
-  }
   builder->destroy(this->view);
 }
 
@@ -160,11 +175,23 @@ void SplatterPlotView::render()
   }
   else
   {
+      // We don't want to load the same peak workspace twice into the splatterplot mode
+    if (checkIfPeaksWorkspaceIsAlreadyBeingTracked(src)) {
+      QMessageBox::warning(this, QApplication::tr("Duplicate Peaks Workspace"),
+                           QApplication::tr("You cannot load the same "\
+                                          "Peaks Workpsace multiple times."));
+      builder->destroy(src);
+      pqActiveObjects::instance().setActiveSource(this->splatSource);
+      return;
+    }
+
     this->peaksSource.append(src);
+    setPeakSourceFrame(src);
     renderType = "Wireframe";
-    // Connect the peak source to a listener, to detect its destruction
-    QObject::connect(src, SIGNAL(destroyed()),
+    // Start listening if the source was destroyed
+    QObject::connect(src, SIGNAL(destroyed()), 
                      this, SLOT(onPeakSourceDestroyed()));
+    setPeakButton(true);
   }
 
   // Show the data
@@ -193,6 +220,25 @@ void SplatterPlotView::render()
   {
     this->renderAll();
   }
+
+  // Add peaksSource to the peak controller and the peak filter
+  if (isPeaksWorkspace)
+  {
+    try
+    {
+      m_peaksTableController->updatePeaksWorkspaces(this->peaksSource, this->splatSource);
+
+      if (m_peaksFilter)
+      {
+       updatePeaksFilter(m_peaksFilter);
+      }
+    }
+    catch (...)
+    {
+      setPeakButton(false);
+    }
+  }
+
   emit this->triggerAccept();
 }
 
@@ -295,6 +341,9 @@ void SplatterPlotView::resetCamera()
 
 void SplatterPlotView::destroyPeakSources()
 {
+  // First remove the peaks table, since it makes use of the peaks workspace.
+  onRemovePeaksTable();
+
   pqServer *server = pqActiveObjects::instance().activeServer();
   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
   pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
@@ -311,33 +360,6 @@ void SplatterPlotView::destroyPeakSources()
   this->peaksSource.clear();
 }
 
-/**
- * React to the destruction of a peak source, mainly unregister it from the peakSource container
- */
-void SplatterPlotView::onPeakSourceDestroyed() {
-    pqServer *server = pqActiveObjects::instance().activeServer();
-    pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
-    QList<pqPipelineSource *> sources;
-    sources = smModel->findItems<pqPipelineSource *>(server);
-
-  // Check for each source in the peakSource container, if it still is an existing source
-  for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end();) {
-    bool foundSource = false;
-    for (QList<pqPipelineSource*>::Iterator source = sources.begin(); source != sources.end(); ++source) {
-      // Check if the source registered in PV matches our current peak source
-      if ((*source) == (*it)) {
-        foundSource = true;
-      }
-    }
-
-    if (!foundSource) {
-      it = peaksSource.erase(it);
-    }
-    else {
-      ++it;
-    }
-  }
-}
 
 /**
  * This function reads the coordinates from the probe point plugin and
@@ -375,6 +397,287 @@ void SplatterPlotView::readAndSendCoordinates()
   }
 }
 
+/**
+ * Set up the buttons for the visible peaks.
+ */
+void SplatterPlotView::setupVisiblePeaksButtons()
+{
+  // Populate the rebin button
+  QMenu* peaksMenu = new QMenu(this->ui.peaksButton);
+
+  m_allPeaksAction = new QAction("Show all peaks in table", peaksMenu);
+  m_allPeaksAction->setIconVisibleInMenu(false);
+
+  m_removePeaksAction = new QAction("Remove table", peaksMenu);
+  m_removePeaksAction->setIconVisibleInMenu(false);
+
+  peaksMenu->addAction(m_allPeaksAction);
+  peaksMenu->addAction(m_removePeaksAction);
+
+  this->ui.peaksButton->setPopupMode(QToolButton::InstantPopup);
+  this->ui.peaksButton->setMenu(peaksMenu);
+  setPeakButton(false);
+
+  QObject::connect(m_allPeaksAction, SIGNAL(triggered()),
+                   this, SLOT(onShowAllPeaksTable()), Qt::QueuedConnection);
+
+  QObject::connect(m_removePeaksAction, SIGNAL(triggered()),
+                   this, SLOT(onRemovePeaksTable()), Qt::QueuedConnection);
+}
+
+
+/**
+ * On show all peaks 
+ */
+void SplatterPlotView::onShowAllPeaksTable()
+{
+  createPeaksFilter();
+
+  if (m_peaksTableController->hasPeaks())
+  {
+     m_peaksTableController->showFullTable();
+     m_peaksTableController->show();
+  }
+}
+
+
+/**
+ * Remove the visible peaks table.
+ */
+void SplatterPlotView::onRemovePeaksTable()
+{
+  if (m_peaksTableController->hasPeaks())
+  {
+    m_peaksTableController->removeTable();
+  }
+
+  if (m_peaksFilter)
+  {
+    pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+    builder->destroy(m_peaksFilter);
+  }
+}
+
+
+/**
+ * Create the peaks filter
+ */
+void SplatterPlotView::createPeaksFilter()
+{
+  // If the peaks filter already exists, then stay idle.
+  if (m_peaksFilter)
+  {
+    return;
+  }
+
+  // If the there is no peaks workspace, then stay idle.
+  if (peaksSource.isEmpty())
+  {
+    return;
+  }
+
+  // Create the peak filter
+  pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+
+  // Set the peaks workspace name. We need to trigger accept in order to log the workspace in the filter
+  try
+  {
+    m_peaksFilter = builder->createFilter("filters","MantidParaViewPeaksFilter", this->splatSource);
+    QObject::connect(m_peaksFilter, SIGNAL(destroyed()),
+                     this, SLOT(onPeaksFilterDestroyed()));
+
+    // Setup the peaks filter
+    updatePeaksFilter(m_peaksFilter);
+
+    // Create point representation of the source and set the point size 
+    const double pointSize = 4;
+    pqDataRepresentation *dataRepresentation  = m_peaksFilter->getRepresentation(this->view);
+    vtkSMPropertyHelper(dataRepresentation->getProxy(), "Representation").Set("Points");
+    vtkSMPropertyHelper(dataRepresentation->getProxy(), "PointSize").Set(pointSize);
+    dataRepresentation->getProxy()->UpdateVTKObjects();
+
+    pqPipelineRepresentation *pipelineRepresentation = qobject_cast<pqPipelineRepresentation*>(dataRepresentation);
+    pipelineRepresentation->colorByArray("signal", vtkDataObject::FIELD_ASSOCIATION_CELLS);
+    this->resetDisplay();
+    this->setVisibilityListener();
+    this->renderAll();
+  } catch(std::runtime_error &ex)
+  {
+    // Destroy peak filter
+    if (m_peaksFilter)
+    {
+      builder->destroy(m_peaksFilter);
+    }
+    g_log.warning() << ex.what();
+  }
+}
+
+/* On peaks source destroyed
+ * @param source The reference to the destroyed source
+ */
+void SplatterPlotView::onPeakSourceDestroyed()
+{
+  // For each peak Source check if there is a "true" source available.
+  // If it is not availble then remove it from the peakSource storage.
+  for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end();) {
+    pqServer *server = pqActiveObjects::instance().activeServer();
+    pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
+    QList<pqPipelineSource *> sources;
+    sources = smModel->findItems<pqPipelineSource *>(server);
+
+    bool foundSource = false;
+    for (QList<pqPipelineSource *>::iterator src = sources.begin(); src != sources.end(); ++src) {
+      if ((*src) == (*it)) {
+        foundSource = true;
+      }
+    }
+
+    if (!foundSource) {
+      it = peaksSource.erase(it); 
+    } 
+    else {
+      ++it;
+    }
+  }
+
+  if (peaksSource.isEmpty())
+  {
+    setPeakButton(false);
+  }
+
+  // Update the availbale peaksTableController with the available workspaces 
+  m_peaksTableController->updatePeaksWorkspaces(peaksSource, splatSource);
+  
+  // Update the peaks filter
+  try
+  {  
+    updatePeaksFilter(m_peaksFilter);
+  }
+  catch(std::runtime_error &ex)
+  {
+    g_log.warning() << ex.what();
+  }
+
+  // Set an active source
+  if (peaksSource.isEmpty()) {
+    pqActiveObjects::instance().setActiveSource(this->splatSource);
+  }
+  else {
+    pqActiveObjects::instance().setActiveSource(this->peaksSource[0]);
+  }
+}
+
+/**
+ * Sets the visibility of the peak button.
+ * @param state The visibility state of the peak button.
+ */
+void SplatterPlotView::setPeakButton(bool state)
+{
+  this->ui.peaksButton->setEnabled(state);
+}
+
+/**
+ * Set the frame of the peak source
+ * @param source The peak source
+ */
+void SplatterPlotView::setPeakSourceFrame(pqPipelineSource* source)
+{
+  int peakViewCoords = vtkSMPropertyHelper(this->origSrc->getProxy(), "SpecialCoordinates").GetAsInt();
+  peakViewCoords--;
+  vtkSMPropertyHelper(source->getProxy(), "Peak Dimensions").Set(peakViewCoords);
+}
+
+/**
+ * Check if a peaks workspace is already tracked by the peaksSource list.
+ */
+bool SplatterPlotView::checkIfPeaksWorkspaceIsAlreadyBeingTracked(pqPipelineSource* source) {
+  bool isContained = false;
+  std::string sourceName(vtkSMPropertyHelper(source->getProxy(), "WorkspaceName").GetAsString());
+  for (QList<QPointer<pqPipelineSource>>::Iterator it = peaksSource.begin(); it != peaksSource.end(); ++it) {
+    std::string trackedName(vtkSMPropertyHelper((*it)->getProxy(), "WorkspaceName").GetAsString());
+    if ((*it == source) || (sourceName == trackedName)) {
+      isContained = true;
+      break;
+    }
+  }
+  return isContained;
+}
+
+/**
+ * Updates the peaks filter, i.e. supplies the filter with a list of peaks workspaces and delimiter
+ * @param filter The peaks filter.
+ */
+void SplatterPlotView::updatePeaksFilter(pqPipelineSource* filter) {
+  if (!filter){
+    return;
+  }
+
+  // If there are no peaks, then destroy the filter, else update it.
+  if (peaksSource.isEmpty()) {
+    pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
+    builder->destroy(filter);
+  }
+  else {
+    std::string workspaceNamesConcatentated = m_peaksTableController->getConcatenatedWorkspaceNames(m_peaksWorkspaceNameDelimiter);
+    if (workspaceNamesConcatentated.empty())
+    {
+      throw std::runtime_error("The peaks viewer does not contain a valid peaks workspace.");
+    }
+
+    vtkSMPropertyHelper(filter->getProxy(), "PeaksWorkspace").Set(workspaceNamesConcatentated.c_str());
+    vtkSMPropertyHelper(filter->getProxy(), "Delimiter").Set(m_peaksWorkspaceNameDelimiter.c_str());
+    emit this->triggerAccept();
+    filter->updatePipeline();
+    this->resetCamera();
+  }  
+}
+
+/**
+ * Reacts to a destroyed peaks filter, mainly for setting the peak filter pointer to NULL.
+ * We need to do this, since PV can destroy the filter in a general destorySources command.
+ */
+void SplatterPlotView::onPeaksFilterDestroyed() {
+  m_peaksFilter = NULL;
+}
+
+/**
+ * Destroy all sources in the splatterplot view. We need to delete the filters before 
+ * we can delete the underlying sources
+ */
+void SplatterPlotView::destroyAllSourcesInView() {
+  destroyFiltersForSplatterPlotView();
+
+  // Destroy the remaning sources and filters
+  pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+  builder->destroySources();
+}
+
+
+void SplatterPlotView::destroyFiltersForSplatterPlotView(){
+   pqObjectBuilder *builder = pqApplicationCore::instance()->getObjectBuilder();
+  if (this->m_peaksFilter)
+  {
+    builder->destroy(this->m_peaksFilter);
+  }
+  if (!this->peaksSource.isEmpty())
+  {
+    this->destroyPeakSources();
+    pqActiveObjects::instance().setActiveSource(this->origSrc);
+  }
+  if (this->probeSource)
+  {
+    builder->destroy(this->probeSource);
+  }
+  if (this->threshSource)
+  {
+    builder->destroy(this->threshSource);
+  }
+  if (this->splatSource)
+  {
+    builder->destroy(this->splatSource);
+  }
+}
+
 } // SimpleGui
 } // Vates
 } // Mantid
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
index 09817b9f5ad9beee7fef6b2c1892ac0a8475dc30..e9c3809f654d0c5dea4b45b98a827d6c5d59d4bf 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/StandardView.cpp
@@ -42,7 +42,6 @@ namespace SimpleGui
  */
   StandardView::StandardView(QWidget *parent) : ViewBase(parent),m_binMDAction(NULL),
                                                                  m_sliceMDAction(NULL),
-                                                                 m_cutMDAction(NULL),
                                                                  m_unbinAction(NULL)
 {
   this->ui.setupUi(this);
@@ -86,15 +85,12 @@ void StandardView::setupViewButtons()
   m_sliceMDAction = new QAction("SliceMD", rebinMenu);
   m_sliceMDAction->setIconVisibleInMenu(false);
 
-  m_cutMDAction = new QAction("CutMD", rebinMenu);
-  m_cutMDAction->setIconVisibleInMenu(false);
 
   m_unbinAction = new QAction("Remove Rebinning", rebinMenu);
   m_unbinAction->setIconVisibleInMenu(false);
 
   rebinMenu->addAction(m_binMDAction);
   rebinMenu->addAction(m_sliceMDAction);
-  rebinMenu->addAction(m_cutMDAction);
   rebinMenu->addAction(m_unbinAction);
 
   this->ui.rebinToolButton->setPopupMode(QToolButton::InstantPopup);
@@ -104,18 +100,11 @@ void StandardView::setupViewButtons()
                    this, SLOT(onBinMD()), Qt::QueuedConnection);
   QObject::connect(m_sliceMDAction, SIGNAL(triggered()),
                    this, SLOT(onSliceMD()), Qt::QueuedConnection);
-  QObject::connect(m_cutMDAction, SIGNAL(triggered()),
-                   this, SLOT(onCutMD()), Qt::QueuedConnection);
   // Set the unbinbutton to remove the rebinning on a workspace
   // which was binned in the VSI
   QObject::connect(m_unbinAction, SIGNAL(triggered()),
                    this, SIGNAL(unbin()), Qt::QueuedConnection);
 
-
-  // Populate the slice button
-
-  // Populate the cut button
-
 }
 
 void StandardView::destroyView()
@@ -269,13 +258,11 @@ void StandardView::setRebinAndUnbinButtons()
   {
     this->m_binMDAction->setEnabled(false);
     this->m_sliceMDAction->setEnabled(false);
-    this->m_cutMDAction->setEnabled(false);
   }
   else 
   {
     this->m_binMDAction->setEnabled(true);
     this->m_sliceMDAction->setEnabled(true);
-    this->m_cutMDAction->setEnabled(false);
   }
 
   // If there are no temporary workspaces the button should be disabled.
@@ -306,13 +293,6 @@ void StandardView::onSliceMD()
   emit rebin("SliceMD");
 }
 
-/**
- * Reacts to the user selecting the CutMD algorithm
- */ 
-void StandardView::onCutMD()
-{
-  emit rebin("CutMD");
-}
 
 /**
   * Listen for a change of the active source in order to check if the the 
@@ -325,7 +305,6 @@ void StandardView::activeSourceChangeListener(pqPipelineSource* source)
   {
     this->m_binMDAction->setEnabled(false);
     this->m_sliceMDAction->setEnabled(false);
-    this->m_cutMDAction->setEnabled(false);
     this->m_unbinAction->setEnabled(false);
     return;
   }
@@ -347,21 +326,18 @@ void StandardView::activeSourceChangeListener(pqPipelineSource* source)
   {
     this->m_binMDAction->setEnabled(true);
     this->m_sliceMDAction->setEnabled(true);
-    this->m_cutMDAction->setEnabled(false);
     this->m_unbinAction->setEnabled(true);
   }
   else if (workspaceType.find("MDEW Source") != std::string::npos)
   {
     this->m_binMDAction->setEnabled(true);
     this->m_sliceMDAction->setEnabled(true);
-    this->m_cutMDAction->setEnabled(false);
     this->m_unbinAction->setEnabled(false);
   }
   else
   {
     this->m_binMDAction->setEnabled(false);
     this->m_sliceMDAction->setEnabled(false);
-    this->m_cutMDAction->setEnabled(false);
     this->m_unbinAction->setEnabled(false);
   }
 }
diff --git a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
index fc09884575eca7239cac825138057c61da06faa4..17cc2e0c856421f86c463603921acc4d93b06eee 100644
--- a/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
+++ b/Code/Mantid/Vates/VatesSimpleGui/ViewWidgets/src/ViewBase.cpp
@@ -12,6 +12,7 @@
 #include <pqDataRepresentation.h>
 #include <pqObjectBuilder.h>
 #include <pqPipelineSource.h>
+#include <pqPipelineFilter.h>
 #include <pqPipelineRepresentation.h>
 #include <pqPVApplicationCore.h>
 #include <pqRenderView.h>
@@ -329,7 +330,7 @@ void ViewBase::checkView(ModeControlWidget::Views initialView)
 
 /**
  * This metod sets the status of the splatterplot button explictly to a desired value
- * @param visiblity The state of the the splatterplot view button.
+ * @param visibility The state of the the splatterplot view button.
  */
 void ViewBase::setSplatterplot(bool visibility)
 {
@@ -338,7 +339,7 @@ void ViewBase::setSplatterplot(bool visibility)
 
 /**
  * This metod sets the status of the standard view button explictly to a desired value
- * @param visiblity The state of the the standard view button.
+ * @param visibility The state of the the standard view button.
  */
 void ViewBase::setStandard(bool visibility)
 {
@@ -801,6 +802,96 @@ void ViewBase::onSourceDestroyed()
 {
 }
 
+/**
+ * Destroy all sources in the view.
+ */
+void ViewBase::destroyAllSourcesInView() {
+  pqServer *server = pqActiveObjects::instance().activeServer();
+  pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
+  QList<pqPipelineSource *> sources = smModel->findItems<pqPipelineSource *>(server);
+
+  // Out of all pqPipelineSources, find the "true" sources, which were
+  // created by a Source Plugin, i.e. MDEW Source, MDHW Source, PeakSource
+  QList<pqPipelineSource*> trueSources;
+  for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source) {
+    if (!qobject_cast<pqPipelineFilter*>(*source)) {
+      trueSources.push_back(*source);
+    }
+  }
+
+  // For each true source, go to the end of the pipeline and destroy it on the way back
+  // to the start. This assumes linear pipelines.
+  for (QList<pqPipelineSource *>::iterator trueSource = trueSources.begin(); trueSource != trueSources.end(); ++trueSource) {
+    destroySinglePipeline(*trueSource);
+  }
+}
+
+
+/**
+ * Destroy a single, linear pipeline
+ * @param source A true pqPiplineSource, i.e. not a filter.
+ */
+void ViewBase::destroySinglePipeline(pqPipelineSource * source) {
+
+    pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
+
+    // Move to the end of the pipeline
+    pqPipelineSource *sourceBuffer = source;
+    while(sourceBuffer->getNumberOfConsumers() > 0) {
+      sourceBuffer = sourceBuffer->getConsumer(0);
+    }
+
+    // Now destroy the pipeline coming back again
+    pqPipelineFilter* filter = qobject_cast<pqPipelineFilter*>(sourceBuffer);
+    while(filter) {
+      sourceBuffer = filter->getInput(0);
+      builder->destroy(filter);
+      filter = qobject_cast<pqPipelineFilter*>(sourceBuffer);
+    }
+
+    builder->destroy(sourceBuffer);
+}
+
+/**
+ * Set the listener for the visibility of the representations
+ */
+void ViewBase::setVisibilityListener()
+{
+  // Set the connection to listen to a visibility change of the representation.
+  pqServer *server = pqActiveObjects::instance().activeServer();
+  pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
+  QList<pqPipelineSource *> sources;
+  sources = smModel->findItems<pqPipelineSource *>(server);
+
+  // Attach the visibilityChanged signal for all sources.
+  for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source)
+  {
+    QObject::connect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)),
+                     this, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)),
+                     Qt::UniqueConnection);
+  }
+}
+
+/**
+ * Disconnects the visibility listener connection for all sources
+ */
+void ViewBase::removeVisibilityListener() {
+    // Set the connection to listen to a visibility change of the representation.
+  pqServer *server = pqActiveObjects::instance().activeServer();
+  pqServerManagerModel *smModel = pqApplicationCore::instance()->getServerManagerModel();
+  QList<pqPipelineSource *> sources;
+  sources = smModel->findItems<pqPipelineSource *>(server);
+
+  // Attach the visibilityChanged signal for all sources.
+  for (QList<pqPipelineSource *>::iterator source = sources.begin(); source != sources.end(); ++source)
+  {
+    QObject::disconnect((*source), SIGNAL(visibilityChanged(pqPipelineSource*, pqDataRepresentation*)),
+                         this, SLOT(onVisibilityChanged(pqPipelineSource*, pqDataRepresentation*)));
+  }
+}
+
+
+
 } // namespace SimpleGui
 } // namespace Vates
 } // namespace Mantid
diff --git a/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst b/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst
index eddd7ddb415126d728446b85a2ca6877c2a4795b..f1774a3d93ffa3306ff1a4e808b4a3076dc6ffba 100644
--- a/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/AddPeak-v1.rst
@@ -9,7 +9,7 @@
 Description
 -----------
 
-Adds a peak to a :ref:`PeaksWorkspace <PeaksWorkspace>`__.
+Adds a peak to a :ref:`PeaksWorkspace <PeaksWorkspace>`.
 
 Usage
 -----
diff --git a/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst b/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst
index 3428f32e330a3075bfdac710825247c4c55d25bd..ab768f8c24c9793bc57186c7a4f12c7adb521a09 100644
--- a/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/AddPeakHKL-v1.rst
@@ -10,7 +10,7 @@
 Description
 -----------
 
-Add a peak in the HKL frame to an existing :ref:`PeaksWorkspace <PeaksWorkspace>`__. The OrientedLattice must be provided and the Goniometer should be set correctly before running the algorithm. 
+Add a peak in the HKL frame to an existing :ref:`PeaksWorkspace <PeaksWorkspace>`. The OrientedLattice must be provided and the Goniometer should be set correctly before running the algorithm. 
 
 The peak is added to the existing PeaksWorkspace. Run information and goniometer setting and the UB matrix are taken from the provided PeaksWorkspace.
 
diff --git a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
index 58bbefcd73e40284bd3ef125d5f6f1fd88d5cc35..adc45fcce602ce461688b34fc864942138f33ac4 100644
--- a/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/ConvertCWPDMDToSpectra-v1.rst
@@ -13,6 +13,11 @@ This algorithms is to collect the all the counts on the detectors among
 a set of measurements, which belong to a same experiment run,
 and bin them according to detector's position, i.e., :math:`2\theta`. 
 
+In this algorithm's name, ConvertCWPDMDToSpectra, *CW* stands for constant wave 
+(reactor-source instrument); *PD* stands for powder diffraction; and *MD* 
+stands for MDEventWorkspace because the input of this algorithms are two 
+MDEventWorkspaces. 
+
 This algorithm takes 2 MDEventWorkspaces as inputs.  
 One stores the detectors' counts;
 and the other stores the monitors' counts. 
diff --git a/Code/Mantid/docs/source/algorithms/CutMD-v1.rst b/Code/Mantid/docs/source/algorithms/CutMD-v1.rst
index 4f1dea9a34b774cd4cd0061c0543215d62bd10d4..98b00565f70354061e153679fb13593d870b82d5 100644
--- a/Code/Mantid/docs/source/algorithms/CutMD-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/CutMD-v1.rst
@@ -37,8 +37,8 @@ Usage
    projection = Projection([1,1,0], [-1,1,0])
    proj_ws = projection.createWorkspace()
    
-   # Apply the cut
-   out_md = CutMD(to_cut, Projection=proj_ws, P1Bin=[0.1], P2Bin=[0.1], P3Bin=[0.1], P4Bin=[-5,5], NoPix=True)
+   # Apply the cut (PBins property sets the P1Bin, P2Bin, etc. properties for you)
+   out_md = CutMD(to_cut, Projection=proj_ws, PBins=([0.1], [0.1], [0.1], [-5,5]), NoPix=True)
    print 'number of dimensions', out_md.getNumDims()
    print 'number of dimensions not integrated', len(out_md.getNonIntegratedDimensions())
    dim_dE = out_md.getDimension(3)
diff --git a/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..b1e4a48ccfef235fda24488dbdf9b0242b0f07ec
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/CylinderPaalmanPingsCorrection-v1.rst
@@ -0,0 +1,64 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+Calculates absorption corrections for a cylindrical or annular sample giving
+output in the Paalman & Pings absorption factors: :math:`A_{s,s}` (correction
+factor for scattering and absorption in sample), :math:`A_{s,sc}` (scattering in
+sample and absorption in sample and container), :math:`A_{c,sc}` (scattering in
+container and absorption in sample and container) and  :math:`A_{c,c}`
+(scattering and absorption in container).
+
+Restrictions on the input workspace
+###################################
+
+The input workspace must have a fully defined instrument that has X axis units
+of wavelength.
+
+Usage
+-----
+
+**Example:**
+
+.. code-block:: python
+
+    # Create a sample workspace
+    sample = CreateSampleWorkspace(NumBanks=1, BankPixelWidth=1,
+                                   XUnit='Wavelength',
+                                   XMin=6.8, XMax=7.9,
+                                   BinWidth=0.1)
+
+    # Copy and scale it to make a can workspace
+    can = CloneWorkspace(InputWorkspace=sample)
+    can = Scale(InputWorkspace=can, Factor=1.2)
+
+    # Calculate absorption corrections
+    corr = CylinderPaalmanPingsCorrection(SampleWorkspace=sample,
+                                          SampleChemicalFormula='H2-O',
+                                          SampleInnerRadius=0.05,
+                                          SampleOuterRadius=0.1,
+                                          CanWorkspace=can,
+                                          CanChemicalFormula='V',
+                                          CanOuterRadius=0.15,
+                                          BeamHeight=0.1,
+                                          BeamWidth=0.1,
+                                          StepSize=0.002,
+                                          Emode='Indirect',
+                                          Efixed=1.845)
+
+    print 'Correction workspaces: %s' % (', '.join(corr.getNames()))
+
+Output:
+
+.. code-block:: none
+
+    Correction workspaces: corr_ass, corr_assc, corr_acsc, corr_acc
+
+.. categories::
diff --git a/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst b/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..df06d774613de3f24f955af488933db8ef83553e
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/EstimatePeakErrors-v1.rst
@@ -0,0 +1,38 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm takes a function after it has been optimized by the Fit algorithm and calculates peak parameter and associated errors for all peaks in this function. The peak parameters are its centre, height, FWHM and intensity. The output workspace is a table with three columns: parameter name, parameter value and parameter error.
+
+Usage
+-----
+(*At the moment the algorithm works properly if run from C++ only.*)
+
+    import numpy as np
+
+    # Create a data set
+    x = np.linspace(-10,10,100)
+    y = 10 * 2.0 / (2.0**2 + (x+4)**2 ) + 10 * 3.0 / (3.0**2 + (x-3)**2 ) + 3.0
+    e = np.ones_like(x)
+    ws = CreateWorkspace(x,y,e)
+
+    # Define a fitting function.
+    fun = "name=Lorentzian,Amplitude=10,PeakCentre=-4,FWHM=2;"+\
+                  "name=Lorentzian,Amplitude=10,PeakCentre=3,FWHM=3;"+\
+                  "name=FlatBackground,A0=3"
+
+    # Fit the function.
+    Fit(fun,ws)
+
+    # Calculate peak parameter error estimates for the two Lorentzians.
+    params = EstimatePeakErrors(fun)
+
+ 
+.. categories::
diff --git a/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst b/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
index 415db1d13ded7be90fe6b58ef0005bddd81c7a83..47da311b90228afe23bd4799a76b12cdb1e909a9 100644
--- a/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/FlatPlatePaalmanPingsCorrection-v1.rst
@@ -23,7 +23,8 @@ available in `RAL Technical Report 74-103
 Restrictions on the input workspace
 ###################################
 
-The input workspace must have units of wavelength.
+The input workspace must have a fully defined instrument that has X axis units
+of wavelength.
 
 Usage
 -----
diff --git a/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..90eebc58ce6c8a7e9c96d010e4bebe236211b8c1
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/IndirectAnnulusAbsorption-v1.rst
@@ -0,0 +1,63 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+Calculates and applies corrections for scattering abs absorption in a annular
+sample for a run on an indirect inelastic instrument, optionally also performing
+a simple can subtraction is a container workspace is provided.
+
+The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings
+attenuation factor for absorption and scattering in the sample.
+
+Usage
+-----
+
+.. include:: ../usagedata-note.txt
+
+**Example - Sample corrections for IRIS:**
+
+.. testcode:: SampleCorrectionsWithCanSubtraction
+
+  red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+  can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+
+  corrected, ass = IndirectAnnulusAbsorption(SampleWorkspace=red_ws,
+                                             CanWorkspace=can_ws,
+                                             CanScaleFactor=0.8,
+                                             ChemicalFormula='H2-O',
+                                             CanInnerRadius=0.2,
+                                             SampleInnerRadius=0.15,
+                                             SampleOuterRadius=0.16,
+                                             CanOuterRadius=0.22,
+                                             Events=200)
+
+  print ('Corrected workspace is intensity against %s'
+        % (corrected.getAxis(0).getUnit().caption()))
+
+  print ('Corrections workspace is %s against %s'
+        % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption()))
+
+
+.. testcleanup:: SampleCorrectionsWithCanSubtraction
+
+   DeleteWorkspace(red_ws)
+   DeleteWorkspace(can_ws)
+   DeleteWorkspace(corrected)
+   DeleteWorkspace(ass)
+
+**Output:**
+
+
+.. testoutput:: SampleCorrectionsWithCanSubtraction
+
+  Corrected workspace is intensity against Energy transfer
+  Corrections workspace is Attenuation factor against Wavelength
+
+.. categories::
diff --git a/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..eb7c25150ad5e01ea9cf7942029c6b733b17c578
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/IndirectCylinderAbsorption-v1.rst
@@ -0,0 +1,59 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+Calculates and applies corrections for scattering abs absorption in a
+cylindrical sample for a run on an indirect inelastic instrument, optionally
+also performing a simple can subtraction is a container workspace is provided.
+
+The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings
+attenuation factor for absorption and scattering in the sample.
+
+Usage
+-----
+
+.. include:: ../usagedata-note.txt
+
+**Example - Sample corrections for IRIS:**
+
+.. testcode:: SampleCorrectionsWithCanSubtraction
+
+  red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+  can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+
+  corrected, ass = IndirectCylinderAbsorption(SampleWorkspace=red_ws,
+                                              CanWorkspace=can_ws,
+                                              CanScaleFactor=0.8,
+                                              ChemicalFormula='H2-O',
+                                              SampleRadius=0.2)
+
+  print ('Corrected workspace is intensity against %s'
+        % (corrected.getAxis(0).getUnit().caption()))
+
+  print ('Corrections workspace is %s against %s'
+        % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption()))
+
+
+.. testcleanup:: SampleCorrectionsWithCanSubtraction
+
+   DeleteWorkspace(red_ws)
+   DeleteWorkspace(can_ws)
+   DeleteWorkspace(corrected)
+   DeleteWorkspace(ass)
+
+**Output:**
+
+
+.. testoutput:: SampleCorrectionsWithCanSubtraction
+
+  Corrected workspace is intensity against Energy transfer
+  Corrections workspace is Attenuation factor against Wavelength
+
+.. categories::
diff --git a/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..0557ecb326b9a7cfc0630f34e8ce1d1c2e70e9fe
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/IndirectFlatPlateAbsorption-v1.rst
@@ -0,0 +1,62 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+Calculates and applies corrections for scattering abs absorption in a flat plate
+sample for a run on an indirect inelastic instrument, optionally also performing
+a simple can subtraction is a container workspace is provided.
+
+The corrections workspace (:math:`A_{s,s}`) is the standard Paalman and Pings
+attenuation factor for absorption and scattering in the sample.
+
+Usage
+-----
+
+.. include:: ../usagedata-note.txt
+
+**Example - Sample corrections for IRIS:**
+
+.. testcode:: SampleCorrectionsWithCanSubtraction
+
+  red_ws = LoadNexusProcessed(Filename='irs26176_graphite002_red.nxs')
+  can_ws = LoadNexusProcessed(Filename='irs26173_graphite002_red.nxs')
+
+  corrected, ass = IndirectFlatPlateAbsorption(SampleWorkspace=red_ws,
+                                               CanWorkspace=can_ws,
+                                               CanScaleFactor=0.8,
+                                               ChemicalFormula='H2-O',
+                                               SampleHeight=1,
+                                               SampleWidth=1,
+                                               SampleThickness=1,
+                                               ElementSize=1)
+
+  print ('Corrected workspace is intensity against %s'
+        % (corrected.getAxis(0).getUnit().caption()))
+
+  print ('Corrections workspace is %s against %s'
+        % (ass.YUnitLabel(), ass.getAxis(0).getUnit().caption()))
+
+
+.. testcleanup:: SampleCorrectionsWithCanSubtraction
+
+   DeleteWorkspace(red_ws)
+   DeleteWorkspace(can_ws)
+   DeleteWorkspace(corrected)
+   DeleteWorkspace(ass)
+
+**Output:**
+
+
+.. testoutput:: SampleCorrectionsWithCanSubtraction
+
+  Corrected workspace is intensity against Energy transfer
+  Corrections workspace is Attenuation factor against Wavelength
+
+.. categories::
diff --git a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst
index ddbdd07345bf16c4155643c9d04b443b2e889369..4f91c1e8c1bd17f4234bdc458adf8cefe524c7a2 100644
--- a/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/LoadSpiceAscii-v1.rst
@@ -55,7 +55,10 @@ Usage
 
   print "Number of measuring points = %d" % (datatbws.rowCount())
   print "Number of columns in data workspace = %d" % (datatbws.columnCount())
-  print "Number of run information = %d" % (len(infows.getRun().getProperties()))
+  propertylist = infows.getRun().getProperties()
+  print "Number of run information = %d" % (len(propertylist))
+  for i in xrange(len(propertylist)):
+      print "Property %d: Name = %-20s." % (i, propertylist[i].name)
   print "Sum of Counts = %d" % (infows.getRun().getProperty("Sum of Counts").value)
   print "Center of Mass = %.5f +/- %.5f" % (infows.getRun().getProperty("Center of Mass").value, 
       infows.getRun().getProperty("Center of Mass.error").value)
@@ -71,7 +74,42 @@ Output:
 
   Number of measuring points = 61
   Number of columns in data workspace = 70
-  Number of run information = 34
+  Number of run information = 35
+  Property 0: Name = Center of Mass      .
+  Property 1: Name = Center of Mass.error.
+  Property 2: Name = Full Width Half-Maximum.
+  Property 3: Name = Full Width Half-Maximum.error.
+  Property 4: Name = Sum of Counts       .
+  Property 5: Name = analyzer            .
+  Property 6: Name = builtin_command     .
+  Property 7: Name = col_headers         .
+  Property 8: Name = collimation         .
+  Property 9: Name = command             .
+  Property 10: Name = date                .
+  Property 11: Name = def_x               .
+  Property 12: Name = def_y               .
+  Property 13: Name = experiment          .
+  Property 14: Name = experiment_number   .
+  Property 15: Name = latticeconstants    .
+  Property 16: Name = local_contact       .
+  Property 17: Name = mode                .
+  Property 18: Name = monochromator       .
+  Property 19: Name = preset_channel      .
+  Property 20: Name = preset_type         .
+  Property 21: Name = preset_value        .
+  Property 22: Name = proposal            .
+  Property 23: Name = runend              .
+  Property 24: Name = samplemosaic        .
+  Property 25: Name = samplename          .
+  Property 26: Name = sampletype          .
+  Property 27: Name = scan                .
+  Property 28: Name = scan_title          .
+  Property 29: Name = sense               .
+  Property 30: Name = time                .
+  Property 31: Name = ubconf              .
+  Property 32: Name = ubmatrix            .
+  Property 33: Name = users               .
+  Property 34: Name = run_start           .
   Sum of Counts = 1944923
   Center of Mass = 9.00076 +/- 0.00921
 
diff --git a/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst b/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..358c9f42d8af1ced158ad28fab7c3aecffd57870
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/MSDFit-v1.rst
@@ -0,0 +1,47 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+Fits :math:`log(intensity)` vs :math:`Q^{2}` with a straight line for each run
+to obtain the mean square displacement for a given range of runs.
+
+This algorithm operates on the QSquared workspace (*_q2*) generated by the
+:ref:`ElasticWindowMultiple <algm-ElasticWindowMultiple>` algorithm.
+
+Usage
+-----
+
+**Example - Performing MSDFit on simulated data.**
+
+.. testcode:: ExGeneratedDataFit
+
+    # Create some data that is similar to the output of ElasticWindowMultiple
+    sample = CreateSampleWorkspace(Function='User Defined',
+                    UserDefinedFunction='name=ExpDecay,Height=1,Lifetime=6',
+                    NumBanks=1, BankPixelWidth=1, XUnit='QSquared', XMin=0.0,
+                    XMax=5.0, BinWidth=0.1)
+
+    msd, param, fit = MSDFit(InputWorkspace=sample,
+                             XStart=0.0, XEnd=5.0,
+                             SpecMin=0, SpecMax=0)
+
+    print ', '.join(msd.getNames())
+    print 'A0: ' + str(msd.getItem(0).readY(0))
+    print 'A1: ' + str(msd.getItem(1).readY(0))
+
+Output:
+
+.. testoutput:: ExGeneratedDataFit
+
+    msd_A0, msd_A1
+    A0: [ 0.95908058]
+    A1: [ 0.11014908]
+
+.. categories::
diff --git a/Code/Mantid/docs/source/concepts/Analysis_Data_Service.rst b/Code/Mantid/docs/source/concepts/AnalysisDataService.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Analysis_Data_Service.rst
rename to Code/Mantid/docs/source/concepts/AnalysisDataService.rst
diff --git a/Code/Mantid/docs/source/concepts/Create_an_IDF.rst b/Code/Mantid/docs/source/concepts/CreateanIDF.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Create_an_IDF.rst
rename to Code/Mantid/docs/source/concepts/CreateanIDF.rst
diff --git a/Code/Mantid/docs/source/concepts/Data_Service.rst b/Code/Mantid/docs/source/concepts/DataService.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Data_Service.rst
rename to Code/Mantid/docs/source/concepts/DataService.rst
diff --git a/Code/Mantid/docs/source/concepts/Dynamic_Factory.rst b/Code/Mantid/docs/source/concepts/DynamicFactory.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Dynamic_Factory.rst
rename to Code/Mantid/docs/source/concepts/DynamicFactory.rst
diff --git a/Code/Mantid/docs/source/concepts/Error_Propagation.rst b/Code/Mantid/docs/source/concepts/ErrorPropagation.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Error_Propagation.rst
rename to Code/Mantid/docs/source/concepts/ErrorPropagation.rst
diff --git a/Code/Mantid/docs/source/concepts/EventWorkspace.rst b/Code/Mantid/docs/source/concepts/EventWorkspace.rst
index 7e8712b18582552f9147ff9e1d0d9f5c3c19a403..09b7e0428229fe7f16ed0f89627d2a2e02a235d9 100644
--- a/Code/Mantid/docs/source/concepts/EventWorkspace.rst
+++ b/Code/Mantid/docs/source/concepts/EventWorkspace.rst
@@ -1,7 +1,7 @@
 .. _EventWorkspace:
 
-EventWorkspace
-==============
+Event Workspace
+===============
 
 Quick Summary For Users
 -----------------------
diff --git a/Code/Mantid/docs/source/concepts/Facilities_File.rst b/Code/Mantid/docs/source/concepts/FacilitiesFile.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Facilities_File.rst
rename to Code/Mantid/docs/source/concepts/FacilitiesFile.rst
diff --git a/Code/Mantid/docs/source/concepts/Framework_Manager.rst b/Code/Mantid/docs/source/concepts/FrameworkManager.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Framework_Manager.rst
rename to Code/Mantid/docs/source/concepts/FrameworkManager.rst
diff --git a/Code/Mantid/docs/source/concepts/Geometry_of_Position.rst b/Code/Mantid/docs/source/concepts/GeometryofPosition.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/Geometry_of_Position.rst
rename to Code/Mantid/docs/source/concepts/GeometryofPosition.rst
index b6cbf2f310b3c80a4092d82c12ebdee9d2c1e86f..4451b15f80217ab2b8ca7b19aa725fe5967d9a61 100644
--- a/Code/Mantid/docs/source/concepts/Geometry_of_Position.rst
+++ b/Code/Mantid/docs/source/concepts/GeometryofPosition.rst
@@ -1,6 +1,6 @@
 .. _Geometry of Position:
 
-Geometry_of_Position
+Geometry of Position
 ====================
 
 What is it?
diff --git a/Code/Mantid/docs/source/concepts/Geometry_of_Shape.rst b/Code/Mantid/docs/source/concepts/GeometryofShape.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Geometry_of_Shape.rst
rename to Code/Mantid/docs/source/concepts/GeometryofShape.rst
diff --git a/Code/Mantid/docs/source/concepts/Instrument_Data_Service.rst b/Code/Mantid/docs/source/concepts/InstrumentDataService.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Instrument_Data_Service.rst
rename to Code/Mantid/docs/source/concepts/InstrumentDataService.rst
diff --git a/Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst b/Code/Mantid/docs/source/concepts/LETSampleIDF.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst
rename to Code/Mantid/docs/source/concepts/LETSampleIDF.rst
index 84f33546f669182a8992da0853dc0f8f8e92ee0a..cd8fc2847fce37ab09664f9e6f6047a4ba4b9607 100644
--- a/Code/Mantid/docs/source/concepts/LET_Sample_IDF.rst
+++ b/Code/Mantid/docs/source/concepts/LETSampleIDF.rst
@@ -3,7 +3,7 @@
 .. role:: xml(literal)
    :class: highlight
    
-IDF-ISIS-SANS2D-annotated
+IDF ISIS LET annotated
 =========================
 
 This page annotates the direct inelastic instrument LET, with the purpose of (hopefully) quickly learn the basis of creating a similar IDF. 
diff --git a/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst b/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst
index 96b00dbbdf396a62650d1d7bc944cc4c63ffc5e6..af2e92bd3ca3d6608ab213b244718959713c7c75 100644
--- a/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst
+++ b/Code/Mantid/docs/source/concepts/MDHistoWorkspace.rst
@@ -1,9 +1,9 @@
 .. _MDHistoWorkspace:
 
-MDHistoWorkspace
-================
+MD Histogram Workspace
+======================
 
-The MDHistoWorkspace is a simple multi-dimensional workspace. In
+The MD Histogram Workspace[MDHistoWorkspace] is a simple multi-dimensional workspace. In
 contrast to the :ref:`MDWorkspace <MDWorkspace>`, which contains
 points in space, the MDHistoWorkspace consists of a signal and error
 spread around space on a regular grid.
diff --git a/Code/Mantid/docs/source/concepts/MDWorkspace.rst b/Code/Mantid/docs/source/concepts/MDWorkspace.rst
index 0a0510e528fbb40e71d582d7e5a6a80699341cf8..1319e4009e67062c24557cfbbb8af78eb345a444 100644
--- a/Code/Mantid/docs/source/concepts/MDWorkspace.rst
+++ b/Code/Mantid/docs/source/concepts/MDWorkspace.rst
@@ -1,9 +1,9 @@
 .. _MDWorkspace:
 
-MDWorkspace
-===========
+MD Workspace
+============
 
-The MDWorkspace (short for "Multi-Dimensional" Workspace) is a generic
+The MD Workspace [MDWorkspace] (short for "Multi-Dimensional" Workspace) is a generic
 data structure holdings points (MDEvents) that are defined by their
 position in several dimensions. See also
 :ref:`MDHistoWorkspace <MDHistoWorkspace>`.
diff --git a/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst b/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst
index ff20b14741e329dc0b0cfedad1f1887584aaeb3e..244e23d5a98a093c09d39ad795340c9a7ec3d75d 100644
--- a/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst
+++ b/Code/Mantid/docs/source/concepts/MatrixWorkspace.rst
@@ -1,7 +1,7 @@
 .. _MatrixWorkspace:
 
-MatrixWorkspace
-===============
+Matrix Workspace
+================
 
 What information is in a MatrixWorkspace
 ----------------------------------------
diff --git a/Code/Mantid/docs/source/concepts/Nexus_file.rst b/Code/Mantid/docs/source/concepts/NexusFile.rst
similarity index 97%
rename from Code/Mantid/docs/source/concepts/Nexus_file.rst
rename to Code/Mantid/docs/source/concepts/NexusFile.rst
index 8c22396d56d76ffa003b01df862a56f9744b461e..9cf8a3c5a6ffab7383074736e5cb5f6e6e38b73d 100644
--- a/Code/Mantid/docs/source/concepts/Nexus_file.rst
+++ b/Code/Mantid/docs/source/concepts/NexusFile.rst
@@ -1,6 +1,6 @@
 .. _Nexus file:
 
-Nexus_file
+Nexus File
 ==========
 
 A **Nexus file** is a type of data file used by ISIS traget station 2
diff --git a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst
index e6a32575ab9aa7c40a5cf015f4f33603802fdf1e..d6c43dbd29df77dd17d972089f366459c41f7c73 100644
--- a/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst
+++ b/Code/Mantid/docs/source/concepts/PeaksWorkspace.rst
@@ -1,4 +1,6 @@
-PeaksWorkspace
+.. _PeaksWorkspace:
+
+Peaks Workspace
 ===============
 
 The PeaksWorkspace is a special Workspace that holds a list of single crystal Peak objects.
diff --git a/Code/Mantid/docs/source/concepts/Point_groups.rst b/Code/Mantid/docs/source/concepts/PointGroups.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/Point_groups.rst
rename to Code/Mantid/docs/source/concepts/PointGroups.rst
index e43e722665c1fc392a059bc285b7f3adff20c89d..4974ba3e280b785ff2c04a0e97d149a185beedf8 100644
--- a/Code/Mantid/docs/source/concepts/Point_groups.rst
+++ b/Code/Mantid/docs/source/concepts/PointGroups.rst
@@ -1,6 +1,6 @@
 .. _Point groups:
 
-Point groups
+Point Groups
 ============
 
 This document explains how crystallographic point groups are used in Mantid.
@@ -42,7 +42,7 @@ As mentioned before, point groups can describe the symmetry of a lattice, includ
 To describe the rotational and translational components of the symmetry operation, a matrix :math:`\mathbf{W}_i` and a vector :math:`\mathbf{w}_i` are used. In three dimensions :math:`\mathbf{h}` has three elements, so :math:`\mathbf{W}_i` is a :math:`3\times3`-matrix and the symmetry operation is applied like this:
 
 .. math::
-    \mathbf{h}' = \mathbf{W}_i^{-1}^T \cdot \mathbf{h}
+    \mathbf{h}' = \mathbf{W}_i^{-1T} \cdot \mathbf{h}
 
 Note that the translational component is not used for transforming HKLs and :math:`\mathbf{W}_i` is inverted and transposed. Coordinates :math:`\mathbf{x}` are transformed differently, they are affected by the translational component:
 
diff --git a/Code/Mantid/docs/source/concepts/Properties_File.rst b/Code/Mantid/docs/source/concepts/PropertiesFile.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Properties_File.rst
rename to Code/Mantid/docs/source/concepts/PropertiesFile.rst
diff --git a/Code/Mantid/docs/source/concepts/RAW_File.rst b/Code/Mantid/docs/source/concepts/RAWFile.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/RAW_File.rst
rename to Code/Mantid/docs/source/concepts/RAWFile.rst
index 1b917b56ab569d1b2059e9157abd3e1df3babe6c..b28f1a47b384ac9191111acae7a2428ade19465b 100644
--- a/Code/Mantid/docs/source/concepts/RAW_File.rst
+++ b/Code/Mantid/docs/source/concepts/RAWFile.rst
@@ -1,6 +1,6 @@
 .. _RAW File:
 
-RAW_File
+RAW File
 ========
 
 The RAW file format has been for many years the primary data format of
diff --git a/Code/Mantid/docs/source/concepts/RectangularDetector.rst b/Code/Mantid/docs/source/concepts/RectangularDetector.rst
index 99453e3a800eeb976686299007a4bee46ec8f0c3..c27036adf4a7f45e809a2910a71c063b3957cf08 100644
--- a/Code/Mantid/docs/source/concepts/RectangularDetector.rst
+++ b/Code/Mantid/docs/source/concepts/RectangularDetector.rst
@@ -1,7 +1,7 @@
 .. _RectangularDetector:
 
-RectangularDetector
-===================
+Rectangular Detector
+====================
 
 The rectangular detector is a detector bank that is marked as being a regular rectangular bank. It is a particular class in Mantid (RectangularDetector).
 
diff --git a/Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst b/Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst
rename to Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst
index ae95060335dd6b920f72e74a4f730c33044ce866..0982fccd04039c82e6dba0f0583da98e6e0d2e9d 100644
--- a/Code/Mantid/docs/source/concepts/SANS2D_Sample_IDF.rst
+++ b/Code/Mantid/docs/source/concepts/SANS2DSampleIDF.rst
@@ -4,7 +4,7 @@
 .. role:: xml(literal)
    :class: highlight
 
-IDF-ISIS-SANS2D-annotated
+IDF ISIS SANS2D annotated
 =========================
 
 This page annotates the small angle scattering SANS2D IDF, with the purpose of (hopefully) quickly learn the basis of creating a similar IDF.
diff --git a/Code/Mantid/docs/source/concepts/Shared_Pointer.rst b/Code/Mantid/docs/source/concepts/SharedPointer.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Shared_Pointer.rst
rename to Code/Mantid/docs/source/concepts/SharedPointer.rst
diff --git a/Code/Mantid/docs/source/concepts/Table_Workspaces.rst b/Code/Mantid/docs/source/concepts/TableWorkspaces.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Table_Workspaces.rst
rename to Code/Mantid/docs/source/concepts/TableWorkspaces.rst
diff --git a/Code/Mantid/docs/source/concepts/Unit_Factory.rst b/Code/Mantid/docs/source/concepts/UnitFactory.rst
similarity index 99%
rename from Code/Mantid/docs/source/concepts/Unit_Factory.rst
rename to Code/Mantid/docs/source/concepts/UnitFactory.rst
index 0dae6818787fe3b98874849562a59218a5a43c4d..9ab93a73903065006f7ac82c524852e4d65948ed 100644
--- a/Code/Mantid/docs/source/concepts/Unit_Factory.rst
+++ b/Code/Mantid/docs/source/concepts/UnitFactory.rst
@@ -1,6 +1,6 @@
 .. _Unit Factory:
 
-Unit_Factory
+Unit Factory
 ============
 
 What is it?
diff --git a/Code/Mantid/docs/source/concepts/Using_XML_Schema.rst b/Code/Mantid/docs/source/concepts/UsingXMLSchema.rst
similarity index 100%
rename from Code/Mantid/docs/source/concepts/Using_XML_Schema.rst
rename to Code/Mantid/docs/source/concepts/UsingXMLSchema.rst
diff --git a/Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst b/Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst
similarity index 98%
rename from Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst
rename to Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst
index 0fdc680fa1f7eafeb29cb3987293806524b8260f..c7241d46bbdfd4bca610281e99c33d3e282f94c2 100644
--- a/Code/Mantid/docs/source/concepts/Workflow_Algorithm.rst
+++ b/Code/Mantid/docs/source/concepts/WorkflowAlgorithm.rst
@@ -1,6 +1,6 @@
 .. _Workflow Algorithm:
 
-Workflow_Algorithm
+Workflow Algorithm
 ==================
 
 A workflow algorithm is a special subset of algorithms that perform
diff --git a/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst b/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst
index 7c095bcf14566161f0b99060cc49efdb233e96a3..467a65ceb38f59aa63850d477e11c0a8355b7aff 100644
--- a/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst
+++ b/Code/Mantid/docs/source/concepts/WorkspaceGroup.rst
@@ -1,7 +1,7 @@
 .. _WorkspaceGroup:
 
-WorkspaceGroup
-==============
+Workspace Group
+===============
 
 A WorkspaceGroup is a group of workspaces.
 
diff --git a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst
index 2b86b909ba4edab24db00a8e9ca2bcdf11748c06..30201258338fd85aa81809fbd695c9791c640b9f 100644
--- a/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst
+++ b/Code/Mantid/docs/source/interfaces/Indirect_DataAnalysis.rst
@@ -92,9 +92,9 @@ MSD Fit
   :widget: tabMSD
 
 Given either a saved NeXus file or workspace generated using the ElWin tab, this
-tab fits :math:`log(intensity)` vs. :math:`Q2` with a straight line for each run
-specified to give the Mean Square Displacement (MSD). It then plots the MSD as
-function of run number.
+tab fits :math:`log(intensity)` vs. :math:`Q^{2}` with a straight line for each
+run specified to give the Mean Square Displacement (MSD). It then plots the MSD
+as function of run number.
 
 MSDFit searches for the log files named <runnumber>_sample.txt in your chosen
 raw file directory (the name ‘sample’ is for OSIRIS). If they exist the
@@ -103,7 +103,7 @@ exist the MSD is plotted versus run number (last 3 digits).
 
 The fitted parameters for all runs are in _msd_Table and the <u2> in _msd. To
 run the Sequential fit a workspace named <inst><first-run>_to_<last-run>_lnI is
-created of :math:`ln(I)` v. :math:`Q2` for all runs. A contour or 3D plot of
+created of :math:`ln(I)` v. :math:`Q^{2}` for all runs. A contour or 3D plot of
 this may be of interest.
 
 A sequential fit is run by clicking the Run button at the bottom of the tab, a
diff --git a/Code/Mantid/instrument/LET_Parameters_dr2to12.xml b/Code/Mantid/instrument/LET_Parameters_dr2to12.xml
index 299501ef862dd8cd02e6e2c7b9f5abc33ee6a673..0404c64a28b719a95c9017711d82d3399a5573ba 100644
--- a/Code/Mantid/instrument/LET_Parameters_dr2to12.xml
+++ b/Code/Mantid/instrument/LET_Parameters_dr2to12.xml
@@ -128,7 +128,7 @@
      These detectors locations are used to identify TOF range, contributing into each energy range 
      in multirep mode  -->
 <parameter name="multirep_tof_specta_list"  type="string">
-    <value val="12416,21761"/>
+    <value val="1,128"/>
 </parameter>
 
 
diff --git a/Code/Mantid/instrument/MARI_Definition.xml b/Code/Mantid/instrument/MARI_Definition.xml
index 8f4aa117c1733876e4a94839a840e5107ae35916..ad7332298c5643d768cad43305e34e5e19d997f5 100644
--- a/Code/Mantid/instrument/MARI_Definition.xml
+++ b/Code/Mantid/instrument/MARI_Definition.xml
@@ -45,6 +45,12 @@
   
   <component type="fermi-chopper">
     <location y="-0.1" z="-1.689" />
+    <parameter name="Speed (Hz)">
+      <logfile id="fermi_speed" extract-single-value-as="last_value" />
+    </parameter>
+    <parameter name="Delay (us)">
+      <logfile id="fermi_delay" extract-single-value-as="last_value" />
+    </parameter>
   </component>
   <type name="fermi-chopper" is="chopper">
     <cylinder id="body">
@@ -57,6 +63,9 @@
   
   <component type="disc-chopper">
     <location y="-0.18" z="-3.0" />
+    <parameter name="Speed (Hz)">
+      <logfile id="diskchopper" extract-single-value-as="last_value" />
+    </parameter>
   </component>
   <type name="disc-chopper" is="chopper">
     <cylinder id="body">
diff --git a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py
index fd1318c9e6707dcb75146325f1518f75a441f079..0e261a7d34558240e0b0a1d8a04049259056691a 100644
--- a/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py
+++ b/Code/Mantid/scripts/Inelastic/Direct/dgreduce.py
@@ -3,7 +3,7 @@
 import Direct.DirectEnergyConversion as DRC
 from mantid.simpleapi import *
 from mantid.kernel import funcreturns
-
+from mantid import api
 
 # the class which is responsible for data reduction
 global Reducer
@@ -134,6 +134,7 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No
 # --------------------------------------------------------------------------------------------------------
     if sample_run:
         Reducer.sample_run = sample_run
+        sample_run = None
     try:
         n,r=funcreturns.lhs_info('both')
         wksp_out=r[0]
@@ -149,7 +150,37 @@ def arb_units(wb_run,sample_run,ei_guess,rebin,map_file='default',monovan_run=No
 
     return res
 
-
+def runs_are_equal(ws1,ws2):
+    """Compare two run numbers, provided either as run numbers, 
+       or as workspaces or as ws names"""
+    if ws1 == ws2:
+        return True
+    #-----------------------------------------------
+    def get_run_num(name_or_ws):
+        err = None
+        try:
+            if isinstance(name_or_ws,api.MatrixWorkspace):
+                run_num = name_or_ws.getRunNumber()
+            elif name_or_ws in mtd: # this is also throw Boost.Python.ArgumentError error if mtd not accepts it
+                ws = mtd[name_or_ws]
+                run_num = ws.getRunNumber()
+            else:
+                raise AttributeError
+        except Exception as err:
+            pass
+        if not err is None:
+            raise AttributeError("Input parameter is neither workspace nor ws name")
+        return run_num
+    #-----------------------------------------------
+    try:
+        run_num1 = get_run_num(ws1)
+    except AttributeError:
+        return False
+    try:
+        run_num2 = get_run_num(ws2)
+    except AttributeError:
+        return False
+    return run_num1==run_num2
 
 def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,samp_mass,ei_guess,rebin,map_file='default',monovan_mapfile='default',**kwargs):
     """
@@ -240,13 +271,14 @@ def abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,sam
 
     if sample_run:
         Reducer.sample_run = sample_run
+        sample_run = None
 
     try:
         n,r=funcreturns.lhs_info('both')
         results_name=r[0]
     except:
         results_name = Reducer.prop_man.get_sample_ws_name()
-    if wb_for_run == wb_for_monovanadium: # wb_for_monovanadium property does not accept duplicated workspace
+    if runs_are_equal(wb_for_run,wb_for_monovanadium):# wb_for_monovanadium property does not accept duplicated workspace
         wb_for_monovanadium = None        # if this value is none, it is constructed to be equal to wb_for_run
 
     wksp_out = arb_units(wb_for_run,sample_run,ei_guess,rebin,map_file,monovan_run,wb_for_monovanadium,**kwargs)
diff --git a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py
index a6a3af0d3dc368d454617dfe8a7ee90a887d9b21..54e34ca44457893d7b7090a436bc0127c658a5c8 100644
--- a/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py
+++ b/Code/Mantid/scripts/Inelastic/IndirectDataAnalysis.py
@@ -328,111 +328,6 @@ def furyfitPlotSeq(ws, plot):
     plotParameters(ws, *param_names)
 
 
-##############################################################################
-# MSDFit
-##############################################################################
-
-def msdfitPlotSeq(inputWS, xlabel):
-    workspace = mtd[inputWS + '_A1']
-    if len(workspace.readX(0)) > 1:
-        msd_plot = MTD_PLOT.plotSpectrum(inputWS+'_A1',0,True)
-        msd_layer = msd_plot.activeLayer()
-        msd_layer.setAxisTitle(MTD_PLOT.Layer.Bottom,xlabel)
-        msd_layer.setAxisTitle(MTD_PLOT.Layer.Left,'<u2>')
-
-def msdfit(ws, startX, endX, spec_min=0, spec_max=None, Save=False, Plot=True):
-    StartTime('msdFit')
-    workdir = getDefaultWorkingDirectory()
-
-    num_spectra = mtd[ws].getNumberHistograms()
-    if spec_max is None:
-        spec_max = num_spectra - 1
-
-    if spec_min < 0 or spec_max >= num_spectra:
-        raise ValueError("Invalid spectrum range: %d - %d" % (spec_min, spec_max))
-
-    xlabel = ''
-    ws_run = mtd[ws].getRun()
-
-    if 'vert_axis' in ws_run:
-        xlabel = ws_run.getLogData('vert_axis').value
-
-    mname = ws[:-4]
-    msdWS = mname+'_msd'
-
-    #fit line to each of the spectra
-    function = 'name=LinearBackground, A0=0, A1=0'
-    input_params = [ ws+',i%d' % i for i in xrange(spec_min, spec_max+1)]
-    input_params = ';'.join(input_params)
-    PlotPeakByLogValue(Input=input_params, OutputWorkspace=msdWS, Function=function,
-                       StartX=startX, EndX=endX, FitType='Sequential', CreateOutput=True)
-
-    DeleteWorkspace(msdWS + '_NormalisedCovarianceMatrices')
-    DeleteWorkspace(msdWS + '_Parameters')
-    msd_parameters = msdWS+'_Parameters'
-    RenameWorkspace(msdWS, OutputWorkspace=msd_parameters)
-
-    params_table = mtd[msd_parameters]
-
-    #msd value should be positive, but the fit output is negative
-    msd = params_table.column('A1')
-    for i, value in enumerate(msd):
-        params_table.setCell('A1', i, value * -1)
-
-    #create workspaces for each of the parameters
-    group = []
-
-    ws_name = msdWS + '_A0'
-    group.append(ws_name)
-    ConvertTableToMatrixWorkspace(msd_parameters, OutputWorkspace=ws_name,
-                                  ColumnX='axis-1', ColumnY='A0', ColumnE='A0_Err')
-    xunit = mtd[ws_name].getAxis(0).setUnit('Label')
-    xunit.setLabel('Temperature', 'K')
-
-    ws_name = msdWS + '_A1'
-    group.append(ws_name)
-    ConvertTableToMatrixWorkspace(msd_parameters, OutputWorkspace=ws_name,
-                                  ColumnX='axis-1', ColumnY='A1', ColumnE='A1_Err')
-
-    SortXAxis(ws_name, OutputWorkspace=ws_name)
-
-    xunit = mtd[ws_name].getAxis(0).setUnit('Label')
-    xunit.setLabel('Temperature', 'K')
-
-    GroupWorkspaces(InputWorkspaces=','.join(group),OutputWorkspace=msdWS)
-
-    #add sample logs to output workspace
-    fit_workspaces = msdWS + '_Workspaces'
-    CopyLogs(InputWorkspace=ws, OutputWorkspace=msdWS)
-    AddSampleLog(Workspace=msdWS, LogName="start_x", LogType="Number", LogText=str(startX))
-    AddSampleLog(Workspace=msdWS, LogName="end_x", LogType="Number", LogText=str(endX))
-    CopyLogs(InputWorkspace=msdWS + '_A0', OutputWorkspace=fit_workspaces)
-
-    if Plot:
-        msdfitPlotSeq(msdWS, xlabel)
-    if Save:
-        msd_path = os.path.join(workdir, msdWS+'.nxs')                  # path name for nxs file
-        SaveNexusProcessed(InputWorkspace=msdWS, Filename=msd_path, Title=msdWS)
-        logger.information('Output msd file : '+msd_path)
-
-    EndTime('msdFit')
-    return fit_workspaces
-
-def plotInput(inputfiles,spectra=[]):
-    OneSpectra = False
-    if len(spectra) != 2:
-        spectra = [spectra[0], spectra[0]]
-        OneSpectra = True
-    workspaces = []
-    for in_file in inputfiles:
-        root = LoadNexus(Filename=in_file)
-        if not OneSpectra:
-            GroupDetectors(root, root, DetectorList=range(spectra[0],spectra[1]+1) )
-        workspaces.append(root)
-    if len(workspaces) > 0:
-        graph = MTD_PLOT.plotSpectrum(workspaces,0)
-        graph.activeLayer().setTitle(", ".join(workspaces))
-
 ##############################################################################
 # Corrections
 ##############################################################################
diff --git a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py
index 9c8e3439a26d91c9d6b32940c8c18e0b1a7810b5..0b295c6293fba87977b75302c868818fa15fa996 100644
--- a/Code/Mantid/scripts/test/DirectEnergyConversionTest.py
+++ b/Code/Mantid/scripts/test/DirectEnergyConversionTest.py
@@ -183,8 +183,10 @@ class DirectEnergyConversionTest(unittest.TestCase):
         """ Test for old interface """
         run_ws = CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000)
         LoadInstrument(run_ws,InstrumentName='MARI')
+
         #mono_ws = CloneWorkspace(run_ws)
         wb_ws   = CloneWorkspace(run_ws)
+        AddSampleLog(wb_ws,LogName='run_number',LogText='300',LogType='Number')
         #wb_ws=CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000)
 
         dgreduce.setup('MAR')
@@ -199,6 +201,30 @@ class DirectEnergyConversionTest(unittest.TestCase):
         ws = dgreduce.abs_units(wb_ws,run_ws,None,wb_ws,10,100,8.8,[-10,0.1,7],None,None,**par)
         self.assertTrue(isinstance(ws,api.MatrixWorkspace))
 
+    def test_dgreduce_works_with_name(self):
+        """ Test for old interface """
+        run_ws = CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000)
+        LoadInstrument(run_ws,InstrumentName='MARI')
+        AddSampleLog(run_ws,LogName='run_number',LogText='200',LogType='Number')
+        #mono_ws = CloneWorkspace(run_ws)
+        wb_ws   = CloneWorkspace(run_ws)
+        AddSampleLog(wb_ws,LogName='run_number',LogText='100',LogType='Number')
+        #wb_ws=CreateSampleWorkspace( Function='Multiple Peaks', NumBanks=1, BankPixelWidth=4, NumEvents=10000)
+
+        dgreduce.setup('MAR')
+        par = {}
+        par['ei_mon_spectra']=[4,5]
+        par['abs_units_van_range']=[-4000,8000]
+        # overwrite parameters, which are necessary from command line, but we want them to have test values
+        dgreduce.getReducer().map_file=None
+        dgreduce.getReducer().monovan_mapfile=None
+        dgreduce.getReducer().mono_correction_factor = 1
+        #abs_units(wb_for_run,sample_run,monovan_run,wb_for_monovanadium,samp_rmm,samp_mass,ei_guess,rebin,map_file='default',monovan_mapfile='default',**kwargs):
+        ws = dgreduce.abs_units('wb_ws','run_ws',None,wb_ws,10,100,8.8,[-10,0.1,7],None,None,**par)
+        self.assertTrue(isinstance(ws,api.MatrixWorkspace))
+
+
+
     ##    tReducet.di
     def test_energy_to_TOF_range(self):
 
diff --git a/Code/Tools/DOI/authors.py b/Code/Tools/DOI/authors.py
index 98bc7ecc607318db22e531003d24ff620c3aff83..a9418f58841cc6fd56e6990321b7a60022516eda 100644
--- a/Code/Tools/DOI/authors.py
+++ b/Code/Tools/DOI/authors.py
@@ -73,7 +73,7 @@ _translations = {
     'Roman Tolchenov'         : 'Tolchenov, Roman',
     'MichaelWedel'            : 'Wedel, Michael',
     'Michael Wedel'           : 'Wedel, Michael',
-    'Ross Whitfield'          : 'Whitfield, Robert',
+    'Ross Whitfield'          : 'Whitfield, Ross',
     'Robert Whitley'          : 'Whitley, Robert',
     'Michael Whitty'          : 'Whitty, Michael',
     'Steve Williams'          : 'Williams, Steve',