diff --git a/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp b/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp
index 28cc8d5afa6c61d7ff0f47701ff07e8730e33405..72c78e9a0640d00b9b37ae04f22646331f814ce6 100644
--- a/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp
+++ b/Code/Mantid/Framework/CurveFitting/src/PlotPeakByLogValue.cpp
@@ -26,6 +26,7 @@
 #include "MantidAPI/CompositeFunction.h"
 #include "MantidAPI/TableRow.h"
 #include "MantidAPI/ITableWorkspace.h"
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidKernel/ListValidator.h"
 #include "MantidKernel/MandatoryValidator.h"
 
@@ -157,9 +158,11 @@ void PlotPeakByLogValue::exec() {
     result->addColumn("str", "Source name");
     isDataName = true;
   } else if (logName.empty()) {
-    result->addColumn("double", "axis-1");
+    auto col = result->addColumn("double", "axis-1");
+    col->setPlotType(1); // X-values inplots
   } else {
-    result->addColumn("double", logName);
+    auto col = result->addColumn("double", logName);
+    col->setPlotType(1); // X-values inplots
   }
   // Create an instance of the fitting function to obtain the names of fitting
   // parameters
@@ -227,7 +230,13 @@ void PlotPeakByLogValue::exec() {
       double logValue = 0;
       if (logName.empty()) {
         API::Axis *axis = data.ws->getAxis(1);
-        logValue = (*axis)(j);
+        if(dynamic_cast<BinEdgeAxis *>(axis)) {
+          double lowerEdge((*axis)(j));
+          double upperEdge((*axis)(j+1));
+          logValue = lowerEdge + (upperEdge - lowerEdge) / 2;
+        }
+        else
+          logValue = (*axis)(j);
       } else if (logName != "SourceName") {
         Kernel::Property *prop = data.ws->run().getLogData(logName);
         if (!prop) {
diff --git a/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h b/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h
index c94af2789dac1b146785a132707b9fb8acba2294..cc9be62a8b6aec56c8c2d4c3603c9be2f5208be9 100644
--- a/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h
+++ b/Code/Mantid/Framework/CurveFitting/test/PlotPeakByLogValueTest.h
@@ -14,6 +14,7 @@
 #include "MantidAPI/ParamFunction.h"
 #include "MantidAPI/FunctionFactory.h"
 #include "MantidAPI/WorkspaceGroup.h"
+#include "MantidAPI/BinEdgeAxis.h"
 #include "MantidKernel/TimeSeriesProperty.h"
 #include "MantidKernel/UnitFactory.h"
 
@@ -222,7 +223,6 @@ public:
     WorkspaceCreationHelper::removeWS("PlotPeakResult");
   }
 
-
   void testWorkspaceList_plotting_against_ws_names()
   {
     createData();
@@ -249,7 +249,32 @@ public:
 
     deleteData();
     WorkspaceCreationHelper::removeWS("PlotPeakResult");
+  }
+
+  void testSpectraList_plotting_against_bin_edge_axis()
+  {
+    auto ws = createTestWorkspace();
+    AnalysisDataService::Instance().add( "PLOTPEAKBYLOGVALUETEST_WS", ws );
+
+    PlotPeakByLogValue alg;
+    alg.initialize();
+    alg.setPropertyValue("Input","PLOTPEAKBYLOGVALUETEST_WS,i0;PLOTPEAKBYLOGVALUETEST_WS,i1");
+    alg.setPropertyValue("OutputWorkspace","PlotPeakResult");
+    alg.setPropertyValue("Function","name=LinearBackground,A0=1,A1=0.3;name=Gaussian,PeakCentre=5,Height=2,Sigma=0.1");
+    alg.execute();
+
+    TWS_type result =  WorkspaceCreationHelper::getWS<TableWorkspace>("PlotPeakResult");
+    TS_ASSERT_EQUALS(result->columnCount(),12);
 
+    std::vector<std::string> tnames = result->getColumnNames();
+    TS_ASSERT_EQUALS(tnames.size(),12);
+    TS_ASSERT_EQUALS(tnames[0],"axis-1");
+
+    TS_ASSERT_EQUALS(result->Double(0,0),0.5);
+    TS_ASSERT_EQUALS(result->Double(1,0),3.0);
+
+    WorkspaceCreationHelper::removeWS("PlotPeakResult");
+    WorkspaceCreationHelper::removeWS("PLOTPEAKBYLOGVALUETEST_WS");
   }
 
   void test_passWorkspaceIndexToFunction()
@@ -549,6 +574,14 @@ private:
     }
     testWS->setX(0, xdata);
     testWS->setX(1, xdata);
+
+    std::vector<double> edges;
+    edges.push_back(0.0);
+    edges.push_back(1.0);
+    edges.push_back(5.0);
+    BinEdgeAxis *axis = new BinEdgeAxis(edges);
+    testWS->replaceAxis(1, axis);
+
     return testWS;
   }
 
diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Memory.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Memory.h
index ad94db51ce2ccfa56e5339f2923922faceef4d01..4bb7be30c529e99f0366b7b8e84ad4d1d095ad02 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/Memory.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/Memory.h
@@ -57,6 +57,8 @@ public:
   std::size_t residentMem() const;
   std::size_t virtualMem() const;
   std::size_t reservedMem() const;
+  std::size_t getCurrentRSS() const;
+  std::size_t getPeakRSS() const;
   double getFreeRatio() const;
 
 private:
diff --git a/Code/Mantid/Framework/Kernel/src/Memory.cpp b/Code/Mantid/Framework/Kernel/src/Memory.cpp
index ad360465db7b7217055e2c18b2b1854d3e5061f1..a1f11272d0ac8ca2f642115b8bd1e441366ca495 100644
--- a/Code/Mantid/Framework/Kernel/src/Memory.cpp
+++ b/Code/Mantid/Framework/Kernel/src/Memory.cpp
@@ -9,10 +9,13 @@
 #include <unistd.h>
 #include <fstream>
 #include <malloc.h>
+#include <stdio.h>
+#include <sys/resource.h>
 #endif
 #ifdef __APPLE__
 #include <malloc/malloc.h>
 #include <sys/sysctl.h>
+#include <mach/mach.h>
 #include <mach/mach_host.h>
 #include <mach/task.h>
 #endif
@@ -130,13 +133,13 @@ void process_mem_usage(size_t &vm_usage, size_t &resident_set) {
  */
 bool read_mem_info(size_t &sys_avail, size_t &sys_total) {
   std::ifstream file("/proc/meminfo");
-  std::string line;
+  string line;
   int values_found(0);
   // Need to set this to zero
   sys_avail = 0;
   while (getline(file, line)) {
     std::istringstream is(line);
-    std::string tag;
+    string tag;
     long value(0);
     is >> tag >> value;
     if (!is)
@@ -411,7 +414,7 @@ size_t MemoryStats::availMem() const { return this->avail_memory; }
  * Returns the memory usage of the current process in kiB
  * @returns An unsigned containing the memory used by the current process in kiB
  */
-std::size_t MemoryStats::residentMem() const { return this->res_usage; }
+size_t MemoryStats::residentMem() const { return this->res_usage; }
 
 /**
  * Returns the virtual memory usage of the current process in kiB
@@ -419,7 +422,7 @@ std::size_t MemoryStats::residentMem() const { return this->res_usage; }
  * process in kiB
  */
 
-std::size_t MemoryStats::virtualMem() const { return this->vm_usage; }
+size_t MemoryStats::virtualMem() const { return this->vm_usage; }
 
 /**
  * Returns the reserved memory that has not been factored into the available
@@ -432,7 +435,7 @@ std::size_t MemoryStats::virtualMem() const { return this->vm_usage; }
  * memory calculation
  * @returns An extra area of memory that can still be allocated.
  */
-std::size_t MemoryStats::reservedMem() const {
+size_t MemoryStats::reservedMem() const {
 #ifdef _WIN32
   MEMORY_BASIC_INFORMATION info; // Windows structure
   char *addr = NULL;
@@ -486,6 +489,96 @@ std::ostream &operator<<(std::ostream &out, const MemoryStats &stats) {
   return out;
 }
 
+/**
+ * @returns the peak (maximum so far) resident set size (physical
+ * memory use) measured in bytes, or zero if the value cannot be
+ * determined on this OS.
+ *
+ * This was adopted from
+ *http://nadeausoftware.com/articles/2012/07/c_c_tip_how_get_process_resident_set_size_physical_memory_use
+ */
+size_t MemoryStats::getPeakRSS() const {
+#if defined(_WIN32)
+  /* Windows -------------------------------------------------- */
+  PROCESS_MEMORY_COUNTERS info;
+  GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
+  return (size_t)info.PeakWorkingSetSize;
+
+#elif(defined(_AIX) || defined(__TOS__AIX__)) ||                               \
+    (defined(__sun__) || defined(__sun) ||                                     \
+     defined(sun) && (defined(__SVR4) || defined(__svr4__)))
+  /* AIX and Solaris ------------------------------------------ */
+  struct psinfo psinfo;
+  int fd = -1;
+  if ((fd = open("/proc/self/psinfo", O_RDONLY)) == -1)
+    return (size_t)0L; /* Can't open? */
+  if (read(fd, &psinfo, sizeof(psinfo)) != sizeof(psinfo)) {
+    close(fd);
+    return (size_t)0L; /* Can't read? */
+  }
+  close(fd);
+  return (size_t)(psinfo.pr_rssize * 1024L);
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) ||                 \
+    (defined(__APPLE__) && defined(__MACH__))
+  /* BSD, Linux, and OSX -------------------------------------- */
+  struct rusage rusage;
+  getrusage(RUSAGE_SELF, &rusage);
+#if defined(__APPLE__) && defined(__MACH__)
+  return (size_t)rusage.ru_maxrss;
+#else
+  return (size_t)(rusage.ru_maxrss * 1024L);
+#endif
+
+#else
+  /* Unknown OS ----------------------------------------------- */
+  return (size_t)0L; /* Unsupported. */
+#endif
+}
+
+/**
+ * @returns the current resident set size (physical memory use) measured
+ * in bytes, or zero if the value cannot be determined on this OS.
+ *
+ * This was adopted from
+ *http://nadeausoftware.com/articles/2012/07/c_c_tip_how_get_process_resident_set_size_physical_memory_use
+ */
+size_t MemoryStats::getCurrentRSS() const {
+#if defined(_WIN32)
+  /* Windows -------------------------------------------------- */
+  PROCESS_MEMORY_COUNTERS info;
+  GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
+  return (size_t)info.WorkingSetSize;
+
+#elif defined(__APPLE__) && defined(__MACH__)
+  /* OSX ------------------------------------------------------ */
+  struct mach_task_basic_info info;
+  mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+  if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info,
+                &infoCount) != KERN_SUCCESS)
+    return (size_t)0L; /* Can't access? */
+  return (size_t)info.resident_size;
+
+#elif defined(__linux__) || defined(__linux) || defined(linux) ||              \
+    defined(__gnu_linux__)
+  /* Linux ---------------------------------------------------- */
+  long rss = 0L;
+  FILE *fp = NULL;
+  if ((fp = fopen("/proc/self/statm", "r")) == NULL)
+    return (size_t)0L; /* Can't open? */
+  if (fscanf(fp, "%*s%20ld", &rss) != 1) {
+    fclose(fp);
+    return (size_t)0L; /* Can't read? */
+  }
+  fclose(fp);
+  return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
+
+#else
+  /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
+  return (size_t)0L; /* Unsupported. */
+#endif
+}
+
 // -------------------------- concrete instantiations
 template DLLExport string memToString<uint32_t>(const uint32_t);
 template DLLExport string memToString<uint64_t>(const uint64_t);
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Memory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Memory.cpp
index 764c9b9cc4210788fa05eeaace23335fe3f2b8b9..46aad239e32e0b3cebd83ae3ca11ca510013c9b5 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Memory.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/src/Exports/Memory.cpp
@@ -7,11 +7,13 @@ using namespace boost::python;
 void export_MemoryStats() {
 
   class_<MemoryStats>("MemoryStats", init<>("Construct MemoryStats object."))
-      .def("update", &MemoryStats::update)
-      .def("totalMem", &MemoryStats::totalMem)
-      .def("availMem", &MemoryStats::availMem)
-      .def("residentMem", &MemoryStats::residentMem)
-      .def("virtualMem", &MemoryStats::virtualMem)
-      .def("reservedMem", &MemoryStats::reservedMem)
-      .def("getFreeRatio", &MemoryStats::getFreeRatio);
+      .def("update", &MemoryStats::update, args("self"))
+      .def("totalMem", &MemoryStats::totalMem, args("self"))
+      .def("availMem", &MemoryStats::availMem, args("self"))
+      .def("residentMem", &MemoryStats::residentMem, args("self"))
+      .def("virtualMem", &MemoryStats::virtualMem, args("self"))
+      .def("reservedMem", &MemoryStats::reservedMem, args("self"))
+      .def("getFreeRatio", &MemoryStats::getFreeRatio, args("self"))
+      .def("getCurrentRSS", &MemoryStats::getCurrentRSS, args("self"))
+      .def("getPeakRSS", &MemoryStats::getPeakRSS, args("self"));
 }
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py
index 7285abe4f676d36f3d0c687c4fe9d785843d07b1..de147bde8f794a7a787b822a0e9c8c5def0b3e0c 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/MSDFit.py
@@ -99,13 +99,18 @@ class MSDFit(DataProcessorAlgorithm):
         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)
+        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)
+        RenameWorkspace(self._output_msd_ws,
+                        OutputWorkspace=self._output_param_ws)
 
         params_table = mtd[self._output_param_ws]
 
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/ResNorm.py
similarity index 100%
rename from Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm.py
rename to Code/Mantid/Framework/PythonInterface/plugins/algorithms/ResNorm.py
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
index 918abd99d95b19c7b6bd7e82b3ba080c29cad760..8e046158a12cc9ac8c222cf45149bc8ab9b344be 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ElasticWindowMultiple.py
@@ -209,10 +209,11 @@ class ElasticWindowMultiple(DataProcessorAlgorithm):
             logger.notice('Vertical axis is in run number')
             unit = ('Run No', 'last 3 digits')
 
-        q_ws_axis = mtd[self._q_workspace].getAxis(1)
+        # Create a new vertical axis for the Q and Q**2 workspaces
+        q_ws_axis = NumericAxis.create(len(input_workspace_names))
         q_ws_axis.setUnit("Label").setLabel(unit[0], unit[1])
 
-        q2_ws_axis = mtd[self._q2_workspace].getAxis(1)
+        q2_ws_axis = NumericAxis.create(len(input_workspace_names))
         q2_ws_axis.setUnit("Label").setLabel(unit[0], unit[1])
 
         # Set the vertical axis values
@@ -224,6 +225,10 @@ class ElasticWindowMultiple(DataProcessorAlgorithm):
                 q_ws_axis.setValue(idx, float(run_numbers[idx][-3:]))
                 q2_ws_axis.setValue(idx, float(run_numbers[idx][-3:]))
 
+        # Add the new vertical axis to each workspace
+        mtd[self._q_workspace].replaceAxis(1, q_ws_axis)
+        mtd[self._q2_workspace].replaceAxis(1, q2_ws_axis)
+
         # Process the ELF workspace
         if self._elf_workspace != '':
             logger.information('Creating ELF workspace')
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PoldiDataAnalysis.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PoldiDataAnalysis.py
index 765d12c751604f0d974faf8e6c0f617bbce3e159..1a5d147fa66d0bb7b0992a29b675f904a34795d4 100644
--- a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PoldiDataAnalysis.py
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/PoldiDataAnalysis.py
@@ -81,6 +81,10 @@ class PoldiDataAnalysis(PythonAlgorithm):
                              doc=('If this is activated, plot the sum of residuals and calculated spectrum together '
                                   'with the theoretical spectrum and the residuals.'))
 
+        self.declareProperty("OutputIntegratedIntensities", False, direction=Direction.Input,
+                             doc=("If this option is checked the peak intensities of the 2D-fit will be integrated, "
+                                  "otherwise they will be the maximum intensity."))
+
         self.declareProperty('OutputRawFitParameters', False, direction=Direction.Input,
                              doc=('Activating this option produces an output workspace which contains the raw '
                                   'fit parameters.'))
@@ -97,6 +101,7 @@ class PoldiDataAnalysis(PythonAlgorithm):
         self.profileFunction = self.getProperty("ProfileFunction").value
         self.useGlobalParameters = self.getProperty("TieProfileParameters").value
         self.maximumRelativeFwhm = self.getProperty("MaximumRelativeFwhm").value
+        self.outputIntegratedIntensities = self.getProperty("OutputIntegratedIntensities").value
 
         self.globalParameters = ''
         if self.useGlobalParameters:
@@ -247,6 +252,7 @@ class PoldiDataAnalysis(PythonAlgorithm):
                         OutputWorkspace=spectrum2DName,
                         Calculated1DSpectrum=spectrum1DName,
                         RefinedPoldiPeakWorkspace=refinedPeaksName,
+                        OutputIntegratedIntensities=self.outputIntegratedIntensities,
                         RefinedCellParameters=refinedCellName,
                         RawFitParameters=rawFitParametersWorkspaceName)
 
diff --git a/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py
new file mode 100644
index 0000000000000000000000000000000000000000..0a22122c248f00cd4e96de38ea44822620e45d66
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/plugins/algorithms/WorkflowAlgorithms/ResNorm2.py
@@ -0,0 +1,202 @@
+#pylint: disable=no-init
+from mantid.api import (PythonAlgorithm, AlgorithmFactory, MatrixWorkspaceProperty,
+                        WorkspaceGroup, WorkspaceGroupProperty)
+from mantid.kernel import Direction
+from mantid.simpleapi import *
+
+
+class ResNorm(PythonAlgorithm):
+
+    _res_ws = None
+    _van_ws = None
+    _e_min = None
+    _e_max = None
+    _create_output = None
+    _out_ws = None
+
+
+    def category(self):
+        return "Workflow\\MIDAS;PythonAlgorithms"
+
+
+    def summary(self):
+        return """Creates a group normalisation file by taking a resolution file
+                  and fitting it to all the groups in the resolution (vanadium)
+                  reduction."""
+
+    def version(self):
+        return 2
+
+
+    def PyInit(self):
+        self.declareProperty(MatrixWorkspaceProperty('ResolutionWorkspace', '',
+                                                     direction=Direction.Input),
+                             doc='Workspace containing resolution')
+
+        self.declareProperty(MatrixWorkspaceProperty('VanadiumWorkspace', '',
+                                                     direction=Direction.Input),
+                             doc='Workspace containing reduction of vanadium run')
+
+        self.declareProperty(name='EnergyMin',
+                             defaultValue=-0.2,
+                             doc='Minimum energy for fit. Default=-0.2')
+
+        self.declareProperty(name='EnergyMax',
+                             defaultValue=0.2,
+                             doc='Maximum energy for fit. Default=0.2')
+
+        self.declareProperty(name='CreateOutput',
+                             defaultValue=False,
+                             doc='Create additional fitting output')
+
+        self.declareProperty(WorkspaceGroupProperty('OutputWorkspace', '',
+                                                    direction=Direction.Output),
+                             doc='Fitted parameter output')
+
+
+    def validateInputs(self):
+        self._get_properties()
+        issues = dict()
+
+        # Validate fitting range in energy
+        if self._e_min > self._e_max:
+            issues['EnergyMax'] = 'Must be less than EnergyMin'
+
+        res_ws = mtd[self._res_ws]
+        # Can't use a WorkspaceGroup for resolution
+        if isinstance(res_ws, WorkspaceGroup):
+            issues['ResolutionWorkspace'] = 'Must be a MatrixWorkspace'
+
+        # Resolution should only have one histogram
+        elif mtd[self._res_ws].getNumberHistograms() != 1:
+            issues['ResolutionWorkspace'] = 'Must have exactly one histogram'
+
+        return issues
+
+
+    def _get_properties(self):
+        self._res_ws = self.getPropertyValue('ResolutionWorkspace')
+        self._van_ws = self.getPropertyValue('VanadiumWorkspace')
+        self._e_min = self.getProperty('EnergyMin').value
+        self._e_max = self.getProperty('EnergyMax').value
+        self._create_output = self.getProperty('CreateOutput').value
+        self._out_ws = self.getPropertyValue('OutputWorkspace')
+
+
+    def PyExec(self):
+        from IndirectCommon import getWSprefix
+
+        # Process vanadium workspace
+        van_ws = ConvertSpectrumAxis(InputWorkspace=self._van_ws,
+                                     OutputWorkspace='__ResNorm_vanadium',
+                                     Target='ElasticQ',
+                                     EMode='Indirect')
+
+        num_hist = van_ws.getNumberHistograms()
+
+        v_values = van_ws.getAxis(1).extractValues()
+        v_unit = van_ws.getAxis(1).getUnit().unitID()
+
+        # Process resolution workspace
+        padded_res_ws = self._process_res_ws(num_hist)
+
+        input_str = ''
+        for idx in range(num_hist):
+            input_str += '%s,i%d;' % (padded_res_ws, idx)
+
+        out_name = getWSprefix(self._res_ws) + 'ResNorm_Fit'
+        function = 'name=TabulatedFunction,Workspace=%s,Scaling=1,Shift=0,XScaling=1,ties=(Shift=0)' % self._van_ws
+
+        fit_params = PlotPeakByLogValue(Input=input_str,
+                                        OutputWorkspace=out_name,
+                                        Function=function,
+                                        FitType='Individual',
+                                        PassWSIndexToFunction=True,
+                                        CreateOutput=self._create_output,
+                                        StartX=self._e_min,
+                                        EndX=self._e_max)
+
+        params = {'XScaling':'Stretch', 'Scaling':'Intensity'}
+        result_workspaces = []
+        for param_name, output_name in params.items():
+            result_workspaces.append(self._process_fit_params(fit_params, param_name, v_values, v_unit, output_name))
+
+        GroupWorkspaces(InputWorkspaces=result_workspaces,
+                        OutputWorkspace=self._out_ws)
+        self.setProperty('OutputWorkspace', self._out_ws)
+
+        DeleteWorkspace(van_ws)
+        DeleteWorkspace(padded_res_ws)
+        if not self._create_output:
+            DeleteWorkspace(fit_params)
+
+
+    def _process_res_ws(self, num_hist):
+        """
+        Generate a resolution workspaes with the same number of histograms
+        as the vanadium run, with area normalised to 1.
+
+        @param num_hist Number of histograms required
+        @return Padded workspace
+        """
+
+        norm_res_ws = '__ResNorm_unityres'
+        NormaliseToUnity(InputWorkspace=self._res_ws,
+                         OutputWorkspace=norm_res_ws)
+
+        ws_name = '__ResNorm_res_%s_%dspec' % (self._res_ws, num_hist)
+
+        for idx in range(num_hist):
+            input_ws_1 = ws_name
+            if idx == 0:
+                input_ws_1 = norm_res_ws
+
+            AppendSpectra(InputWorkspace1=input_ws_1,
+                          InputWorkspace2=norm_res_ws,
+                          OutputWorkspace=ws_name)
+
+        DeleteWorkspace(norm_res_ws)
+
+        return mtd[ws_name]
+
+
+    #pylint: disable=too-many-arguments
+    def _process_fit_params(self, fit_params, parameter_name, x_axis, x_unit, workspace_suffix=None):
+        """
+        Generate the output workspace containing fit parameters using the
+        fit parameter table from PlotPeakByLogValue.
+
+        @param fit_params Fit parameters as table workspace
+        @param parameter_name Parameter name to extract
+        @param x_axis Values for X axis of output workspace
+        @param x_unit Unit for X axis of output workspace
+        @param workspace_suffix Suffix of result workspace name
+        """
+
+        if workspace_suffix is None:
+            workspace_suffix = parameter_name
+
+        col_names = fit_params.getColumnNames()
+
+        y_values = []
+        e_values = []
+
+        y_values = fit_params.column(col_names.index(parameter_name))
+        e_values = fit_params.column(col_names.index(parameter_name + '_Err'))
+
+        ws_name = self._out_ws + '_' + workspace_suffix
+
+        CreateWorkspace(OutputWorkspace=ws_name,
+                        DataX=x_axis,
+                        DataY=y_values,
+                        DataE=e_values,
+                        NSpec=1,
+                        UnitX=x_unit,
+                        VerticalAxisUnit='Text',
+                        VerticalAxisValues=[parameter_name])
+
+        return ws_name
+
+
+# Register algorithm with Mantid
+AlgorithmFactory.subscribe(ResNorm)
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 9e32c9b72529524f47858b2d3e16e2ebf39ddc2f..9d46caf2c6746cbbb9a5b084ae3ecd6375639161 100644
--- a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/CMakeLists.txt
@@ -47,6 +47,7 @@ set ( TEST_PY_FILES
   MolDynTest.py
   MSDFitTest.py
   PDDetermineCharacterizationsTest.py
+  ResNorm2Test.py
   RetrieveRunInfoTest.py
   SANSWideAngleCorrectionTest.py
   SavePlot1DTest.py
diff --git a/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ResNorm2Test.py b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ResNorm2Test.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d974788fee7016b3b8d01ff0c19498bf22b0913
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/test/python/plugins/algorithms/ResNorm2Test.py
@@ -0,0 +1,75 @@
+import unittest
+from mantid.simpleapi import *
+from mantid.api import MatrixWorkspace, WorkspaceGroup
+
+
+class ResNorm2Test(unittest.TestCase):
+
+    _res_ws = None
+    _van_ws = None
+
+
+    def setUp(self):
+        self._res_ws = Load(Filename='irs26173_graphite002_res.nxs',
+                            OutputWorkspace='__ResNormTest_Resolution')
+        self._van_ws = Load(Filename='irs26173_graphite002_red.nxs',
+                            OutputWorkspace='__ResNormTest_Vanadium')
+
+
+    def _validate_result(self, result):
+        """
+        Validates that the result workspace is of the correct type, units and shape.
+
+        @param result Result workspace form ResNorm
+        """
+
+        self.assertTrue(isinstance(result, WorkspaceGroup))
+        self.assertEquals(result.getNumberOfEntries(), 2)
+
+        expected_names = [result.name() + '_' + n for n in ['Intensity', 'Stretch']]
+        for name in expected_names:
+            self.assertTrue(name in result.getNames())
+
+        for idx in range(result.getNumberOfEntries()):
+            sub_ws = result.getItem(idx)
+            self.assertTrue(isinstance(sub_ws, MatrixWorkspace))
+            self.assertEqual(sub_ws.blocksize(), self._van_ws.getNumberHistograms())
+            self.assertEquals(sub_ws.getAxis(0).getUnit().unitID(), 'MomentumTransfer')
+
+
+    def test_basic(self):
+        """
+        Tests a basic run of ResNorm.
+        """
+        result = ResNorm(ResolutionWorkspace=self._res_ws,
+                         VanadiumWorkspace=self._van_ws,
+                         Version=2)
+        self._validate_result(result)
+
+
+    def test_with_limits(self):
+        """
+        Tests a basic run of ResNorm with energy limits.
+        """
+        result = ResNorm(ResolutionWorkspace=self._res_ws,
+                         VanadiumWorkspace=self._van_ws,
+                         EnergyMin=-0.1,
+                         EnergyMax=0.1,
+                         Version=2)
+        self._validate_result(result)
+
+
+    def test_with_bad_limits(self):
+        """
+        Tests validation for energy range.
+        """
+        self.assertRaises(RuntimeError, ResNorm,
+                          ResolutionWorkspace=self._res_ws,
+                          VanadiumWorkspace=self._van_ws,
+                          EnergyMin=0.1,
+                          EnergyMax=-0.1,
+                          Version=2)
+
+
+if __name__=="__main__":
+    unittest.main()
diff --git a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
index 6f7a0af47eec43203941c19348339fa12a68245e..df7b16d2aebb20a9fadc16a13f9a582e533d8499 100644
--- a/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
+++ b/Code/Mantid/Framework/SINQ/src/PoldiFitPeaks2D.cpp
@@ -398,19 +398,28 @@ PoldiFitPeaks2D::getPeakFromPeakFunction(IPeakFunction_sptr profileFunction,
   errorAlg->execute();
 
   double centre = profileFunction->centre();
-  double height = profileFunction->height();
   double fwhmValue = profileFunction->fwhm();
 
   ITableWorkspace_sptr errorTable = errorAlg->getProperty("OutputWorkspace");
-
   double centreError = errorTable->cell<double>(0, 2);
-  double heightError = errorTable->cell<double>(1, 2);
   double fwhmError = errorTable->cell<double>(2, 2);
 
   UncertainValue d(centre, centreError);
-  UncertainValue intensity(height, heightError);
   UncertainValue fwhm(fwhmValue, fwhmError);
 
+  UncertainValue intensity;
+
+  bool useIntegratedIntensities = getProperty("OutputIntegratedIntensities");
+  if (useIntegratedIntensities) {
+    double integratedIntensity = profileFunction->intensity();
+    double integratedIntensityError = errorTable->cell<double>(3, 2);
+    intensity = UncertainValue(integratedIntensity, integratedIntensityError);
+  } else {
+    double height = profileFunction->height();
+    double heightError = errorTable->cell<double>(1, 2);
+    intensity = UncertainValue(height, heightError);
+  }
+
   // Create peak with extracted parameters and supplied hkl
   PoldiPeak_sptr peak =
       PoldiPeak::create(MillerIndices(hkl), d, intensity, UncertainValue(1.0));
@@ -1215,6 +1224,11 @@ void PoldiFitPeaks2D::init() {
                                                    "", Direction::Output),
                   "Table workspace with fitted peaks.");
 
+  declareProperty("OutputIntegratedIntensities", false,
+                  "If this option is checked, the peaks in the algorithm's "
+                  "output will have integrated intensities instead of the "
+                  "maximum.");
+
   declareProperty(new WorkspaceProperty<Workspace>(
       "RefinedCellParameters", "", Direction::Output, PropertyMode::Optional));
 
diff --git a/Code/Mantid/MantidPlot/make_package.rb.in b/Code/Mantid/MantidPlot/make_package.rb.in
index afab0d3b60844b00e4b7bade807835eea796d039..1d52b0a5615bd1f87251fc793d272b563a853cc4 100755
--- a/Code/Mantid/MantidPlot/make_package.rb.in
+++ b/Code/Mantid/MantidPlot/make_package.rb.in
@@ -204,12 +204,12 @@ end
 #Copy over python libraries not included with OSX. 
 #currently missing epics
 path = "/Library/Python/2.7/site-packages"
-directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil"]
+directories = ["sphinx","sphinx_bootstrap_theme","IPython","zmq","pygments","backports","certifi","tornado","markupsafe","jinja2","psutil","jsonschema","functools32","ptyprocess"]
 directories.each do |directory|
   addPythonLibrary("#{path}/#{directory}")
 end
 
-files = ["gnureadline.so","readline.py","pyparsing.py"]
+files = ["gnureadline.so","readline.py","pyparsing.py","mistune.py","mistune.so"]
 files.each do |file|
   copyFile("#{path}/#{file}")
 end
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit/MultiDatasetFit.h b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit/MultiDatasetFit.h
index dc99c26083257f54aff33cd7fbb63838793d855c..c89adb98b1243722541ae8ed799ce3fd6172c165 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit/MultiDatasetFit.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/inc/MantidQtCustomInterfaces/MultiDatasetFit/MultiDatasetFit.h
@@ -88,6 +88,8 @@ private slots:
   void enableZoom();
   void enablePan();
   void enableRange();
+  void checkFittingType();
+  void setLogNames();
 
 protected:
   virtual void initLayout();
@@ -104,6 +106,8 @@ private:
   void removeSpectra(QList<int> rows);
   void loadSettings();
   void saveSettings() const;
+  void fitSequential();
+  void fitSimultaneous();
 
   /// The form generated by Qt Designer
   Ui::MultiDatasetFit m_uiForm;
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MDFPlotController.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MDFPlotController.cpp
index 07d64ae00c11981ab67a1891b4bbbe31e5938ee4..79717f8541fe074679783154b91765cc2ce2c622 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MDFPlotController.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MDFPlotController.cpp
@@ -5,6 +5,8 @@
 #include "MantidQtCustomInterfaces/MultiDatasetFit/MDFDatasetPlotData.h"
 
 #include "MantidQtMantidWidgets/RangeSelector.h"
+#include "MantidAPI/AnalysisDataService.h"
+#include "MantidAPI/WorkspaceGroup.h"
 
 #include <boost/make_shared.hpp>
 
@@ -115,12 +117,15 @@ boost::shared_ptr<DatasetPlotData> PlotController::getData(int index)
     QString wsName = m_table->item( index, wsColumn )->text();
     int wsIndex = m_table->item( index, wsIndexColumn )->text().toInt();
     QString outputWorkspaceName = owner()->getOutputWorkspaceName();
-    if ( !outputWorkspaceName.isEmpty() )
-    {
-      outputWorkspaceName += QString("_%1").arg(index);
+    std::string outName = outputWorkspaceName.toStdString();
+    if (!outputWorkspaceName.isEmpty() &&
+        Mantid::API::AnalysisDataService::Instance().doesExist(outName)) {
+      auto ws = Mantid::API::AnalysisDataService::Instance().retrieve(outName);
+      if (auto  group = boost::dynamic_pointer_cast<Mantid::API::WorkspaceGroup>(ws)) {
+        outputWorkspaceName = QString::fromStdString(group->getItem(index)->name());
+      }
     }
-    try
-    {
+    try {
       data = boost::make_shared<DatasetPlotData>( wsName, wsIndex, outputWorkspaceName );
       m_plotData.insert(index, data );
     }
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
index 03065dd8bff32ada7e34d99dc2e724cec80e7c28..a8d5f4f86c76c36ba01a247d352fab6555c62b72 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/MultiDatasetFit/MultiDatasetFit.cpp
@@ -4,6 +4,9 @@
 #include "MantidQtCustomInterfaces/MultiDatasetFit/MDFEditLocalParameterDialog.h"
 
 #include "MantidAPI/AlgorithmManager.h"
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/ITableWorkspace.h"
+#include "MantidKernel/TimeSeriesProperty.h"
 
 #include "MantidQtAPI/AlgorithmRunner.h"
 #include "MantidQtMantidWidgets/FitOptionsBrowser.h"
@@ -72,6 +75,7 @@ void MultiDatasetFit::initLayout()
                                         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_dataController,SIGNAL(dataTableUpdated()),this,SLOT(setLogNames()));
   connect(m_plotController,SIGNAL(fittingRangeChanged(int, double, double)),m_dataController,SLOT(setFittingRange(int, double, double)));
   connect(m_uiForm.cbShowDataErrors,SIGNAL(toggled(bool)),m_plotController,SLOT(showDataErrors(bool)));
   connect(m_uiForm.btnToVisibleRange,SIGNAL(clicked()),m_plotController,SLOT(resetRange()));
@@ -84,12 +88,15 @@ void MultiDatasetFit::initLayout()
   splitter->addWidget( m_functionBrowser );
   connect(m_functionBrowser,SIGNAL(localParameterButtonClicked(const QString&)),this,SLOT(editLocalParameterValues(const QString&)));
   connect(m_functionBrowser,SIGNAL(functionStructureChanged()),this,SLOT(reset()));
+  connect(m_functionBrowser,SIGNAL(globalsChanged()),this,SLOT(checkFittingType()));
   connect(m_plotController,SIGNAL(currentIndexChanged(int)),m_functionBrowser,SLOT(setCurrentDataset(int)));
   connect(m_dataController,SIGNAL(spectraRemoved(QList<int>)),m_functionBrowser,SLOT(removeDatasets(QList<int>)));
   connect(m_dataController,SIGNAL(spectraAdded(int)),m_functionBrowser,SLOT(addDatasets(int)));
 
-  m_fitOptionsBrowser = new MantidQt::MantidWidgets::FitOptionsBrowser(NULL);
-  splitter->addWidget( m_fitOptionsBrowser );
+  m_fitOptionsBrowser = new MantidQt::MantidWidgets::FitOptionsBrowser(
+      NULL, MantidQt::MantidWidgets::FitOptionsBrowser::SimultaneousAndSequential);
+  connect(m_fitOptionsBrowser,SIGNAL(changedToSequentialFitting()),this,SLOT(setLogNames()));
+  splitter->addWidget(m_fitOptionsBrowser);
 
   m_uiForm.browserLayout->addWidget( splitter );
 
@@ -149,15 +156,54 @@ boost::shared_ptr<Mantid::API::IFunction> MultiDatasetFit::createFunction() cons
   return m_functionBrowser->getGlobalFunction();
 }
 
-/// Run the fitting algorithm.
-void MultiDatasetFit::fit()
+/// Fit the data sets sequentially if there are no global parameters.
+void MultiDatasetFit::fitSequential()
 {
-  if ( !m_functionBrowser->hasFunction() )
+  try
   {
-    QMessageBox::warning( this, "MantidPlot - Warning","Function wasn't set." );
-    return;
+    std::ostringstream input;
+
+    int n = getNumberOfSpectra();
+    for(int ispec = 0; ispec < n; ++ispec)
+    {
+      input << getWorkspaceName(ispec) << ",i" << getWorkspaceIndex(ispec) << ";";
+    }
+
+    auto fun = m_functionBrowser->getFunction();
+    auto fit = Mantid::API::AlgorithmManager::Instance().create("PlotPeakByLogValue");
+    fit->initialize();
+    fit->setPropertyValue("Function", fun->asString() );
+    fit->setPropertyValue("Input", input.str());
+    auto range = getFittingRange(0);
+    fit->setProperty( "StartX", range.first );
+    fit->setProperty( "EndX", range.second );
+
+    m_fitOptionsBrowser->copyPropertiesToAlgorithm(*fit);
+
+    m_outputWorkspaceName = m_fitOptionsBrowser->getProperty("OutputWorkspace").toStdString() + "_Workspaces";
+
+    m_fitRunner.reset( new API::AlgorithmRunner() );
+    connect( m_fitRunner.get(),SIGNAL(algorithmComplete(bool)), this, SLOT(finishFit(bool)), Qt::QueuedConnection );
+
+    m_fitRunner->startAlgorithm(fit);
+
+  }
+  catch(std::exception& e)
+  {
+    QString mess(e.what());
+    const int maxSize = 500;
+    if ( mess.size() > maxSize )
+    {
+      mess = mess.mid(0,maxSize);
+      mess += "...";
+    }
+    QMessageBox::critical( this, "MantidPlot - Error", QString("PlotPeakByLogValue failed:\n\n  %1").arg(mess) );
   }
+}
 
+/// Fit the data simultaneously.
+void MultiDatasetFit::fitSimultaneous()
+{
   try
   {
     auto fun = createFunction();
@@ -190,7 +236,7 @@ void MultiDatasetFit::fit()
       fit->setPropertyValue("Output",m_outputWorkspaceName);
       m_fitOptionsBrowser->setProperty("Output","out");
     }
-    m_outputWorkspaceName += "_Workspace";
+    m_outputWorkspaceName += "_Workspaces";
 
     m_fitRunner.reset( new API::AlgorithmRunner() );
     connect( m_fitRunner.get(),SIGNAL(algorithmComplete(bool)), this, SLOT(finishFit(bool)), Qt::QueuedConnection );
@@ -211,6 +257,31 @@ void MultiDatasetFit::fit()
   }
 }
 
+/// Run the fitting algorithm.
+void MultiDatasetFit::fit()
+{
+  if ( !m_functionBrowser->hasFunction() )
+  {
+    QMessageBox::warning( this, "MantidPlot - Warning","Function wasn't set." );
+    return;
+  }
+
+  auto fittingType = m_fitOptionsBrowser->getCurrentFittingType();
+  
+  if (fittingType == MantidWidgets::FitOptionsBrowser::Simultaneous)
+  {
+    fitSimultaneous();
+  }
+  else if (fittingType == MantidWidgets::FitOptionsBrowser::Sequential)
+  {
+    fitSequential();
+  }
+  else
+  {
+    throw std::logic_error("Unrecognised fitting type. Only Normal and Sequential are accepted.");
+  }
+}
+
 /// Get the workspace name of the i-th spectrum.
 /// @param i :: Index of a spectrum in the data table.
 std::string MultiDatasetFit::getWorkspaceName(int i) const
@@ -264,8 +335,37 @@ void MultiDatasetFit::finishFit(bool error)
   {
     m_plotController->clear();
     m_plotController->update();
-    Mantid::API::IFunction_sptr fun = m_fitRunner->getAlgorithm()->getProperty("Function");
-    updateParameters( *fun );
+    Mantid::API::IFunction_sptr fun;
+    if (m_fitOptionsBrowser->getCurrentFittingType() == MantidWidgets::FitOptionsBrowser::Simultaneous)
+    {
+      fun = m_fitRunner->getAlgorithm()->getProperty("Function");
+      updateParameters( *fun );
+    }
+    else 
+    {
+      auto paramsWSName = m_fitOptionsBrowser->getProperty("OutputWorkspace").toStdString();
+      if (!Mantid::API::AnalysisDataService::Instance().doesExist(paramsWSName)) return;
+      size_t nSpectra = getNumberOfSpectra();
+      if (nSpectra == 0) return;
+      fun = m_functionBrowser->getGlobalFunction();
+      auto nParams = fun->nParams() / nSpectra;
+      auto params = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::ITableWorkspace>(paramsWSName);
+      if (nParams * 2 + 2 != params->columnCount())
+      {
+        throw std::logic_error("Output table workspace has unexpected number of columns.");
+      }
+      for(size_t index = 0; index < nSpectra; ++index)
+      {
+        std::string prefix = "f" + boost::lexical_cast<std::string>(index) + ".";
+        for(size_t ip = 0; ip < nParams; ++ip)
+        {
+          auto colIndex = ip * 2 + 1;
+          auto column = params->getColumn(colIndex);
+          fun->setParameter(prefix + column->name(), column->toDouble(index));
+        }
+      }
+      updateParameters( *fun );
+    }
   }
 }
 
@@ -455,5 +555,49 @@ void MultiDatasetFit::saveSettings() const
   settings.setValue("ApplyRangeToAll",m_uiForm.cbApplyRangeToAll->isChecked());
 }
 
+/// Make sure that simultaneous fitting is on
+/// when the function has at least one global parameter.
+void MultiDatasetFit::checkFittingType()
+{
+  auto globals = m_functionBrowser->getGlobalParameters();
+  if (globals.isEmpty())
+  {
+    m_fitOptionsBrowser->unlockCurrentFittingType();
+  }
+  else
+  {
+    m_fitOptionsBrowser->lockCurrentFittingType(MantidWidgets::FitOptionsBrowser::Simultaneous);
+  }
+}
+
+/**
+ * Collect names of the logs in the data workspaces and pass them on to m_fitOptionsBrowser.
+ */
+void MultiDatasetFit::setLogNames()
+{
+  if (getNumberOfSpectra() > 0)
+  {
+    try
+    {
+      auto ws = Mantid::API::AnalysisDataService::Instance().retrieveWS<Mantid::API::MatrixWorkspace>(getWorkspaceName(0));
+      const std::vector<Mantid::Kernel::Property*> logs = ws->run().getLogData();
+      QStringList logNames;
+      for(int i=0;i<static_cast<int>(logs.size());++i)
+      {
+        if (dynamic_cast<Mantid::Kernel::TimeSeriesProperty<double>*>(logs[i]))
+        {
+          logNames << QString::fromStdString(logs[i]->name());
+        }
+      }
+      if (!logNames.isEmpty())
+      {
+        m_fitOptionsBrowser->setLogNames(logNames);
+      }
+    }
+    catch (...) 
+    {/*Maybe the data table hasn't updated yet*/}
+  }
+}
+
 } // CustomInterfaces
 } // MantidQt
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingModel.cpp b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingModel.cpp
index dd2f753aade53571bc7c06d640db57707b02b9bf..ab69c56ceb3c1de9d1a8c74cafa9b3619fccfa7d 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingModel.cpp
+++ b/Code/Mantid/MantidQt/CustomInterfaces/src/Muon/ALCBaselineModellingModel.cpp
@@ -172,26 +172,34 @@ namespace CustomInterfaces
 
   MatrixWorkspace_const_sptr ALCBaselineModellingModel::data() const
   {
-    IAlgorithm_sptr extract = AlgorithmManager::Instance().create("ExtractSingleSpectrum");
-    extract->setChild(true);
-    extract->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_data));
-    extract->setProperty("WorkspaceIndex", 0);
-    extract->setProperty("OutputWorkspace", "__NotUsed__");
-    extract->execute();
-    MatrixWorkspace_const_sptr result = extract->getProperty("OutputWorkspace");
-    return result;
+    if (m_data) {
+      IAlgorithm_sptr extract = AlgorithmManager::Instance().create("ExtractSingleSpectrum");
+      extract->setChild(true);
+      extract->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_data));
+      extract->setProperty("WorkspaceIndex", 0);
+      extract->setProperty("OutputWorkspace", "__NotUsed__");
+      extract->execute();
+      MatrixWorkspace_const_sptr result = extract->getProperty("OutputWorkspace");
+      return result;
+    } else {
+      return MatrixWorkspace_const_sptr();
+    }
   }
 
   MatrixWorkspace_const_sptr ALCBaselineModellingModel::correctedData() const
   {
-    IAlgorithm_sptr extract = AlgorithmManager::Instance().create("ExtractSingleSpectrum");
-    extract->setChild(true);
-    extract->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_data));
-    extract->setProperty("WorkspaceIndex", 2);
-    extract->setProperty("OutputWorkspace", "__NotUsed__");
-    extract->execute();
-    MatrixWorkspace_const_sptr result = extract->getProperty("OutputWorkspace");
-    return result;
+    if (m_data && (m_data->getNumberHistograms()==3) ) {
+      IAlgorithm_sptr extract = AlgorithmManager::Instance().create("ExtractSingleSpectrum");
+      extract->setChild(true);
+      extract->setProperty("InputWorkspace", boost::const_pointer_cast<MatrixWorkspace>(m_data));
+      extract->setProperty("WorkspaceIndex", 2);
+      extract->setProperty("OutputWorkspace", "__NotUsed__");
+      extract->execute();
+      MatrixWorkspace_const_sptr result = extract->getProperty("OutputWorkspace");
+      return result;
+    } else {
+      return MatrixWorkspace_const_sptr();
+    }
   }
 
 } // namespace CustomInterfaces
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingModelTest.h b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingModelTest.h
index d9cb119841ca2ce481a305e963d4057206240b4c..724760d3469d7614736e3176ff31c8961bad4d75 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingModelTest.h
+++ b/Code/Mantid/MantidQt/CustomInterfaces/test/ALCBaselineModellingModelTest.h
@@ -145,6 +145,16 @@ public:
     TS_ASSERT_THROWS_NOTHING(m_model->exportModel());
   }
 
+  void test_noData()
+  {
+    // Set a null shared pointer
+    MatrixWorkspace_const_sptr data = MatrixWorkspace_const_sptr();
+    m_model->setData(data);
+
+    TS_ASSERT_THROWS_NOTHING(m_model->data());
+    TS_ASSERT_THROWS_NOTHING(m_model->correctedData());
+  }
+
 };
 
 
diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
index a8f1429c57de969b5e52759a0c78aedbc4f23cc7..cd156c85a0dec4456553d01b46ed22118cfb6fd7 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
+++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FitOptionsBrowser.h
@@ -43,13 +43,28 @@ class EXPORT_OPT_MANTIDQT_MANTIDWIDGETS FitOptionsBrowser: public QWidget
 {
   Q_OBJECT
 public:
+  /// Support for fitting algorithms:
+  ///   Simultaneous: Fit
+  ///   Sequential:   PlotPeakByLogValue
+  ///   SimultaneousAndSequential: both Fit and PlotPeakByLogValue, toggled with
+  ///       "Fitting" property.
+  enum FittingType {Simultaneous = 0, Sequential, SimultaneousAndSequential};
+
   /// Constructor
-  FitOptionsBrowser(QWidget *parent = NULL);
+  FitOptionsBrowser(QWidget *parent = NULL, FittingType fitType = Simultaneous);
   QString getProperty(const QString& name) const;
   void setProperty(const QString& name, const QString& value);
   void copyPropertiesToAlgorithm(Mantid::API::IAlgorithm& fit) const;
   void saveSettings(QSettings& settings) const;
   void loadSettings(const QSettings& settings);
+  FittingType getCurrentFittingType() const;
+  void setCurrentFittingType(FittingType fitType);
+  void lockCurrentFittingType(FittingType fitType);
+  void unlockCurrentFittingType();
+  void setLogNames(const QStringList& logNames);
+
+signals:
+  void changedToSequentialFitting();
 
 private slots:
 
@@ -59,25 +74,33 @@ private:
 
   void createBrowser();
   void createProperties();
+  void createCommonProperties();
+  void createSimultaneousFitProperties();
+  void createSequentialFitProperties();
   void updateMinimizer();
+  void switchFitType();
+  void displayNormalFitProperties();
+  void displaySequentialFitProperties();
+
   QtProperty* createPropertyProperty(Mantid::Kernel::Property* prop);
   QtProperty* addDoubleProperty(const QString& name);
 
+  void addProperty(const QString& name, QtProperty* prop,
+    QString (FitOptionsBrowser::*getter)(QtProperty*)const, 
+    void (FitOptionsBrowser::*setter)(QtProperty*,const QString&));
+
   //  Setters and getters
-  QString getMinimizer() const;
-  void setMinimizer(const QString&);
-  QString getCostFunction() const;
-  void setCostFunction(const QString&);
-  QString getMaxIterations() const;
-  void setMaxIterations(const QString&);
-  QString getOutput() const;
-  void setOutput(const QString&);
-  QString getIgnoreInvalidData() const;
-  void setIgnoreInvalidData(const QString&);
-
-  void addProperty(const QString& name, 
-    QString (FitOptionsBrowser::*getter)()const, 
-    void (FitOptionsBrowser::*setter)(const QString&));
+  QString getMinimizer(QtProperty*) const;
+  void setMinimizer(QtProperty*, const QString&);
+
+  QString getIntProperty(QtProperty*) const;
+  void setIntProperty(QtProperty*, const QString&);
+  QString getBoolProperty(QtProperty*) const;
+  void setBoolProperty(QtProperty*, const QString&);
+  QString getStringEnumProperty(QtProperty*) const;
+  void setStringEnumProperty(QtProperty*, const QString&);
+  QString getStringProperty(QtProperty*) const;
+  void setStringProperty(QtProperty*, const QString&);
 
   /// Qt property browser which displays properties
   QtTreePropertyBrowser* m_browser;
@@ -95,6 +118,8 @@ private:
   /// Manager for groups of properties
   QtGroupPropertyManager* m_groupManager;
 
+  /// FitType property
+  QtProperty* m_fittingTypeProp;
   /// Minimizer group property
   QtProperty* m_minimizerGroup;
   /// Minimizer property
@@ -103,18 +128,39 @@ private:
   QtProperty* m_costFunction;
   /// MaxIterations property
   QtProperty* m_maxIterations;
+  
+  // Fit properties
   /// Output property
   QtProperty* m_output;
   /// IgnoreInvalidData property
   QtProperty* m_ignoreInvalidData;
 
+  // PlotPeakByLogValue properties
+  /// FitType property
+  QtProperty* m_fitType;
+  /// OutputWorkspace property
+  QtProperty* m_outputWorkspace;
+  /// LogValue property
+  QtProperty* m_logValue;
+
   /// Precision of doubles in m_doubleManager
   int m_decimals;
 
+  typedef  void (FitOptionsBrowser::*SetterType)(QtProperty*, const QString&);
+  typedef  QString (FitOptionsBrowser::*GetterType)(QtProperty*)const;
+  /// Maps algorithm property name to the QtProperty
+  QMap<QString,QtProperty*> m_propertyNameMap;
   /// Store for the properties setter methods
-  QMap<QString,void (FitOptionsBrowser::*)(const QString&)> m_setters;
+  QMap<QtProperty*,SetterType> m_setters;
   /// Store for the properties getter methods
-  QMap<QString,QString (FitOptionsBrowser::*)()const> m_getters;
+  QMap<QtProperty*,GetterType> m_getters;
+
+  /// The Fitting Type
+  FittingType m_fittingType;
+  /// Store special properties of the normal Fit
+  QList<QtProperty*> m_simultaneousProperties;
+  /// Store special properties of the sequential Fit
+  QList<QtProperty*> m_sequentialProperties;
 };
 
 } // MantidWidgets
diff --git a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h
index 115b9ffbd2e785809d692ca1aa54c258ff2d4c1f..5302d5dab2eefdb29cf267585df262be3c1a64c5 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h
+++ b/Code/Mantid/MantidQt/MantidWidgets/inc/MantidQtMantidWidgets/FunctionBrowser.h
@@ -153,6 +153,7 @@ signals:
   void localParameterButtonClicked(const QString& parName);
 
   void functionStructureChanged();
+  void globalsChanged();
 
 public slots:
 
@@ -289,6 +290,7 @@ protected slots:
   /// Called when a function parameter property is changed
   void parameterChanged(QtProperty*);
   void parameterButtonClicked(QtProperty*);
+  void globalChanged(QtProperty*, const QString&, bool);
 
 protected:
   /// Manager for function group properties
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
index a7a39d3337707c84ce53e13f2b7c3e1bb9ca3c57..5ff51742f09233d7d57d1a7c55d3d0cbeb8c8a34 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/FitOptionsBrowser.cpp
@@ -43,10 +43,11 @@ namespace MantidWidgets
 /**
  * Constructor
  * @param parent :: The parent widget.
+ * @param fitType :: The type of the underlying fitting algorithm.
  */
-FitOptionsBrowser::FitOptionsBrowser(QWidget *parent)
+FitOptionsBrowser::FitOptionsBrowser(QWidget *parent, FittingType fitType)
   :QWidget(parent),
-  m_decimals(6)
+  m_decimals(6), m_fittingType(fitType)
 {
   // create m_browser
   createBrowser();
@@ -99,6 +100,28 @@ void FitOptionsBrowser::createBrowser()
  */
 void FitOptionsBrowser::createProperties()
 {
+  createCommonProperties();
+  if (m_fittingType == Simultaneous || m_fittingType == SimultaneousAndSequential)
+  {
+    createSimultaneousFitProperties();
+  }
+  if (m_fittingType == Sequential || m_fittingType == SimultaneousAndSequential)
+  {
+    createSequentialFitProperties();
+  }
+}
+
+void FitOptionsBrowser::createCommonProperties()
+{
+  if (m_fittingType == SimultaneousAndSequential)
+  {
+    m_fittingTypeProp = m_enumManager->addProperty("Fitting");
+    QStringList types;
+    types << "Simultaneous" << "Sequential";
+    m_enumManager->setEnumNames(m_fittingTypeProp, types);
+    m_browser->addProperty(m_fittingTypeProp);
+  }
+
   // Create MaxIterations property
   m_maxIterations = m_intManager->addProperty("Max Iterations");
   {
@@ -106,7 +129,7 @@ void FitOptionsBrowser::createProperties()
     m_intManager->setMinimum(m_maxIterations,0);
     m_browser->addProperty(m_maxIterations);
 
-    addProperty("MaxIterations", &FitOptionsBrowser::getMaxIterations, &FitOptionsBrowser::setMaxIterations);
+    addProperty("MaxIterations", m_maxIterations, &FitOptionsBrowser::getIntProperty, &FitOptionsBrowser::setIntProperty);
   }
 
   // Set up the minimizer property.
@@ -135,10 +158,8 @@ void FitOptionsBrowser::createProperties()
     {
       m_enumManager->setValue(m_minimizer,i);
     }
-
     m_browser->addProperty(m_minimizerGroup);
-
-    addProperty("Minimizer", &FitOptionsBrowser::getMinimizer, &FitOptionsBrowser::setMinimizer);
+    addProperty("Minimizer", m_minimizer, &FitOptionsBrowser::getMinimizer, &FitOptionsBrowser::setMinimizer);
   }
 
   // Create cost function property
@@ -148,40 +169,101 @@ void FitOptionsBrowser::createProperties()
     std::vector<std::string> costOptions =
       Mantid::API::CostFunctionFactory::Instance().getKeys();
     QStringList costFunctions;
-
     // Store them in the m_minimizer enum property
     for(auto it = costOptions.begin(); it != costOptions.end(); ++it)
     {
       costFunctions << QString::fromStdString(*it);
     }
     m_enumManager->setEnumNames(m_costFunction,costFunctions);
-
     m_browser->addProperty(m_costFunction);
-
-    addProperty("CostFunction", &FitOptionsBrowser::getCostFunction, &FitOptionsBrowser::setCostFunction);
+    addProperty("CostFunction", m_costFunction, &FitOptionsBrowser::getStringEnumProperty, &FitOptionsBrowser::setStringEnumProperty);
   }
 
+}
+
+void FitOptionsBrowser::createSimultaneousFitProperties()
+{
   // Create Output property
   m_output = m_stringManager->addProperty("Output");
   {
     m_browser->addProperty(m_output);
-    addProperty("Output", &FitOptionsBrowser::getOutput, &FitOptionsBrowser::setOutput);
+    addProperty("Output", m_output, &FitOptionsBrowser::getStringProperty, &FitOptionsBrowser::setStringProperty);
+    m_simultaneousProperties << m_output;
   }
 
   // Create Ignore property
   m_ignoreInvalidData = m_boolManager->addProperty("Ignore Invalid Data");
   {
     m_browser->addProperty(m_ignoreInvalidData);
-    addProperty("IgnoreInvalidData", &FitOptionsBrowser::getIgnoreInvalidData, &FitOptionsBrowser::setIgnoreInvalidData);
+    addProperty("IgnoreInvalidData", m_ignoreInvalidData, &FitOptionsBrowser::getBoolProperty, &FitOptionsBrowser::setBoolProperty);
+    m_simultaneousProperties << m_ignoreInvalidData;
   }
 }
 
-void FitOptionsBrowser::addProperty(const QString& name, 
-  QString (FitOptionsBrowser::*getter)()const, 
-  void (FitOptionsBrowser::*setter)(const QString&))
+void FitOptionsBrowser::createSequentialFitProperties()
 {
-  m_getters[name] = getter;
-  m_setters[name] = setter;
+  // Create FitType property
+  m_fitType = m_enumManager->addProperty("Fit Type");
+  {
+    QStringList types;
+    types << "Sequential" << "Individual";
+    m_enumManager->setEnumNames(m_fitType,types);
+    m_enumManager->setValue(m_fitType,0);
+    addProperty("FitType", m_fitType, &FitOptionsBrowser::getStringEnumProperty, &FitOptionsBrowser::setStringEnumProperty);
+    m_sequentialProperties << m_fitType;
+  }
+
+  // Create OutputWorkspace property
+  m_outputWorkspace = m_stringManager->addProperty("OutputWorkspace");
+  {
+    addProperty("OutputWorkspace", m_outputWorkspace, &FitOptionsBrowser::getStringProperty, &FitOptionsBrowser::setStringProperty);
+    m_sequentialProperties << m_outputWorkspace;
+  }
+
+  // Create CreateOutput property
+  auto prop = m_boolManager->addProperty("Create Output");
+  {
+    addProperty("CreateOutput", prop, &FitOptionsBrowser::getBoolProperty, &FitOptionsBrowser::setBoolProperty);
+    m_sequentialProperties << prop;
+  }
+
+  // Create OutputCompositeMembers property
+  prop = m_boolManager->addProperty("Output Composite Members");
+  {
+    addProperty("OutputCompositeMembers", prop, &FitOptionsBrowser::getBoolProperty, &FitOptionsBrowser::setBoolProperty);
+    m_sequentialProperties << prop;
+  }
+
+  // Create ConvolveMembers property
+  prop = m_boolManager->addProperty("Convolve Members");
+  {
+    addProperty("ConvolveMembers", prop, &FitOptionsBrowser::getBoolProperty, &FitOptionsBrowser::setBoolProperty);
+    m_sequentialProperties << prop;
+  }
+
+  // Create PassWSIndexToFunction property
+  prop = m_boolManager->addProperty("Pass WS Index To Function");
+  {
+    addProperty("PassWSIndexToFunction", prop, &FitOptionsBrowser::getBoolProperty, &FitOptionsBrowser::setBoolProperty);
+    m_sequentialProperties << prop;
+  }
+
+  // Create LogValue property
+  m_logValue = m_enumManager->addProperty("Log Value");
+  {
+    //m_enumManager->setValue(m_logValue,0);
+    addProperty("LogValue", m_logValue, &FitOptionsBrowser::getStringEnumProperty, &FitOptionsBrowser::setStringEnumProperty);
+    m_sequentialProperties << m_logValue;
+  }
+}
+
+void FitOptionsBrowser::addProperty(const QString& name, QtProperty* prop,
+                                    QString (FitOptionsBrowser::*getter)(QtProperty*)const, 
+  void (FitOptionsBrowser::*setter)(QtProperty*,const QString&))
+{
+  m_propertyNameMap[name] = prop;
+  m_getters[prop] = getter;
+  m_setters[prop] = setter;
 }
 
 
@@ -207,6 +289,10 @@ void FitOptionsBrowser::enumChanged(QtProperty* prop)
   {
     updateMinimizer();
   }
+  else if (prop == m_fittingTypeProp)
+  {
+    switchFitType();
+  }
 }
 
 /**
@@ -242,6 +328,53 @@ void FitOptionsBrowser::updateMinimizer()
   }
 }
 
+/**
+ * Switch the current fit type according to the value in the FitType property.
+ */
+void FitOptionsBrowser::switchFitType()
+{
+  auto fitType = m_enumManager->value(m_fittingTypeProp);
+  if (fitType == 0)
+  {
+    displayNormalFitProperties();
+  }
+  else
+  {
+    displaySequentialFitProperties();
+  }
+}
+
+/**
+ * Show normal Fit properties and hide the others.
+ */
+void FitOptionsBrowser::displayNormalFitProperties()
+{
+  foreach(QtProperty* prop, m_simultaneousProperties)
+  {
+    m_browser->addProperty(prop);
+  }
+  foreach(QtProperty* prop, m_sequentialProperties)
+  {
+    m_browser->removeProperty(prop);
+  }
+}
+
+/**
+ * Show sequential fit (PlotPeakByLogValue) properties and hide the others.
+ */
+void FitOptionsBrowser::displaySequentialFitProperties()
+{
+  foreach(QtProperty* prop, m_sequentialProperties)
+  {
+    m_browser->addProperty(prop);
+  }
+  foreach(QtProperty* prop, m_simultaneousProperties)
+  {
+    m_browser->removeProperty(prop);
+  }
+  emit changedToSequentialFitting();
+}
+
 /**
  * Create a QtProperty for an Algorithm Property
  * and attach it to the correct manager.
@@ -314,11 +447,16 @@ QtProperty* FitOptionsBrowser::createPropertyProperty(Mantid::Kernel::Property*
  */
 void FitOptionsBrowser::copyPropertiesToAlgorithm(Mantid::API::IAlgorithm& fit) const
 {
-    for(auto p = m_getters.constBegin(); p != m_getters.constEnd(); ++p)
+  for(auto p = m_propertyNameMap.constBegin(); p != m_propertyNameMap.constEnd(); ++p)
+  {
+    auto propertyName = p.key().toStdString();
+    if (fit.existsProperty(propertyName))
     {
-      auto f = p.value();
-      fit.setPropertyValue( p.key().toStdString(), (this->*f)().toStdString() );
+      auto prop = p.value();
+      auto f = m_getters[prop];
+      fit.setPropertyValue(propertyName, (this->*f)(prop).toStdString() );
     }
+  }
 }
 
 /**
@@ -327,12 +465,13 @@ void FitOptionsBrowser::copyPropertiesToAlgorithm(Mantid::API::IAlgorithm& fit)
  */
 QString FitOptionsBrowser::getProperty(const QString& name) const
 {
-  if ( !m_getters.contains(name) )
+  if ( !m_propertyNameMap.contains(name) )
   {
     throw std::runtime_error("Property " + name.toStdString() + " isn't supported by the browser.");
   }
-  auto f = m_getters[name];
-  return (this->*f)();
+  auto prop = m_propertyNameMap[name];
+  auto f = m_getters[prop];
+  return (this->*f)(prop);
 }
 
 /**
@@ -342,18 +481,19 @@ QString FitOptionsBrowser::getProperty(const QString& name) const
  */
 void FitOptionsBrowser::setProperty(const QString& name, const QString& value)
 {
-  if ( !m_getters.contains(name) )
+  if ( !m_propertyNameMap.contains(name) )
   {
     throw std::runtime_error("Property " + name.toStdString() + " isn't supported by the browser.");
   }
-  auto f = m_setters[name];
-  (this->*f)(value);
+  auto prop = m_propertyNameMap[name];
+  auto f = m_setters[prop];
+  (this->*f)(prop,value);
 }
 
 /**
  * Get the value of the Minimizer property.
  */
-QString FitOptionsBrowser::getMinimizer() const
+QString FitOptionsBrowser::getMinimizer(QtProperty*) const
 {
   int i = m_enumManager->value(m_minimizer);
   QString minimStr = m_enumManager->enumNames(m_minimizer)[i];
@@ -401,94 +541,109 @@ QString FitOptionsBrowser::getMinimizer() const
  * Set new value to the Minimizer property.
  * @param value :: The new value.
  */
-void FitOptionsBrowser::setMinimizer(const QString& value)
+void FitOptionsBrowser::setMinimizer(QtProperty*, const QString& value)
 {
   QStringList terms = value.split(',');
   int i = m_enumManager->enumNames(m_minimizer).indexOf(terms[0]);
   m_enumManager->setValue(m_minimizer,i);
 }
 
+// ------------------------- Generic setters and getters ------------------------------//
+
 /**
- * Get the value of the CostFunction property.
+ * Get the value of an integer algorithm property.
+ * @param prop :: The corresponding QtProperty.
  */
-QString FitOptionsBrowser::getCostFunction() const
+QString FitOptionsBrowser::getIntProperty(QtProperty* prop) const
 {
-  int i = m_enumManager->value(m_costFunction);
-  return m_enumManager->enumNames(m_costFunction)[i];
+  return QString::number(m_intManager->value(prop));
 }
 
 /**
- * Set new value to the CostFunction property.
+ * Set a new value of an integer algorithm property.
+ * @param prop :: The corresponding QtProperty.
  * @param value :: The new value.
  */
-void FitOptionsBrowser::setCostFunction(const QString& value)
+void FitOptionsBrowser::setIntProperty(QtProperty* prop, const QString& value)
 {
-  int i = m_enumManager->enumNames(m_costFunction).indexOf(value);
-  m_enumManager->setValue(m_costFunction,i);
+  m_intManager->setValue(prop,value.toInt());
 }
 
 /**
- * Get the value of the MaxIterations property.
+ * Get the value of a bool algorithm property.
+ * @param prop :: The corresponding QtProperty.
  */
-QString FitOptionsBrowser::getMaxIterations() const
+QString FitOptionsBrowser::getBoolProperty(QtProperty* prop) const
 {
-  return QString::number(m_intManager->value(m_maxIterations));
+  return QString::number(m_boolManager->value(prop));
 }
 
 /**
- * Set new value to the MaxIterations property.
+ * Set a new value of a bool algorithm property.
+ * @param prop :: The corresponding QtProperty.
  * @param value :: The new value.
  */
-void FitOptionsBrowser::setMaxIterations(const QString& value)
+void FitOptionsBrowser::setBoolProperty(QtProperty* prop, const QString& value)
 {
-  m_intManager->setValue(m_maxIterations,value.toInt());
+  bool boolValue = (value == "1") || (value.lower() == "true");
+  m_boolManager->setValue( prop, boolValue );
 }
 
 /**
- * Get the value of the Output property.
+ * Get the value of a string algorithm property with predefined set of values.
+ * @param prop :: The corresponding QtProperty.
  */
-QString FitOptionsBrowser::getOutput() const
+QString FitOptionsBrowser::getStringEnumProperty(QtProperty* prop) const
 {
-  return m_stringManager->value(m_output);
+  int i = m_enumManager->value(prop);
+  if (i < 0) return "";
+  return m_enumManager->enumNames(prop)[i];
 }
 
 /**
- * Set new value to the Output property.
+ * Set a new value of a string algorithm property with predefined set of values.
+ * @param prop :: The corresponding QtProperty.
  * @param value :: The new value.
  */
-void FitOptionsBrowser::setOutput(const QString& value)
+void FitOptionsBrowser::setStringEnumProperty(QtProperty* prop, const QString& value)
 {
-  m_stringManager->setValue(m_output,value);
+  int i = m_enumManager->enumNames(prop).indexOf(value);
+  if (i >= 0)
+    m_enumManager->setValue(prop,i);
 }
 
 /**
- * Get the value of the IgnoreInvalidData property.
+ * Get the value of a string algorithm property.
+ * @param prop :: The corresponding QtProperty.
  */
-QString FitOptionsBrowser::getIgnoreInvalidData() const
+QString FitOptionsBrowser::getStringProperty(QtProperty* prop) const
 {
-  return QString::number(m_boolManager->value(m_ignoreInvalidData));
+  return m_stringManager->value(prop);
 }
 
 /**
- * Set new value to the IgnoreInvalidData property.
+ * Set a new value of a string algorithm property.
+ * @param prop :: The corresponding QtProperty.
  * @param value :: The new value.
  */
-void FitOptionsBrowser::setIgnoreInvalidData(const QString& value)
+void FitOptionsBrowser::setStringProperty(QtProperty* prop, const QString& value)
 {
-  bool boolValue = (value == "1") || (value == "true");
-  m_boolManager->setValue( m_ignoreInvalidData, boolValue );
+  m_stringManager->setValue(prop, value);
 }
 
+// ------------------------------------------------------------------------------------//
+
 /**
  * Save the last property values in settings.
  * @param settings :: A QSettings instance provided by the user of this class.
  */
 void FitOptionsBrowser::saveSettings(QSettings& settings) const
 {
-  for(auto p = m_getters.constBegin(); p != m_getters.constEnd(); ++p)
+  for(auto p = m_propertyNameMap.constBegin(); p != m_propertyNameMap.constEnd(); ++p)
   {
-    auto f = p.value();
-    settings.setValue( p.key(), (this->*f)() );
+    auto prop = p.value();
+    auto f = m_getters[prop];
+    settings.setValue( p.key(), (this->*f)(prop) );
   }
 }
 
@@ -498,17 +653,81 @@ void FitOptionsBrowser::saveSettings(QSettings& settings) const
  */
 void FitOptionsBrowser::loadSettings(const QSettings& settings)
 {
-  for(auto p = m_setters.constBegin(); p != m_setters.constEnd(); ++p)
+  for(auto p = m_propertyNameMap.constBegin(); p != m_propertyNameMap.constEnd(); ++p)
   {
     QString value = settings.value( p.key() ).toString();
     if ( !value.isEmpty() )
     {
-      auto f = p.value();
-      (this->*f)( value );
+      auto prop = p.value();
+      auto f = m_setters[prop];
+      (this->*f)(prop, value);
     }
   }
 }
 
+/**
+ * Get the current fitting type, ie which algorithm to use:
+ *    Simultaneous for Fit and Sequential for PlotPeakByLogValue.
+ */
+FitOptionsBrowser::FittingType FitOptionsBrowser::getCurrentFittingType() const
+{
+  auto value = m_enumManager->value(m_fittingTypeProp);
+  return static_cast<FitOptionsBrowser::FittingType>(value);
+}
+
+/**
+ * Set the current fitting type, ie which algorithm to use:
+ *    Simultaneous for Fit and Sequential for PlotPeakByLogValue.
+ */
+void FitOptionsBrowser::setCurrentFittingType(FitOptionsBrowser::FittingType fitType)
+{
+  m_enumManager->setValue(m_fittingTypeProp, fitType);
+}
+
+/**
+ * Lock the browser in a particular fitting type state. Disable the switch option.
+ * @param fitType :: Fitting type to lock the browser in.
+ */
+void FitOptionsBrowser::lockCurrentFittingType(FitOptionsBrowser::FittingType fitType)
+{
+  m_enumManager->setValue(m_fittingTypeProp, fitType);
+  m_fittingTypeProp->setEnabled(false);
+}
+
+/**
+ * Make the fitting type changeable again.
+ */
+void FitOptionsBrowser::unlockCurrentFittingType()
+{
+  m_fittingTypeProp->setEnabled(true);
+}
+
+/**
+ * Define log names to use with the LogValue property.
+ * @param logNames :: The log names
+ */
+void FitOptionsBrowser::setLogNames(const QStringList& logNames)
+{
+  auto i = m_enumManager->value(m_logValue);
+  if (!logNames.isEmpty() && logNames.front().isEmpty())
+  {
+    m_enumManager->setEnumNames(m_logValue, logNames);
+  }
+  else
+  {
+    QStringList names = logNames;
+    names.insert(0,"");
+    m_enumManager->setEnumNames(m_logValue, names);
+  }
+  if (i < logNames.size())
+  {
+    m_enumManager->setValue(m_logValue, i);
+  }
+  else
+  {
+    m_enumManager->setValue(m_logValue, 0);
+  }
+}
 
 } // MantidWidgets
 } // MantidQt
diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/FunctionBrowser.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
index 6a1fec1998500607aeb2285e94c3e85923cbb12e..a5091090e1853d2504aafb2b319a9723dbd797a3 100644
--- a/Code/Mantid/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
+++ b/Code/Mantid/MantidQt/MantidWidgets/src/FunctionBrowser.cpp
@@ -165,6 +165,7 @@ void FunctionBrowser::createBrowser()
 
   m_browser->setContextMenuPolicy(Qt::CustomContextMenu);
   connect(m_browser, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(popupMenu(const QPoint &)));
+  connect(m_browser, SIGNAL(optionChanged(QtProperty*, const QString&, bool)), this, SLOT(globalChanged(QtProperty*, const QString&, bool)));
 
   connect(m_attributeStringManager,SIGNAL(propertyChanged(QtProperty*)),this,SLOT(attributeChanged(QtProperty*)));
   connect(m_attributeDoubleManager,SIGNAL(propertyChanged(QtProperty*)),this,SLOT(attributeChanged(QtProperty*)));
@@ -2189,6 +2190,13 @@ void FunctionBrowser::setColumnSizes(int s0, int s1, int s2)
   m_browser->setColumnSizes(s0, s1, s2);
 }
 
+/**
+ * Emit a signal when any of the Global options change.
+ */
+void FunctionBrowser::globalChanged(QtProperty*, const QString&, bool)
+{
+  emit globalsChanged();
+}
 
 } // MantidWidgets
 } // MantidQt
diff --git a/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.cpp b/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.cpp
index 58bee7f04ccc37853953ad4fc870e594fd514959..53f493d7bee8d791a84e17494c4fdab5350c34ff 100644
--- a/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.cpp
+++ b/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.cpp
@@ -134,9 +134,12 @@ public:
     setChecked( ! isChecked() );
     m_property->setOption( m_optionName, isChecked() );
     update();
+    emit optionChanged(m_property, m_optionName, isChecked());
   }
   void setChecked(bool on){m_checked = on;}
   bool isChecked() const {return m_checked;}
+signals:
+  void optionChanged(QtProperty*, const QString&, bool);
 private:
   QtProperty *m_property;
   QString m_optionName;
@@ -351,6 +354,9 @@ public:
 
     QTreeWidgetItem *editedItem() const { return m_editedItem; }
 
+signals:
+    void optionChanged(QtProperty*, const QString&, bool);
+
 private slots:
     void slotEditorDestroyed(QObject *object);
 
@@ -435,6 +441,7 @@ QWidget *QtPropertyEditorDelegate::createEditor(QWidget *parent,
       if ( property->hasOption(optionName) )
       {
         QWidget *editor = new PropertyOptionCheckBox(parent,property,optionName);
+        connect(editor,SIGNAL(optionChanged(QtProperty*, const QString&, bool)),this,SIGNAL(optionChanged(QtProperty*, const QString&, bool)));
         return editor;
       }
     }
@@ -591,6 +598,7 @@ void QtTreePropertyBrowserPrivate::init(QWidget *parent, const QStringList &opti
     m_treeWidget->setEditTriggers(QAbstractItemView::EditKeyPressed);
     m_delegate = new QtPropertyEditorDelegate(parent);
     m_delegate->setEditorPrivate(this);
+    QObject::connect(m_delegate,SIGNAL(optionChanged(QtProperty*, const QString&, bool)),parent,SIGNAL(optionChanged(QtProperty*, const QString&, bool)));
     m_treeWidget->setItemDelegate(m_delegate);
     m_treeWidget->header()->setMovable(false);
     m_treeWidget->header()->setResizeMode(QHeaderView::Stretch);
diff --git a/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.h b/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.h
index 51d367dc7bf8b0bb0c489b8d1ac4bce1e5138704..80072884d6001d464d2d1e6292ace6bc98413c96 100644
--- a/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.h
+++ b/Code/Mantid/QtPropertyBrowser/src/qttreepropertybrowser.h
@@ -159,6 +159,7 @@ Q_SIGNALS:
 
     void collapsed(QtBrowserItem *item);
     void expanded(QtBrowserItem *item);
+    void optionChanged(QtProperty*, const QString&, bool);
 
 protected:
     virtual void itemInserted(QtBrowserItem *item, QtBrowserItem *afterItem);
diff --git a/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_red.nxs.md5 b/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_red.nxs.md5
new file mode 100644
index 0000000000000000000000000000000000000000..dd49338b31255373fb60d986554ea8a6ce46902c
--- /dev/null
+++ b/Code/Mantid/Testing/Data/UnitTest/irs26173_graphite002_red.nxs.md5
@@ -0,0 +1 @@
+f52ac64ec23fb50b6d4649592aee4fdb
\ No newline at end of file
diff --git a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py
index 81007b721a560d782e1fa7f3cd4b18da8e4d91c0..cebeabf3e16062e9e85b38687d2352a6c861c8f5 100644
--- a/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py
+++ b/Code/Mantid/Testing/SystemTests/tests/analysis/POLDIFitPeaks2DTest.py
@@ -1,8 +1,9 @@
-#pylint: disable=no-init,invalid-name,too-many-locals
+# pylint: disable=no-init,invalid-name,too-many-locals,too-few-public-methods
 import stresstesting
 from mantid.simpleapi import *
 import numpy as np
 
+
 class POLDIFitPeaks2DTest(stresstesting.MantidStressTest):
     """The system test currently checks that the calculation of 2D spectra
     works correctly."""
@@ -18,7 +19,7 @@ class POLDIFitPeaks2DTest(stresstesting.MantidStressTest):
 
     def loadAndPrepareData(self, filenames):
         for dataFile in filenames:
-            LoadSINQFile(Instrument='POLDI',Filename=dataFile + ".hdf",OutputWorkspace=dataFile)
+            LoadSINQFile(Instrument='POLDI', Filename=dataFile + ".hdf", OutputWorkspace=dataFile)
             LoadInstrument(Workspace=dataFile, InstrumentName="POLDI", RewriteSpectraMap=True)
             PoldiTruncateData(InputWorkspace=dataFile, OutputWorkspace=dataFile)
 
@@ -28,19 +29,21 @@ class POLDIFitPeaks2DTest(stresstesting.MantidStressTest):
 
     def loadReferenceSpectrum(self, filenames):
         for dataFile in filenames:
-            Load(Filename="%s_2d_reference_Spectrum.nxs" % (dataFile), OutputWorkspace="%s_2d_reference_Spectrum" % (dataFile))
+            Load(Filename="%s_2d_reference_Spectrum.nxs" % (dataFile),
+                 OutputWorkspace="%s_2d_reference_Spectrum" % (dataFile))
             LoadInstrument(Workspace="%s_2d_reference_Spectrum" % (dataFile), InstrumentName="POLDI")
-            Load(Filename="%s_1d_reference_Spectrum.nxs" % (dataFile), OutputWorkspace="%s_1d_reference_Spectrum" % (dataFile))
+            Load(Filename="%s_1d_reference_Spectrum.nxs" % (dataFile),
+                 OutputWorkspace="%s_1d_reference_Spectrum" % (dataFile))
 
     def runCalculateSpectrum2D(self, filenames):
         for dataFile in filenames:
             PoldiFitPeaks2D(InputWorkspace="%s_2d_reference_Spectrum" % (dataFile),
-                               PoldiPeakWorkspace="%s_reference_Peaks" % (dataFile),
-                               FitConstantBackground=False, FitLinearBackground=False,
-                               RefinedPoldiPeakWorkspace="%s_refined_Peaks" % (dataFile),
-                               OutputWorkspace="%s_2d_calculated_Spectrum" % (dataFile),
-                               Calculated1DSpectrum="%s_1d_calculated_Spectrum" % (dataFile),
-                               MaximumIterations=100)
+                            PoldiPeakWorkspace="%s_reference_Peaks" % (dataFile),
+                            FitConstantBackground=False, FitLinearBackground=False,
+                            RefinedPoldiPeakWorkspace="%s_refined_Peaks" % (dataFile),
+                            OutputWorkspace="%s_2d_calculated_Spectrum" % (dataFile),
+                            Calculated1DSpectrum="%s_1d_calculated_Spectrum" % (dataFile),
+                            MaximumIterations=100)
 
     def analyseResults(self, filenames):
         for dataFile in filenames:
@@ -66,7 +69,6 @@ class POLDIFitPeaks2DTest(stresstesting.MantidStressTest):
 
                     self.assertLessThan(np.fabs(value - reference), error)
 
-
             spectra1D = ["%s_1d_%s_Spectrum"]
 
             for wsName in spectra1D:
@@ -85,8 +87,8 @@ class POLDIFitPeaks2DTest(stresstesting.MantidStressTest):
                 self.assertTrue(np.all(xDataCalc == xDataRef))
                 self.assertLessThan(maxDifference, 0.07)
 
-class POLDIFitPeaks2DPawleyTest(stresstesting.MantidStressTest):
 
+class POLDIFitPeaks2DPawleyTest(stresstesting.MantidStressTest):
     def runTest(self):
         si = PoldiLoadRuns(2013, 6903, 6904, 2)
         corr = PoldiAutoCorrelation('si_data_6904')
@@ -110,3 +112,48 @@ class POLDIFitPeaks2DPawleyTest(stresstesting.MantidStressTest):
         self.assertLessThan(np.abs(cell_a_err), 5.0e-5)
         self.assertLessThan(np.abs(cell_a - 5.4311946) / cell_a_err, 1.5)
 
+        DeleteWorkspace(si_refs)
+        DeleteWorkspace(indexed)
+        DeleteWorkspace(peaks)
+        DeleteWorkspace(si)
+        DeleteWorkspace(fit2d)
+        DeleteWorkspace(fit1d)
+        DeleteWorkspace(fit_plots)
+        DeleteWorkspace(peaks_ref_2d)
+
+
+class POLDIFitPeaks2DIntegratedIntensities(stresstesting.MantidStressTest):
+    def runTest(self):
+        si = PoldiLoadRuns(2013, 6903, 6904, 2)
+        corr = PoldiAutoCorrelation('si_data_6904')
+        peaks = PoldiPeakSearch(corr, MaximumPeakNumber=8)
+        peaks_ref, fit_plots = PoldiFitPeaks1D(corr, PoldiPeakTable='peaks')
+
+        # Run the same analysis twice, once with integrated and once with maximum intensities
+        # Since a Gaussian is used, the integration can be checked numerically.
+        fit2d, fit1d, peaks_ref_2d = PoldiFitPeaks2D('si_data_6904', peaks_ref,
+                                                           OutputIntegratedIntensities=False,
+                                                           MaximumIterations=100)
+
+        fit2d, fit1d, peaks_ref_2d_integrated = PoldiFitPeaks2D('si_data_6904', peaks_ref,
+                                                                      OutputIntegratedIntensities=True,
+                                                                      MaximumIterations=100)
+
+        self.assertEquals(peaks_ref_2d.rowCount(), peaks_ref_2d_integrated.rowCount())
+
+        for i in range(peaks_ref_2d.rowCount()):
+            rowHeight = peaks_ref_2d.row(i)
+
+            sigmaGaussian = (rowHeight['FWHM (rel.)'] * rowHeight['d']) / (2.0 * np.sqrt(2.0 * np.log(2.0)))
+            integratedGaussian = rowHeight['Intensity'] * np.sqrt(np.pi * 2.0) * sigmaGaussian
+
+            rowIntegrated = peaks_ref_2d_integrated.row(i)
+
+            # The numerical peak integration is done with a precision of 1e-10
+            self.assertDelta(integratedGaussian, rowIntegrated['Intensity'], 1e-10)
+
+        DeleteWorkspace(fit2d)
+        DeleteWorkspace(fit1d)
+        DeleteWorkspace(si)
+        DeleteWorkspace(peaks)
+        DeleteWorkspace(fit_plots)
diff --git a/Code/Mantid/docs/source/algorithms/PoldiFitPeaks2D-v1.rst b/Code/Mantid/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
index cb85043511ca6b1d9669830e69b02879bd2e0089..d20d3751daa2734c61909f6b2a9a80259af15c0e 100644
--- a/Code/Mantid/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/PoldiFitPeaks2D-v1.rst
@@ -21,7 +21,7 @@ Alternatively, if the peaks have been indexed using a different method, the log
 
 PoldiFitPeaks2D can also be used to calculate a theoretical 2D pattern from a set of peaks by limiting the iterations to 0.
 
-In addition to performing the 2D-fit, a theoretical 1D-diffractogram of the fit-function is calculated as well, which can be used in conjunction with :ref:`algm-PoldiAnalyseResiduals` to assess the quality of a fit.
+In addition to performing the 2D-fit, a theoretical 1D-diffractogram of the fit-function is calculated as well, which can be used in conjunction with :ref:`algm-PoldiAnalyseResiduals` to assess the quality of a fit. Depending on the value of the `OutputIntegratedIntensity`-option, the output peaks intensities are either integrated or describe the maximum.
 
 Usage
 -----
diff --git a/Code/Mantid/docs/source/algorithms/ResNorm-v1.rst b/Code/Mantid/docs/source/algorithms/ResNorm-v1.rst
index e43e7b7820d6f2a0ab8cf706c8136f9a53fafbcd..33f9724048a398f2af826bceed73a1ba89099d94 100644
--- a/Code/Mantid/docs/source/algorithms/ResNorm-v1.rst
+++ b/Code/Mantid/docs/source/algorithms/ResNorm-v1.rst
@@ -31,7 +31,7 @@ Usage
 			ws = CropWorkspace(ws, StartWorkspaceIndex=0, EndWorkspaceIndex=9)
 			ws = ScaleX(ws, -5, "Add")
 			ws = ScaleX(ws, 0.1, "Multiply")
-			
+
 			#load instrument and instrument parameters
 			LoadInstrument(ws, InstrumentName='IRIS')
 			path = os.path.join(config['instrumentDefinition.directory'], 'IRIS_graphite_002_Parameters.xml')
@@ -43,7 +43,14 @@ Usage
 		ws = createSampleWorkspace("irs26173_graphite002_red", random=True)
 		res = createSampleWorkspace("irs26173_graphite002_res")
 
-		ResNorm(VanNumber='26176', ResNumber='26173', InputType='Workspace', ResInputType='Workspace', Instrument='irs', Analyser='graphite002', Plot='None')
+		ResNorm(VanNumber='26176',
+            ResNumber='26173',
+            InputType='Workspace',
+            ResInputType='Workspace',
+            Instrument='irs',
+            Analyser='graphite002',
+            Plot='None',
+            Version=1)
 
 
 .. categories::
diff --git a/Code/Mantid/docs/source/algorithms/ResNorm-v2.rst b/Code/Mantid/docs/source/algorithms/ResNorm-v2.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ca9e6f496e2edb0523968e51e8142b61c11bda1d
--- /dev/null
+++ b/Code/Mantid/docs/source/algorithms/ResNorm-v2.rst
@@ -0,0 +1,68 @@
+.. algorithm::
+
+.. summary::
+
+.. alias::
+
+.. properties::
+
+Description
+-----------
+
+This algorithm fits the variation of the width of the resolution file to give a
+stretch factor and fits the peak intensities by normalising the peak area to
+unity and performing a linear fit with the vanadium.
+
+The outpout workspace is a WorkspaceGroup containing two MatrixWorkspaces named
+*_Intensity* and *_Stretch* with the fitted parameters.
+
+Usage
+-----
+
+**Example - a basic example using ResNorm.**
+
+.. testcode:: ExIRISResNorm
+
+    def createSampleWorkspace(name, num_spec=10, random=False):
+      """
+      Creates a sample workspace with a single lorentzian that looks like IRIS data
+      """
+      import os
+
+      # Create sample data
+      function = "name=Lorentzian,Amplitude=8,PeakCentre=5,FWHM=0.7"
+      ws = CreateSampleWorkspace("Histogram",
+                                 Function="User Defined",
+                                 UserDefinedFunction=function,
+                                 XUnit="DeltaE",
+                                 Random=random,
+                                 XMin=0,
+                                 XMax=10,
+                                 BinWidth=0.01)
+
+      # Reduce number of spectra
+      ws = CropWorkspace(ws,
+                         StartWorkspaceIndex=0,
+                         EndWorkspaceIndex=num_spec-1)
+
+      ws = ScaleX(ws, -5, "Add")
+      ws = ScaleX(ws, 0.1, "Multiply")
+
+      # Load instrument and instrument parameters
+      LoadInstrument(ws, InstrumentName='IRIS')
+      path = os.path.join(config['instrumentDefinition.directory'], 'IRIS_graphite_002_Parameters.xml')
+      LoadParameterFile(ws, Filename=path)
+      ws = RenameWorkspace(ws, OutputWorkspace=name)
+
+      return ws
+
+
+    van = createSampleWorkspace("irs26173_graphite002_red", random=True)
+    res = createSampleWorkspace("irs26173_graphite002_res", num_spec=1)
+
+    res_norm = ResNorm(ResolutionWorkspace=res,
+                       VanadiumWorkspace=van,
+                       Version=2)
+
+
+.. categories::