From ced02732784fb6fa123479efeb3732082b3b971a Mon Sep 17 00:00:00 2001
From: Matthew Andrew <matthew.andrew@tessella.com>
Date: Fri, 27 Sep 2019 15:19:30 +0100
Subject: [PATCH] Added IndirectFitAnalysisTab Re #22055

---
 .../Indirect/CMakeLists.txt                   |    6 +
 qt/scientific_interfaces/Indirect/ConvFit.cpp |    4 +-
 qt/scientific_interfaces/Indirect/ConvFit.h   |    6 +-
 qt/scientific_interfaces/Indirect/ConvFit.ui  |    6 +-
 .../Indirect/IndirectFitAnalysisTab.cpp       |  900 ++++---------
 .../Indirect/IndirectFitAnalysisTab.h         |  189 +--
 .../Indirect/IndirectFitAnalysisTabLegacy.cpp | 1123 +++++++++++++++++
 .../Indirect/IndirectFitAnalysisTabLegacy.h   |  243 ++++
 .../IndirectSpectrumSelectionPresenter.cpp    |   83 +-
 .../IndirectSpectrumSelectionPresenter.h      |   21 +-
 ...directSpectrumSelectionPresenterLegacy.cpp |  280 ++++
 ...IndirectSpectrumSelectionPresenterLegacy.h |   76 ++
 .../IndirectSpectrumSelectionView.cpp         |   68 +-
 .../Indirect/IndirectSpectrumSelectionView.h  |   31 +-
 .../IndirectSpectrumSelectionViewLegacy.cpp   |  275 ++++
 .../IndirectSpectrumSelectionViewLegacy.h     |  105 ++
 qt/scientific_interfaces/Indirect/IqtFit.cpp  |    4 +-
 qt/scientific_interfaces/Indirect/IqtFit.h    |    4 +-
 qt/scientific_interfaces/Indirect/IqtFit.ui   |    6 +-
 qt/scientific_interfaces/Indirect/JumpFit.cpp |    2 +-
 qt/scientific_interfaces/Indirect/JumpFit.h   |    4 +-
 qt/scientific_interfaces/Indirect/JumpFit.ui  |    6 +-
 qt/scientific_interfaces/Indirect/MSDFit.cpp  |    2 +-
 qt/scientific_interfaces/Indirect/MSDFit.h    |    4 +-
 qt/scientific_interfaces/Indirect/MSDFit.ui   |    6 +-
 .../IndirectSpectrumSelectionPresenterTest.h  |   10 +-
 26 files changed, 2582 insertions(+), 882 deletions(-)
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.cpp
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.h
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.cpp
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.h
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.cpp
 create mode 100644 qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.h

diff --git a/qt/scientific_interfaces/Indirect/CMakeLists.txt b/qt/scientific_interfaces/Indirect/CMakeLists.txt
index 77a34013bba..29a677f9460 100644
--- a/qt/scientific_interfaces/Indirect/CMakeLists.txt
+++ b/qt/scientific_interfaces/Indirect/CMakeLists.txt
@@ -33,6 +33,7 @@ set(
   IndirectDataValidationHelper.cpp
   IndirectDiffractionReduction.cpp
   IndirectEditResultsDialog.cpp
+  IndirectFitAnalysisTabLegacy.cpp
   IndirectFitAnalysisTab.cpp
   IndirectFitDataLegacy.cpp
   IndirectFitDataPresenterLegacy.cpp
@@ -70,6 +71,8 @@ set(
   IndirectSettingsView.cpp
   IndirectSimulation.cpp
   IndirectSimulationTab.cpp
+  IndirectSpectrumSelectionPresenterLegacy.cpp
+  IndirectSpectrumSelectionViewLegacy.cpp
   IndirectSpectrumSelectionPresenter.cpp
   IndirectSpectrumSelectionView.cpp
   IndirectSqw.cpp
@@ -160,6 +163,7 @@ set(
   IndirectDataTablePresenter.h
   IndirectDiffractionReduction.h
   IndirectEditResultsDialog.h
+  IndirectFitAnalysisTabLegacy.h
   IndirectFitAnalysisTab.h
   IndirectFitDataPresenterLegacy.h
   IndirectFitDataViewLegacy.h
@@ -185,6 +189,8 @@ set(
   IndirectSettingsView.h
   IndirectSimulation.h
   IndirectSimulationTab.h
+  IndirectSpectrumSelectionPresenterLegacy.h
+  IndirectSpectrumSelectionViewLegacy.h
   IndirectSpectrumSelectionPresenter.h
   IndirectSpectrumSelectionView.h
   IndirectSqw.h
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.cpp b/qt/scientific_interfaces/Indirect/ConvFit.cpp
index 9d4b67b86b1..6a94e13d5c6 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.cpp
+++ b/qt/scientific_interfaces/Indirect/ConvFit.cpp
@@ -36,7 +36,7 @@ namespace CustomInterfaces {
 namespace IDA {
 
 ConvFit::ConvFit(QWidget *parent)
-    : IndirectFitAnalysisTab(new ConvFitModel, parent),
+    : IndirectFitAnalysisTabLegacy(new ConvFitModel, parent),
       m_uiForm(new Ui::ConvFit) {
   m_uiForm->setupUi(parent);
   m_convFittingModel = dynamic_cast<ConvFitModel *>(fittingModel());
@@ -121,7 +121,7 @@ void ConvFit::setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) {
     m_convFittingModel->setTemperature(boost::none);
   fitAlgorithm->setProperty("ExtractMembers",
                             boolSettingValue("ExtractMembers"));
-  IndirectFitAnalysisTab::setupFit(fitAlgorithm);
+  IndirectFitAnalysisTabLegacy::setupFit(fitAlgorithm);
 }
 
 void ConvFit::setModelResolution(const QString &resolutionName) {
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.h b/qt/scientific_interfaces/Indirect/ConvFit.h
index aec220fe8a3..9caa438a617 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.h
+++ b/qt/scientific_interfaces/Indirect/ConvFit.h
@@ -8,8 +8,8 @@
 #define MANTIDQTCUSTOMINTERFACESIDA_CONVFIT_H_
 
 #include "ConvFitModel.h"
-#include "IndirectFitAnalysisTab.h"
-#include "IndirectSpectrumSelectionPresenter.h"
+#include "IndirectFitAnalysisTabLegacy.h"
+#include "IndirectSpectrumSelectionPresenterLegacy.h"
 
 #include "MantidAPI/CompositeFunction.h"
 #include "MantidAPI/MatrixWorkspace_fwd.h"
@@ -18,7 +18,7 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
-class DLLExport ConvFit : public IndirectFitAnalysisTab {
+class DLLExport ConvFit : public IndirectFitAnalysisTabLegacy {
   Q_OBJECT
 
 public:
diff --git a/qt/scientific_interfaces/Indirect/ConvFit.ui b/qt/scientific_interfaces/Indirect/ConvFit.ui
index cdf2489085a..58fc9dbe4d5 100644
--- a/qt/scientific_interfaces/Indirect/ConvFit.ui
+++ b/qt/scientific_interfaces/Indirect/ConvFit.ui
@@ -71,7 +71,7 @@
              <number>0</number>
             </property>
             <item>
-             <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView" name="svSpectrumView" native="true">
+             <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy" name="svSpectrumView" native="true">
               <property name="sizePolicy">
                <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
                 <horstretch>1</horstretch>
@@ -150,9 +150,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView</class>
+   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy</class>
    <extends>QWidget</extends>
-   <header>IndirectSpectrumSelectionView.h</header>
+   <header>IndirectSpectrumSelectionViewLegacy.h</header>
    <container>1</container>
   </customwidget>
   <customwidget>
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
index f80e46e2377..769d64b152b 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.cpp
@@ -5,12 +5,13 @@
 //     & Institut Laue - Langevin
 // SPDX - License - Identifier: GPL - 3.0 +
 #include "IndirectFitAnalysisTab.h"
-#include "ui_ConvFit.h"
-#include "ui_IqtFit.h"
-#include "ui_JumpFit.h"
-#include "ui_MSDFit.h"
+// #include "ui_ConvFit.h"
+// #include "ui_IqtFit.h"
+// #include "ui_JumpFit.h"
+// #include "ui_MSDFit.h"
 
 #include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/MultiDomainFunction.h"
 #include "MantidAPI/TextAxis.h"
 #include "MantidAPI/WorkspaceFactory.h"
 
@@ -36,28 +37,30 @@ WorkspaceGroup_sptr getADSGroupWorkspace(std::string const &workspaceName) {
       workspaceName);
 }
 
-void updateParameters(
-    IFunction_sptr function,
-    std::unordered_map<std::string, ParameterValue> const &parameters) {
-  for (auto i = 0u; i < function->nParams(); ++i) {
-    auto const value = parameters.find(function->parameterName(i));
-    if (value != parameters.end()) {
-      function->setParameter(i, value->second.value);
-      if (value->second.error)
-        function->setError(i, *value->second.error);
-    }
-  }
-}
-
-void updateAttributes(
-    IFunction_sptr function, std::vector<std::string> const &attributeNames,
-    std::unordered_map<std::string, IFunction::Attribute> const &attributes) {
-  for (const auto &attributeName : attributeNames) {
-    auto const value = attributes.find(attributeName);
-    if (value != attributes.end())
-      function->setAttribute(attributeName, value->second);
-  }
-}
+// void updateParameters(
+//    IFunction_sptr function,
+//    std::unordered_map<std::string, ParameterValue> const &parameters) {
+//  if (!function)
+//    return;
+//  for (auto i = 0u; i < function->nParams(); ++i) {
+//    auto const value = parameters.find(function->parameterName(i));
+//    if (value != parameters.end()) {
+//      function->setParameter(i, value->second.value);
+//      if (value->second.error)
+//        function->setError(i, *value->second.error);
+//    }
+//  }
+//}
+
+// void updateAttributes(
+//    IFunction_sptr function, std::vector<std::string> const &attributeNames,
+//    std::unordered_map<std::string, IFunction::Attribute> const &attributes) {
+//  for (const auto &attributeName : attributeNames) {
+//    auto const value = attributes.find(attributeName);
+//    if (value != attributes.end())
+//      function->setAttribute(attributeName, value->second);
+//  }
+//}
 
 } // namespace
 
@@ -65,215 +68,97 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-IndirectFitAnalysisTab::IndirectFitAnalysisTab(IndirectFittingModelLegacy *model,
+IndirectFitAnalysisTab::IndirectFitAnalysisTab(IndirectFittingModel *model,
                                                QWidget *parent)
-    : IndirectDataAnalysisTabLegacy(parent), m_fittingModel(model) {}
+    : IndirectDataAnalysisTab(parent), m_fittingModel(model) {}
 
 void IndirectFitAnalysisTab::setup() {
   setupFitTab();
   updateResultOptions();
 
-  connect(m_dataPresenter.get(),
-          SIGNAL(startXChanged(double, std::size_t, std::size_t)), this,
-          SLOT(tableStartXChanged(double, std::size_t, std::size_t)));
-  connect(m_dataPresenter.get(),
-          SIGNAL(endXChanged(double, std::size_t, std::size_t)), this,
-          SLOT(tableEndXChanged(double, std::size_t, std::size_t)));
-  connect(
-      m_dataPresenter.get(),
-      SIGNAL(
-          excludeRegionChanged(const std::string &, std::size_t, std::size_t)),
-      this,
-      SLOT(tableExcludeChanged(const std::string &, std::size_t, std::size_t)));
-  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()), this,
-          SLOT(setModelFitFunction()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(fitScheduled()), this,
-          SLOT(singleFit()));
-  connect(m_fitPropertyBrowser, SIGNAL(sequentialFitScheduled()), this,
-          SLOT(executeFit()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)), this,
-          SLOT(setModelStartX(double)));
-  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)), this,
-          SLOT(setModelEndX(double)));
-
-  connect(m_fitPropertyBrowser,
-          SIGNAL(parameterChanged(const Mantid::API::IFunction *)), this,
-          SIGNAL(parameterChanged(const Mantid::API::IFunction *)));
-
-  connect(m_fitPropertyBrowser,
-          SIGNAL(customBoolChanged(const QString &, bool)), this,
-          SIGNAL(customBoolChanged(const QString &, bool)));
+  connect(m_outOptionsPresenter.get(), SIGNAL(plotSpectra()), this,
+          SLOT(plotSelectedSpectra()));
 
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SLOT(setModelFitFunction()));
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SIGNAL(functionChanged()));
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SLOT(updateResultOptions()));
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SLOT(updateParameterValues()));
+  connectDataPresenter();
+  connectPlotPresenter();
+  connectFitPropertyBrowser();
+  connectSpectrumPresenter();
+}
 
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SLOT(updatePlotGuess()));
-  connect(m_fitPropertyBrowser, SIGNAL(workspaceNameChanged(const QString &)),
-          this, SLOT(updatePlotGuess()));
+void IndirectFitAnalysisTab::connectDataPresenter() {
+  connect(m_dataPresenter.get(),
+          SIGNAL(startXChanged(double, DatasetIndex, WorkspaceIndex)), this,
+          SLOT(tableStartXChanged(double, DatasetIndex, WorkspaceIndex)));
+  connect(m_dataPresenter.get(),
+          SIGNAL(endXChanged(double, DatasetIndex, WorkspaceIndex)), this,
+          SLOT(tableEndXChanged(double, DatasetIndex, WorkspaceIndex)));
+  connect(m_dataPresenter.get(),
+          SIGNAL(excludeRegionChanged(const std::string &, DatasetIndex,
+                                      WorkspaceIndex)),
+          this,
+          SLOT(tableExcludeChanged(const std::string &, DatasetIndex,
+                                   WorkspaceIndex)));
+  connect(m_dataPresenter.get(), SIGNAL(startXChanged(double)), this,
+          SLOT(startXChanged(double)));
+  connect(m_dataPresenter.get(), SIGNAL(endXChanged(double)), this,
+          SLOT(endXChanged(double)));
 
+  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()), this,
+          SLOT(respondToSingleResolutionLoaded()));
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
+          SLOT(respondToDataChanged()));
+  connect(m_dataPresenter.get(), SIGNAL(singleDataViewSelected()), this,
+          SLOT(respondToSingleDataViewSelected()));
+  connect(m_dataPresenter.get(), SIGNAL(multipleDataViewSelected()), this,
+          SLOT(respondToMultipleDataViewSelected()));
+  connect(m_dataPresenter.get(), SIGNAL(dataAdded()), this,
+          SLOT(respondToDataAdded()));
+  connect(m_dataPresenter.get(), SIGNAL(dataRemoved()), this,
+          SLOT(respondToDataRemoved()));
+}
+
+void IndirectFitAnalysisTab::connectPlotPresenter() {
   connect(m_plotPresenter.get(),
-          SIGNAL(fitSingleSpectrum(std::size_t, std::size_t)), this,
-          SLOT(singleFit(std::size_t, std::size_t)));
+          SIGNAL(fitSingleSpectrum(DatasetIndex, WorkspaceIndex)), this,
+          SLOT(singleFit(DatasetIndex, WorkspaceIndex)));
   connect(m_plotPresenter.get(),
           SIGNAL(runAsPythonScript(const QString &, bool)), this,
           SIGNAL(runAsPythonScript(const QString &, bool)));
-
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
-          SLOT(updateResultOptions()));
-  connect(m_dataPresenter.get(), SIGNAL(updateAvailableFitTypes()), this,
-          SIGNAL(updateAvailableFitTypes()));
-
-  connect(m_outOptionsPresenter.get(), SIGNAL(plotSpectra()), this,
-          SLOT(plotSelectedSpectra()));
-
-  connectDataAndSpectrumPresenters();
-  connectDataAndPlotPresenters();
-  connectDataAndFitBrowserPresenters();
-  connectSpectrumAndPlotPresenters();
-  connectFitBrowserAndPlotPresenter();
-}
-
-void IndirectFitAnalysisTab::connectDataAndPlotPresenters() {
-  connect(m_dataPresenter.get(), SIGNAL(multipleDataViewSelected()),
-          m_plotPresenter.get(), SLOT(showMultipleDataSelection()));
-  connect(m_dataPresenter.get(), SIGNAL(singleDataViewSelected()),
-          m_plotPresenter.get(), SLOT(hideMultipleDataSelection()));
-
-  connect(m_dataPresenter.get(), SIGNAL(dataAdded()), m_plotPresenter.get(),
-          SLOT(appendLastDataToSelection()));
-  connect(m_dataPresenter.get(), SIGNAL(dataRemoved()), m_plotPresenter.get(),
-          SLOT(updateDataSelection()));
-
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
-          SLOT(updateAvailableSpectra()));
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
-          SLOT(updatePlots()));
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
-          SLOT(updateGuess()));
-
-  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()),
-          m_plotPresenter.get(), SLOT(updatePlots()));
-  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-
   connect(m_plotPresenter.get(), SIGNAL(startXChanged(double)), this,
           SLOT(setDataTableStartX(double)));
   connect(m_plotPresenter.get(), SIGNAL(endXChanged(double)), this,
           SLOT(setDataTableEndX(double)));
-}
-
-void IndirectFitAnalysisTab::connectSpectrumAndPlotPresenters() {
-  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
-          m_spectrumPresenter.get(), SLOT(setActiveModelIndex(std::size_t)));
-  connect(m_plotPresenter.get(), SIGNAL(noFitDataSelected()),
-          m_spectrumPresenter.get(), SLOT(disableView()));
-  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
-          m_plotPresenter.get(), SLOT(updateSelectedDataName()));
-  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
-          m_plotPresenter.get(), SLOT(updateAvailableSpectra()));
-}
-
-void IndirectFitAnalysisTab::connectFitBrowserAndPlotPresenter() {
-  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
-          this, SLOT(setBrowserWorkspace(std::size_t)));
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
-          SLOT(updateAttributeValues()));
-  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
-          this, SLOT(updateAttributeValues()));
-  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
-          this, SLOT(updateParameterValues()));
-  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
-          SLOT(setBrowserWorkspaceIndex(std::size_t)));
-  // Update attributes before parameters as the parameters may depend on the
-  // attribute values
-  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
-          SLOT(updateAttributeValues()));
-  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
-          SLOT(updateParameterValues()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)),
-          m_plotPresenter.get(), SLOT(setStartX(double)));
-  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)),
-          m_plotPresenter.get(), SLOT(setEndX(double)));
-  connect(m_fitPropertyBrowser, SIGNAL(updatePlotSpectrum(int)),
-          m_plotPresenter.get(), SLOT(updatePlotSpectrum(int)));
-  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
-          SLOT(setBrowserWorkspaceIndex(int)));
-  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
-          SLOT(updateAttributeValues()));
-  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
-          SLOT(updateParameterValues()));
-
-  connect(m_plotPresenter.get(), SIGNAL(startXChanged(double)), this,
-          SLOT(setBrowserStartX(double)));
-  connect(m_plotPresenter.get(), SIGNAL(endXChanged(double)), this,
-          SLOT(setBrowserEndX(double)));
+  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(DatasetIndex)),
+          this, SLOT(respondToSelectedFitDataChanged(DatasetIndex)));
+  connect(m_plotPresenter.get(), SIGNAL(noFitDataSelected()), this,
+          SLOT(respondToNoFitDataSelected()));
+  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(WorkspaceIndex)),
+          this, SLOT(respondToPlotSpectrumChanged(WorkspaceIndex)));
   connect(m_plotPresenter.get(), SIGNAL(fwhmChanged(double)), this,
-          SLOT(updateFitBrowserParameterValues()));
+          SLOT(respondToFwhmChanged(double)));
   connect(m_plotPresenter.get(), SIGNAL(backgroundChanged(double)), this,
-          SLOT(updateFitBrowserParameterValues()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(xRangeChanged(double, double)),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-  connect(m_plotPresenter.get(), SIGNAL(fwhmChanged(double)),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-  connect(m_plotPresenter.get(), SIGNAL(backgroundChanged(double)),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-
-  connect(m_fitPropertyBrowser,
-          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
-          m_plotPresenter.get(), SLOT(updateRangeSelectors()));
-  connect(m_fitPropertyBrowser,
-          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()),
-          m_plotPresenter.get(), SLOT(updatePlots()));
-  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()),
-          m_plotPresenter.get(), SLOT(updateGuess()));
-
-  connect(m_fitPropertyBrowser, SIGNAL(plotGuess()), m_plotPresenter.get(),
-          SLOT(enablePlotGuessInSeparateWindow()));
-}
-
-void IndirectFitAnalysisTab::connectDataAndSpectrumPresenters() {
-  connect(m_dataPresenter.get(), SIGNAL(singleDataViewSelected()),
-          m_spectrumPresenter.get(), SLOT(setActiveIndexToZero()));
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()),
-          m_spectrumPresenter.get(), SLOT(updateSpectra()));
-  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
-          m_dataPresenter.get(), SLOT(updateSpectraInTable(std::size_t)));
+          SLOT(respondToBackgroundChanged(double)));
+}
+
+void IndirectFitAnalysisTab::connectSpectrumPresenter() {
+  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(DatasetIndex)), this,
+          SLOT(respondToChangeOfSpectraRange(DatasetIndex)));
   connect(m_spectrumPresenter.get(), SIGNAL(maskChanged(const std::string &)),
           this, SLOT(setDataTableExclude(const std::string &)));
 }
 
-void IndirectFitAnalysisTab::connectDataAndFitBrowserPresenters() {
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
-          SLOT(updateBrowserFittingRange()));
-  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
-          SLOT(setBrowserWorkspace()));
-  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)), this,
-          SLOT(setDataTableStartX(double)));
-  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)), this,
-          SLOT(setDataTableEndX(double)));
+void IndirectFitAnalysisTab::connectFitPropertyBrowser() {
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(respondToFunctionChanged()));
 }
 
 void IndirectFitAnalysisTab::setFitDataPresenter(
-    std::unique_ptr<IndirectFitDataPresenterLegacy> presenter) {
+    std::unique_ptr<IndirectFitDataPresenter> presenter) {
   m_dataPresenter = std::move(presenter);
 }
 
-void IndirectFitAnalysisTab::setPlotView(IIndirectFitPlotViewLegacy *view) {
-  m_plotPresenter = std::make_unique<IndirectFitPlotPresenterLegacy>(
+void IndirectFitAnalysisTab::setPlotView(IIndirectFitPlotView *view) {
+  m_plotPresenter = std::make_unique<IndirectFitPlotPresenter>(
       m_fittingModel.get(), view, this);
 }
 
@@ -290,7 +175,7 @@ void IndirectFitAnalysisTab::setOutputOptionsView(
 }
 
 void IndirectFitAnalysisTab::setFitPropertyBrowser(
-    MantidWidgets::IndirectFitPropertyBrowserLegacy *browser) {
+    IndirectFitPropertyBrowser *browser) {
   browser->init();
   m_fitPropertyBrowser = browser;
 }
@@ -343,21 +228,20 @@ void IndirectFitAnalysisTab::setResolutionFBSuffixes(
   m_dataPresenter->setResolutionFBSuffices(suffices);
 }
 
-std::size_t IndirectFitAnalysisTab::getSelectedDataIndex() const {
+DatasetIndex IndirectFitAnalysisTab::getSelectedDataIndex() const {
   return m_plotPresenter->getSelectedDataIndex();
 }
 
-std::size_t IndirectFitAnalysisTab::getSelectedSpectrum() const {
+WorkspaceIndex IndirectFitAnalysisTab::getSelectedSpectrum() const {
   return m_plotPresenter->getSelectedSpectrum();
 }
 
 bool IndirectFitAnalysisTab::isRangeCurrentlySelected(
-    std::size_t dataIndex, std::size_t spectrum) const {
-  return FittingMode::SEQUENTIAL == m_fittingModel->getFittingMode() ||
-         m_plotPresenter->isCurrentlySelected(dataIndex, spectrum);
+    DatasetIndex dataIndex, WorkspaceIndex spectrum) const {
+  return m_plotPresenter->isCurrentlySelected(dataIndex, spectrum);
 }
 
-IndirectFittingModelLegacy *IndirectFitAnalysisTab::fittingModel() const {
+IndirectFittingModel *IndirectFitAnalysisTab::fittingModel() const {
   return m_fittingModel.get();
 }
 
@@ -374,26 +258,19 @@ QString IndirectFitAnalysisTab::selectedFitType() const {
  * @return              The number of custom functions, with the specified name,
  *                      included in the selected model.
  */
-size_t IndirectFitAnalysisTab::numberOfCustomFunctions(
-    const std::string &functionName) const {
-  return m_fitPropertyBrowser->numberOfCustomFunctions(functionName);
+size_t
+IndirectFitAnalysisTab::numberOfCustomFunctions(const std::string &) const {
+  return 0;
 }
 
 void IndirectFitAnalysisTab::setModelFitFunction() {
-  try {
-    m_fittingModel->setFitFunction(m_fitPropertyBrowser->getFittingFunction());
-  } catch (const std::out_of_range &) {
-    m_fittingModel->setFitFunction(m_fitPropertyBrowser->compositeFunction());
-  }
+  m_fittingModel->setFitFunction(m_fitPropertyBrowser->getFittingFunction());
 }
 
 void IndirectFitAnalysisTab::setModelStartX(double startX) {
   const auto dataIndex = getSelectedDataIndex();
   if (m_fittingModel->numberOfWorkspaces() > dataIndex) {
     m_fittingModel->setStartX(startX, dataIndex, getSelectedSpectrum());
-  } else {
-    setBrowserStartX(0);
-    setBrowserEndX(0);
   }
 }
 
@@ -401,347 +278,80 @@ void IndirectFitAnalysisTab::setModelEndX(double endX) {
   const auto dataIndex = getSelectedDataIndex();
   if (m_fittingModel->numberOfWorkspaces() > dataIndex) {
     m_fittingModel->setEndX(endX, dataIndex, getSelectedSpectrum());
-  } else {
-    setBrowserStartX(0);
-    setBrowserEndX(0);
   }
 }
 
 void IndirectFitAnalysisTab::setDataTableStartX(double startX) {
-  m_dataPresenter->setStartX(startX, m_plotPresenter->getSelectedDataIndex(),
-                             m_plotPresenter->getSelectedSpectrumIndex());
+  m_dataPresenter->setStartX(startX, m_plotPresenter->getSelectedDataIndex());
 }
 
 void IndirectFitAnalysisTab::setDataTableEndX(double endX) {
-  m_dataPresenter->setEndX(endX, m_plotPresenter->getSelectedDataIndex(),
-                           m_plotPresenter->getSelectedSpectrumIndex());
+  m_dataPresenter->setEndX(endX, m_plotPresenter->getSelectedDataIndex());
 }
 
 void IndirectFitAnalysisTab::setDataTableExclude(const std::string &exclude) {
   m_dataPresenter->setExclude(exclude, m_plotPresenter->getSelectedDataIndex(),
-                              m_plotPresenter->getSelectedSpectrumIndex());
-}
-
-void IndirectFitAnalysisTab::setBrowserStartX(double startX) {
-  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
-  m_fitPropertyBrowser->setStartX(startX);
-}
-
-void IndirectFitAnalysisTab::setBrowserEndX(double endX) {
-  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
-  m_fitPropertyBrowser->setEndX(endX);
-}
-
-void IndirectFitAnalysisTab::updateBrowserFittingRange() {
-  const auto range = m_fittingModel->getFittingRange(getSelectedDataIndex(),
-                                                     getSelectedSpectrum());
-  setBrowserStartX(range.first);
-  setBrowserEndX(range.second);
-}
-
-void IndirectFitAnalysisTab::setBrowserWorkspace() {
-  if (m_fittingModel->numberOfWorkspaces() > 0) {
-    auto const name =
-        m_fittingModel->getWorkspace(getSelectedDataIndex())->getName();
-    m_fitPropertyBrowser->setWorkspaceName(QString::fromStdString(name));
-  }
-}
-
-void IndirectFitAnalysisTab::setBrowserWorkspace(std::size_t dataIndex) {
-  const auto name = m_fittingModel->getWorkspace(dataIndex)->getName();
-  m_fitPropertyBrowser->setWorkspaceName(QString::fromStdString(name));
-}
-
-void IndirectFitAnalysisTab::setBrowserWorkspaceIndex(std::size_t spectrum) {
-  setBrowserWorkspaceIndex(boost::numeric_cast<int>(spectrum));
-}
-
-void IndirectFitAnalysisTab::setBrowserWorkspaceIndex(int spectrum) {
-  m_fitPropertyBrowser->setWorkspaceIndex(spectrum);
+                              m_plotPresenter->getSelectedSpectrum());
 }
 
 void IndirectFitAnalysisTab::tableStartXChanged(double startX,
-                                                std::size_t dataIndex,
-                                                std::size_t spectrum) {
+                                                DatasetIndex dataIndex,
+                                                WorkspaceIndex spectrum) {
   if (isRangeCurrentlySelected(dataIndex, spectrum)) {
     m_plotPresenter->setStartX(startX);
-    setBrowserStartX(startX);
+    m_plotPresenter->updateGuess();
+    m_fittingModel->setStartX(startX, m_plotPresenter->getSelectedDataIndex(),
+                              m_plotPresenter->getSelectedSpectrum());
   }
 }
 
 void IndirectFitAnalysisTab::tableEndXChanged(double endX,
-                                              std::size_t dataIndex,
-                                              std::size_t spectrum) {
+                                              DatasetIndex dataIndex,
+                                              WorkspaceIndex spectrum) {
   if (isRangeCurrentlySelected(dataIndex, spectrum)) {
     m_plotPresenter->setEndX(endX);
-    setBrowserEndX(endX);
+    m_plotPresenter->updateGuess();
+    m_fittingModel->setEndX(endX, m_plotPresenter->getSelectedDataIndex(),
+                            m_plotPresenter->getSelectedSpectrum());
   }
 }
 
 void IndirectFitAnalysisTab::tableExcludeChanged(const std::string & /*unused*/,
-                                                 std::size_t dataIndex,
-                                                 std::size_t spectrum) {
+                                                 DatasetIndex dataIndex,
+                                                 WorkspaceIndex spectrum) {
   if (isRangeCurrentlySelected(dataIndex, spectrum))
     m_spectrumPresenter->displayBinMask();
 }
 
-/**
- * Sets whether fit members should be convolved with the resolution after a fit.
- *
- * @param convolveMembers If true, members are to be convolved.
- */
-void IndirectFitAnalysisTab::setConvolveMembers(bool convolveMembers) {
-  m_fitPropertyBrowser->setConvolveMembers(convolveMembers);
-}
-
-/**
- * Updates the ties displayed in the fit property browser, using
- * the set fitting function.
- */
-void IndirectFitAnalysisTab::updateTies() {
-  m_fitPropertyBrowser->updateTies();
-}
-
-/**
- * Sets whether the custom setting with the specified name is enabled.
- *
- * @param settingName The name of the custom setting.
- * @param enabled     True if custom setting should be enabled, false otherwise.
- */
-void IndirectFitAnalysisTab::setCustomSettingEnabled(const QString &customName,
-                                                     bool enabled) {
-  m_fitPropertyBrowser->setCustomSettingEnabled(customName, enabled);
-}
-
-/**
- * Sets the value of the parameter with the specified name, in the function with
- * the specified name.
- *
- * @param functionName  The name of the function containing the parameter.
- * @param parameterName The name of the parameter to set.
- * @param value         The value to set.
- */
-void IndirectFitAnalysisTab::setParameterValue(const std::string &functionName,
-                                               const std::string &parameterName,
-                                               double value) {
-  m_fitPropertyBrowser->setParameterValue(functionName, parameterName, value);
-}
-
-/**
- * Sets the default peak type for the indirect property browser.
- *
- * @param function  The name of the default peak function to set.
- */
-void IndirectFitAnalysisTab::setDefaultPeakType(const std::string &function) {
-  m_fitPropertyBrowser->setDefaultPeakType(function);
-}
-
-/**
- * Adds a check-box with the specified name, to the fit property browser, which
- * when checked adds the specified functions to the mode and when unchecked,
- * removes them.
- *
- * @param groupName     The name/label of the check-box to add.
- * @param functions     The functions to be added when the check-box is checked.
- * @param defaultValue  The default value of the check-box.
- */
-void IndirectFitAnalysisTab::addCheckBoxFunctionGroup(
-    const QString &groupName, const std::vector<IFunction_sptr> &functions,
-    bool defaultValue) {
-  m_fitPropertyBrowser->addCheckBoxFunctionGroup(groupName, functions,
-                                                 defaultValue);
-}
-
-/**
- * Adds a number spinner with the specified name, to the fit property browser,
- * which specifies how many multiples of the specified functions should be added
- * to the model.
- *
- * @param groupName     The name/label of the spinner to add.
- * @param functions     The functions to be added.
- * @param minimum       The minimum value of the spinner.
- * @param maximum       The maximum value of the spinner.
- * @param defaultValue  The default value of the spinner.
- */
-void IndirectFitAnalysisTab::addSpinnerFunctionGroup(
-    const QString &groupName, const std::vector<IFunction_sptr> &functions,
-    int minimum, int maximum, int defaultValue) {
-  m_fitPropertyBrowser->addSpinnerFunctionGroup(groupName, functions, minimum,
-                                                maximum, defaultValue);
-}
-
-/**
- * Adds an option with the specified name, to the fit type combo-box in the fit
- * property browser, which adds the specified functions to the model.
- *
- * @param groupName The name of the option to be added to the fit type
- *                  combo-box.
- * @param functions The functions added by the option.
- */
-void IndirectFitAnalysisTab::addComboBoxFunctionGroup(
-    const QString &groupName, const std::vector<IFunction_sptr> &functions) {
-  m_fitPropertyBrowser->addComboBoxFunctionGroup(groupName, functions);
-}
-
-/**
- * Removes all options from the Fit Type combo-box apart from the 'None' option
- *
- */
-void IndirectFitAnalysisTab::clearFitTypeComboBox() {
-  m_fitPropertyBrowser->clearFitTypeComboBox();
-}
-
-/**
- * Sets the available background options in this fit analysis tab.
- *
- * @param backgrounds A list of the available backgrounds.
- */
-void IndirectFitAnalysisTab::setBackgroundOptions(
-    const QStringList &backgrounds) {
-  m_fitPropertyBrowser->setBackgroundOptions(backgrounds);
+void IndirectFitAnalysisTab::startXChanged(double startX) {
+  m_plotPresenter->setStartX(startX);
+  m_plotPresenter->updateGuess();
+  m_fittingModel->setStartX(startX, m_plotPresenter->getSelectedDataIndex());
 }
 
-/**
- * @param settingKey  The key of the boolean setting whose value to retrieve.
- * @return            The value of the boolean setting with the specified key.
- */
-bool IndirectFitAnalysisTab::boolSettingValue(const QString &settingKey) const {
-  return m_fitPropertyBrowser->boolSettingValue(settingKey);
+void IndirectFitAnalysisTab::endXChanged(double endX) {
+  m_plotPresenter->setEndX(endX);
+  m_plotPresenter->updateGuess();
+  m_fittingModel->setEndX(endX, m_plotPresenter->getSelectedDataIndex());
 }
 
 /**
- * Sets the value of the custom boolean setting, with the specified key, to the
- * specified value.
- *
- * @param settingKey  The key of the custom boolean setting.
- * @param value       The value to set the boolean custom setting to.
- */
-void IndirectFitAnalysisTab::setCustomBoolSetting(const QString &settingKey,
-                                                  bool value) {
-  m_fitPropertyBrowser->setCustomBoolSetting(settingKey, value);
-}
-
-/**
- * @param settingKey  The key of the integer setting whose value to retrieve.
- * @return            The value of the integer setting with the specified key.
- */
-int IndirectFitAnalysisTab::intSettingValue(const QString &settingKey) const {
-  return m_fitPropertyBrowser->intSettingValue(settingKey);
-}
-
-/**
- * @param settingKey  The key of the double setting whose value to retrieve.
- * @return            The value of the double setting with the specified key.
- */
-double
-IndirectFitAnalysisTab::doubleSettingValue(const QString &settingKey) const {
-  return m_fitPropertyBrowser->doubleSettingValue(settingKey);
-}
-
-/**
- * @param settingKey  The key of the enum setting whose value to retrieve.
- * @return            The value of the enum setting with the specified key.
- */
-QString
-IndirectFitAnalysisTab::enumSettingValue(const QString &settingKey) const {
-  return m_fitPropertyBrowser->enumSettingValue(settingKey);
-}
-
-/**
- * Adds a boolean custom setting, with the specified key and display name.
- *
- * @param settingKey    The key of the boolean setting to add.
- * @param settingName   The display name of the boolean setting to add.
- * @param defaultValue  The default value of the boolean setting.
- */
-void IndirectFitAnalysisTab::addBoolCustomSetting(const QString &settingKey,
-                                                  const QString &settingName,
-                                                  bool defaultValue) {
-  m_fitPropertyBrowser->addBoolCustomSetting(settingKey, settingName,
-                                             defaultValue);
-}
-
-/**
- * Adds a double custom setting, with the specified key and display name.
- *
- * @param settingKey    The key of the double setting to add.
- * @param settingName   The display name of the double setting to add.
- * @param defaultValue  The default value of the double setting.
- */
-void IndirectFitAnalysisTab::addDoubleCustomSetting(const QString &settingKey,
-                                                    const QString &settingName,
-                                                    double defaultValue) {
-  m_fitPropertyBrowser->addDoubleCustomSetting(settingKey, settingName,
-                                               defaultValue);
-}
-
-/**
- * Adds an integer custom setting, with the specified key and display name.
- *
- * @param settingKey    The key of the integer setting to add.
- * @param settingName   The display name of the integer setting to add.
- * @param defaultValue  The default value of the integer setting.
- */
-void IndirectFitAnalysisTab::addIntCustomSetting(const QString &settingKey,
-                                                 const QString &settingName,
-                                                 int defaultValue) {
-  m_fitPropertyBrowser->addIntCustomSetting(settingKey, settingName,
-                                            defaultValue);
-}
-
-/**
- * Adds an enum custom setting, with the specified key and display name.
- *
- * @param settingKey    The key of the enum setting to add.
- * @param settingName   The display name of the enum setting to add.
- * @param defaultValue  The default value of the enum setting.
- */
-void IndirectFitAnalysisTab::addEnumCustomSetting(const QString &settingKey,
-                                                  const QString &settingName,
-                                                  const QStringList &options) {
-  m_fitPropertyBrowser->addEnumCustomSetting(settingKey, settingName, options);
-}
-
-/**
- * Adds an optional double custom setting, with the specified key and display
- * name.
- *
- * @param settingKey    The key of the optional double setting to add.
- * @param settingName   The display name of the optional double setting to add.
- * @param optionKey     The key of the setting specifying whether to use this
- *                      this optional setting.
- * @param optionName    The display name of the setting specifying whether to
- *                      use this optional setting.
- * @param defaultValue  The default value of the optional double setting.
- */
-void IndirectFitAnalysisTab::addOptionalDoubleSetting(
-    const QString &settingKey, const QString &settingName,
-    const QString &optionKey, const QString &optionName, bool enabled,
-    double defaultValue) {
-  m_fitPropertyBrowser->addOptionalDoubleSetting(
-      settingKey, settingName, optionKey, optionName, enabled, defaultValue);
-}
-
-/**
- * Sets whether a setting with a specified key affects the fitting function.
+ * Sets whether fit members should be convolved with the resolution after a fit.
  *
- * @param settingKey      The key of the setting.
- * @param changesFunction Boolean specifying whether the setting affects the
- *                        fitting function.
+ * @param convolveMembers If true, members are to be convolved.
  */
-void IndirectFitAnalysisTab::setCustomSettingChangesFunction(
-    const QString &settingKey, bool changesFunction) {
-  m_fitPropertyBrowser->setCustomSettingChangesFunction(settingKey,
-                                                        changesFunction);
+void IndirectFitAnalysisTab::setConvolveMembers(bool convolveMembers) {
+  m_fitPropertyBrowser->setConvolveMembers(convolveMembers);
 }
 
 void IndirectFitAnalysisTab::updateFitOutput(bool error) {
   disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
              SLOT(updateFitOutput(bool)));
 
-  if (error)
+  if (error) {
     m_fittingModel->cleanFailedRun(m_fittingAlgorithm);
-  else
+    m_fittingAlgorithm.reset();
+  } else
     m_fittingModel->addOutput(m_fittingAlgorithm);
 }
 
@@ -749,10 +359,11 @@ void IndirectFitAnalysisTab::updateSingleFitOutput(bool error) {
   disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
              SLOT(updateSingleFitOutput(bool)));
 
-  if (error)
-    m_fittingModel->cleanFailedSingleRun(m_fittingAlgorithm, 0);
-  else
-    m_fittingModel->addSingleFitOutput(m_fittingAlgorithm, 0);
+  if (error) {
+    m_fittingModel->cleanFailedSingleRun(m_fittingAlgorithm, DatasetIndex{0});
+    m_fittingAlgorithm.reset();
+  } else
+    m_fittingModel->addSingleFitOutput(m_fittingAlgorithm, DatasetIndex{0});
 }
 
 /**
@@ -764,84 +375,17 @@ void IndirectFitAnalysisTab::fitAlgorithmComplete(bool error) {
   m_plotPresenter->setFitSingleSpectrumIsFitting(false);
   enableFitButtons(true);
   enableOutputOptions(!error);
-  updateParameterValues();
+  m_fitPropertyBrowser->setErrorsEnabled(!error);
+  if (!error) {
+    updateParameterValues();
+    setModelFitFunction();
+  }
   m_spectrumPresenter->enableView();
   m_plotPresenter->updatePlots();
-
-  connect(m_fitPropertyBrowser,
-          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
-          m_plotPresenter.get(), SLOT(updateGuess()));
   disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
              SLOT(fitAlgorithmComplete(bool)));
 }
 
-/**
- * Updates the attribute values which are dependent on which spectrum is
- * selected. They are updated in the function and in the FitPropertyBrowser.
- */
-void IndirectFitAnalysisTab::updateAttributeValues() {
-  auto const attributeNames = m_fittingModel->getSpectrumDependentAttributes();
-  if (!attributeNames.empty()) {
-    for (auto i = 0; i < m_fitPropertyBrowser->count(); ++i) {
-      auto function = m_fitPropertyBrowser->getFunctionAtIndex(i);
-      updateAttributeValues(function, attributeNames);
-    }
-  }
-}
-
-/**
- * Updates the attribute values in the function provided and in the fit property
- * browser.
- * @param function        The function containing the attributes
- * @param attributeNames  The attributes to update
- */
-void IndirectFitAnalysisTab::updateAttributeValues(
-    IFunction_sptr function, std::vector<std::string> const &attributeNames) {
-  auto const attributes = getAttributes(function, attributeNames);
-  if (!attributes.empty())
-    updateAttributeValues(function, attributeNames, attributes);
-}
-
-void IndirectFitAnalysisTab::updateAttributeValues(
-    IFunction_sptr fitFunction, std::vector<std::string> const &attributeNames,
-    std::unordered_map<std::string, IFunction::Attribute> const &attributes) {
-  try {
-    updateAttributes(fitFunction, attributeNames, attributes);
-    updateFitBrowserAttributeValues();
-  } catch (const std::runtime_error &) {
-    showMessageBox("An unexpected error occured:\n The setting of attribute "
-                   "values failed.");
-  }
-}
-
-/**
- * Updates the attribute values in the the fit property browser.
- */
-void IndirectFitAnalysisTab::updateFitBrowserAttributeValues() {
-  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
-  m_fitPropertyBrowser->updateAttributes();
-}
-
-/**
- * Gets the new attribute values to be updated in the function and in the fit
- * property browser.
- * @param function        The function containing the attributes
- * @param attributeNames  The names of the attributes to update
- */
-std::unordered_map<std::string, IFunction::Attribute>
-IndirectFitAnalysisTab::getAttributes(
-    IFunction_sptr const &function,
-    std::vector<std::string> const &attributeNames) {
-  std::unordered_map<std::string, IFunction::Attribute> attributes;
-  for (auto const &name : attributeNames)
-    if (function->hasAttribute(name))
-      attributes[name] =
-          name == "WorkspaceIndex"
-              ? IFunction::Attribute(m_fitPropertyBrowser->workspaceIndex())
-              : function->getAttribute(name);
-  return attributes;
-}
-
 /**
  * Updates the parameter values and errors in the fit property browser.
  */
@@ -856,34 +400,32 @@ void IndirectFitAnalysisTab::updateParameterValues() {
  * @param parameters  The parameter values to update the browser with.
  */
 void IndirectFitAnalysisTab::updateParameterValues(
-    const std::unordered_map<std::string, ParameterValue> &parameters) {
+    const std::unordered_map<std::string, ParameterValue> &) {
   try {
-    auto fitFunction = m_fitPropertyBrowser->getFittingFunction();
-    updateParameters(fitFunction, parameters);
-
     updateFitBrowserParameterValues();
-
-    if (m_fittingModel->isPreviouslyFit(getSelectedDataIndex(),
-                                        getSelectedSpectrum()))
-      m_fitPropertyBrowser->updateErrors();
-    else
-      m_fitPropertyBrowser->clearErrors();
   } catch (const std::out_of_range &) {
+  } catch (const std::invalid_argument &) {
   }
 }
 
 void IndirectFitAnalysisTab::updateFitBrowserParameterValues() {
-  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
-  m_fitPropertyBrowser->updateParameters();
-}
-
-/**
- * Enables Plot Guess in the FitPropertyBrowser if a sample workspace is loaded
- */
-void IndirectFitAnalysisTab::updatePlotGuess() {
-  auto const sampleWorkspace =
-      m_fittingModel->getWorkspace(getSelectedDataIndex());
-  m_fitPropertyBrowser->updatePlotGuess(sampleWorkspace);
+  if (m_fittingAlgorithm) {
+    MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
+    if (m_fittingModel->getFittingMode() == FittingMode::SEQUENTIAL) {
+      auto const paramWsName =
+          m_fittingAlgorithm->getPropertyValue("OutputParameterWorkspace");
+      auto paramWs =
+          AnalysisDataService::Instance().retrieveWS<ITableWorkspace>(
+              paramWsName);
+      m_fitPropertyBrowser->updateMultiDatasetParameters(*paramWs);
+    } else {
+      IFunction_sptr fun = m_fittingAlgorithm->getProperty("Function");
+      if (fun->getNumberDomains() > 1)
+        m_fitPropertyBrowser->updateMultiDatasetParameters(*fun);
+      else
+        m_fitPropertyBrowser->updateParameters(*fun);
+    }
+  }
 }
 
 /**
@@ -946,8 +488,8 @@ void IndirectFitAnalysisTab::singleFit() {
   singleFit(getSelectedDataIndex(), getSelectedSpectrum());
 }
 
-void IndirectFitAnalysisTab::singleFit(std::size_t dataIndex,
-                                       std::size_t spectrum) {
+void IndirectFitAnalysisTab::singleFit(DatasetIndex dataIndex,
+                                       WorkspaceIndex spectrum) {
   if (validate()) {
     m_plotPresenter->setFitSingleSpectrumIsFitting(true);
     enableFitButtons(false);
@@ -977,7 +519,7 @@ bool IndirectFitAnalysisTab::validate() {
   const auto invalidFunction = m_fittingModel->isInvalidFunction();
   if (invalidFunction)
     validator.addErrorMessage(QString::fromStdString(*invalidFunction));
-  if (m_fittingModel->numberOfWorkspaces() == 0)
+  if (m_fittingModel->numberOfWorkspaces() == DatasetIndex{0})
     validator.addErrorMessage(
         QString::fromStdString("No data has been selected for a fit."));
 
@@ -993,6 +535,12 @@ void IndirectFitAnalysisTab::run() {
   setRunIsRunning(true);
   enableFitButtons(false);
   enableOutputOptions(false);
+  auto const fitType = m_fitPropertyBrowser->selectedFitType();
+  if (fitType == "Simultaneous") {
+    m_fittingModel->setFittingMode(FittingMode::SIMULTANEOUS);
+  } else {
+    m_fittingModel->setFittingMode(FittingMode::SEQUENTIAL);
+  }
   runFitAlgorithm(m_fittingModel->getFittingAlgorithm());
 }
 
@@ -1043,6 +591,12 @@ void IndirectFitAnalysisTab::setPDFWorkspace(std::string const &workspaceName) {
   m_outOptionsPresenter->setMultiWorkspaceOptionsVisible(enablePDFOptions);
 }
 
+void IndirectFitAnalysisTab::updateParameterEstimationData() {
+  m_fitPropertyBrowser->updateParameterEstimationData(
+      m_dataPresenter->getDataForParameterEstimation(
+          getEstimationDataSelector()));
+}
+
 /**
  * Sets the visiblity of the output options Edit Result button
  * @param visible :: true to make the edit result button visible
@@ -1090,20 +644,34 @@ void IndirectFitAnalysisTab::runSingleFit(IAlgorithm_sptr fitAlgorithm) {
 }
 
 void IndirectFitAnalysisTab::setupFit(IAlgorithm_sptr fitAlgorithm) {
-  disconnect(m_fitPropertyBrowser,
-             SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
-             m_plotPresenter.get(), SLOT(updateGuess()));
-
   setAlgorithmProperties(fitAlgorithm);
-
   m_fittingAlgorithm = fitAlgorithm;
   m_spectrumPresenter->disableView();
   m_batchAlgoRunner->addAlgorithm(fitAlgorithm);
-
   connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
           SLOT(fitAlgorithmComplete(bool)));
 }
 
+QStringList IndirectFitAnalysisTab::getDatasetNames() const {
+  QStringList datasetNames;
+  auto const numberWorkspaces = m_fittingModel->numberOfWorkspaces();
+  for (DatasetIndex i{0}; i < numberWorkspaces; ++i) {
+    auto const name =
+        QString::fromStdString(m_fittingModel->getWorkspace(i)->getName());
+    auto const numberSpectra = m_fittingModel->getNumberOfSpectra(i);
+    for (SpectrumRowIndex j{0}; j < numberSpectra; ++j) {
+      datasetNames << name + " (" + QString::number(j.value) + ")";
+    }
+  }
+  return datasetNames;
+}
+
+void IndirectFitAnalysisTab::updateDataReferences() {
+  m_fitPropertyBrowser->updateFunctionBrowserData(
+      m_fittingModel->getNumberOfDomains(), getDatasetNames());
+  m_fittingModel->setFitFunction(m_fitPropertyBrowser->getFittingFunction());
+}
+
 /**
  * Updates whether the options for plotting and saving fit results are
  * enabled/disabled.
@@ -1118,6 +686,84 @@ void IndirectFitAnalysisTab::updateResultOptions() {
   m_outOptionsPresenter->setSaveEnabled(isFit);
 }
 
+void IndirectFitAnalysisTab::respondToChangeOfSpectraRange(DatasetIndex i) {
+  m_plotPresenter->updateSelectedDataName();
+  m_plotPresenter->updateAvailableSpectra();
+  m_dataPresenter->updateSpectraInTable(i);
+  m_fitPropertyBrowser->updateFunctionBrowserData(
+      m_fittingModel->getNumberOfDomains(), getDatasetNames());
+  setModelFitFunction();
+  updateParameterEstimationData();
+}
+
+void IndirectFitAnalysisTab::respondToSingleResolutionLoaded() {
+  setModelFitFunction();
+  m_plotPresenter->updatePlots();
+  m_plotPresenter->updateGuess();
+}
+
+void IndirectFitAnalysisTab::respondToDataChanged() {
+  updateResultOptions();
+  updateDataReferences();
+  m_spectrumPresenter->updateSpectra();
+  m_plotPresenter->updateAvailableSpectra();
+  m_plotPresenter->updatePlots();
+  m_plotPresenter->updateGuess();
+  updateParameterEstimationData();
+}
+
+void IndirectFitAnalysisTab::respondToSingleDataViewSelected() {
+  m_spectrumPresenter->setActiveIndexToZero();
+  m_plotPresenter->hideMultipleDataSelection();
+}
+
+void IndirectFitAnalysisTab::respondToMultipleDataViewSelected() {
+  m_plotPresenter->showMultipleDataSelection();
+}
+
+void IndirectFitAnalysisTab::respondToDataAdded() {
+  updateDataReferences();
+  m_plotPresenter->appendLastDataToSelection();
+  updateParameterEstimationData();
+}
+
+void IndirectFitAnalysisTab::respondToDataRemoved() {
+  updateDataReferences();
+  m_plotPresenter->updateDataSelection();
+  updateParameterEstimationData();
+}
+
+void IndirectFitAnalysisTab::respondToSelectedFitDataChanged(DatasetIndex i) {
+  m_spectrumPresenter->setActiveModelIndex(i);
+  updateParameterValues();
+}
+
+void IndirectFitAnalysisTab::respondToNoFitDataSelected() {
+  m_spectrumPresenter->disableView();
+}
+
+void IndirectFitAnalysisTab::respondToPlotSpectrumChanged(WorkspaceIndex) {
+  auto const index = m_plotPresenter->getSelectedDomainIndex();
+  m_fitPropertyBrowser->setCurrentDataset(index);
+}
+
+void IndirectFitAnalysisTab::respondToFwhmChanged(double) {
+  updateFitBrowserParameterValues();
+  m_plotPresenter->updateGuess();
+}
+
+void IndirectFitAnalysisTab::respondToBackgroundChanged(double value) {
+  m_fitPropertyBrowser->setBackgroundA0(value);
+  setModelFitFunction();
+  m_plotPresenter->updateGuess();
+}
+
+void IndirectFitAnalysisTab::respondToFunctionChanged() {
+  setModelFitFunction();
+  m_plotPresenter->updatePlots();
+  m_plotPresenter->updateGuess();
+}
+
 } // namespace IDA
 } // namespace CustomInterfaces
 } // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
index 71062d6aa99..7a8ef93930e 100644
--- a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTab.h
@@ -7,17 +7,16 @@
 #ifndef MANTIDQTCUSTOMINTERFACESIDA_IFATAB_H_
 #define MANTIDQTCUSTOMINTERFACESIDA_IFATAB_H_
 
-#include "IndirectDataAnalysisTabLegacy.h"
-#include "IndirectFitDataPresenterLegacy.h"
+#include "IndirectDataAnalysisTab.h"
+#include "IndirectFitDataPresenter.h"
 #include "IndirectFitOutputOptionsPresenter.h"
 #include "IndirectFitOutputOptionsView.h"
-#include "IndirectFitPlotPresenterLegacy.h"
-#include "IndirectFittingModelLegacy.h"
+#include "IndirectFitPlotPresenter.h"
+#include "IndirectFitPropertyBrowser.h"
+#include "IndirectFittingModel.h"
 #include "IndirectSpectrumSelectionPresenter.h"
 #include "IndirectSpectrumSelectionView.h"
 
-#include "MantidQtWidgets/Common/IndirectFitPropertyBrowserLegacy.h"
-
 #include <boost/optional.hpp>
 
 #include <QtCore>
@@ -29,107 +28,40 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-class DLLExport IndirectFitAnalysisTab : public IndirectDataAnalysisTabLegacy {
+class DLLExport IndirectFitAnalysisTab : public IndirectDataAnalysisTab {
   Q_OBJECT
 
 public:
-  IndirectFitAnalysisTab(IndirectFittingModelLegacy *model,
+  IndirectFitAnalysisTab(IndirectFittingModel *model,
                          QWidget *parent = nullptr);
 
-  void setFitDataPresenter(std::unique_ptr<IndirectFitDataPresenterLegacy> presenter);
-  void setPlotView(IIndirectFitPlotViewLegacy *view);
+  void setFitDataPresenter(std::unique_ptr<IndirectFitDataPresenter> presenter);
+  void setPlotView(IIndirectFitPlotView *view);
   void setSpectrumSelectionView(IndirectSpectrumSelectionView *view);
   void setOutputOptionsView(IIndirectFitOutputOptionsView *view);
-  void
-  setFitPropertyBrowser(MantidWidgets::IndirectFitPropertyBrowserLegacy *browser);
+  void setFitPropertyBrowser(IndirectFitPropertyBrowser *browser);
+  DatasetIndex getSelectedDataIndex() const;
+  WorkspaceIndex getSelectedSpectrum() const;
+  bool isRangeCurrentlySelected(DatasetIndex dataIndex,
+                                WorkspaceIndex spectrum) const;
 
   virtual std::string tabName() const = 0;
 
   virtual bool hasResolution() const = 0;
-
-  std::size_t getSelectedDataIndex() const;
-  std::size_t getSelectedSpectrum() const;
-  bool isRangeCurrentlySelected(std::size_t dataIndex,
-                                std::size_t spectrum) const;
-
   QString selectedFitType() const;
-
   size_t numberOfCustomFunctions(const std::string &functionName) const;
-
   void setConvolveMembers(bool convolveMembers);
 
-  void updateTies();
-
-  void setCustomSettingEnabled(const QString &customName, bool enabled);
-
-  void setParameterValue(const std::string &functionName,
-                         const std::string &parameterName, double value);
-
-  void setDefaultPeakType(const std::string &function);
-
-  void addCheckBoxFunctionGroup(
-      const QString &groupName,
-      const std::vector<Mantid::API::IFunction_sptr> &functions,
-      bool defaultValue = false);
-
-  void addSpinnerFunctionGroup(
-      const QString &groupName,
-      const std::vector<Mantid::API::IFunction_sptr> &functions,
-      int minimum = 0, int maximum = 10, int defaultValue = 0);
-
-  void addComboBoxFunctionGroup(
-      const QString &groupName,
-      const std::vector<Mantid::API::IFunction_sptr> &functions);
-  void clearFitTypeComboBox();
-
-  void setBackgroundOptions(const QStringList &backgrounds);
-
-  bool boolSettingValue(const QString &settingKey) const;
-
-  void setCustomBoolSetting(const QString &settingKey, bool value);
-
-  int intSettingValue(const QString &settingKey) const;
-
-  double doubleSettingValue(const QString &settingKey) const;
-
-  QString enumSettingValue(const QString &settingKey) const;
-
-  void addBoolCustomSetting(const QString &settingKey,
-                            const QString &settingName,
-                            bool defaultValue = false);
-
-  void addDoubleCustomSetting(const QString &settingKey,
-                              const QString &settingName,
-                              double defaultValue = 0);
-
-  void addIntCustomSetting(const QString &settingKey,
-                           const QString &settingName, int defaultValue = 0);
-
-  void addEnumCustomSetting(const QString &settingKey,
-                            const QString &settingName,
-                            const QStringList &options);
-
-  void addOptionalDoubleSetting(const QString &settingKey,
-                                const QString &settingName,
-                                const QString &optionKey,
-                                const QString &optionName, bool enabled = false,
-                                double defaultValue = 0);
-
-  void setCustomSettingChangesFunction(const QString &settingKey,
-                                       bool changesFunction);
-
-public slots:
-  void setBrowserWorkspace() override;
-
 protected:
-  IndirectFittingModelLegacy *fittingModel() const;
-
+  IndirectFittingModel *fittingModel() const;
   void run() override;
-
   void setSampleWSSuffixes(const QStringList &suffices);
   void setSampleFBSuffixes(const QStringList &suffices);
   void setResolutionWSSuffixes(const QStringList &suffices);
   void setResolutionFBSuffixes(const QStringList &suffices);
+  void setFileExtensionsByName(bool filter) override;
+  void setSampleSuffixes(std::string const &tab, bool filter);
+  void setResolutionSuffixes(std::string const &tab, bool filter);
 
   void setAlgorithmProperties(Mantid::API::IAlgorithm_sptr fitAlgorithm) const;
   void runFitAlgorithm(Mantid::API::IAlgorithm_sptr fitAlgorithm);
@@ -147,92 +79,77 @@ signals:
   void updateAvailableFitTypes();
 
 protected slots:
-
   void setModelFitFunction();
   void setModelStartX(double startX);
   void setModelEndX(double startX);
   void setDataTableStartX(double startX);
   void setDataTableEndX(double endX);
   void setDataTableExclude(const std::string &exclude);
-  void setBrowserStartX(double startX);
-  void setBrowserEndX(double endX);
-  void updateBrowserFittingRange();
-  void setBrowserWorkspace(std::size_t dataIndex);
-  void setBrowserWorkspaceIndex(std::size_t spectrum);
-  void setBrowserWorkspaceIndex(int spectrum);
-  void tableStartXChanged(double startX, std::size_t dataIndex,
-                          std::size_t spectrum);
-  void tableEndXChanged(double endX, std::size_t dataIndex,
-                        std::size_t spectrum);
-  void tableExcludeChanged(const std::string &exclude, std::size_t dataIndex,
-                           std::size_t spectrum);
-
+  void tableStartXChanged(double startX, DatasetIndex dataIndex,
+                          WorkspaceIndex spectrum);
+  void tableEndXChanged(double endX, DatasetIndex dataIndex,
+                        WorkspaceIndex spectrum);
+  void tableExcludeChanged(const std::string &exclude, DatasetIndex dataIndex,
+                           WorkspaceIndex spectrum);
+  void startXChanged(double startX);
+  void endXChanged(double endX);
   void updateFitOutput(bool error);
   void updateSingleFitOutput(bool error);
   void fitAlgorithmComplete(bool error);
-
   void singleFit();
-  void singleFit(std::size_t dataIndex, std::size_t spectrum);
+  void singleFit(DatasetIndex dataIndex, WorkspaceIndex spectrum);
   void executeFit();
-
-  void updateAttributeValues();
-  void updateAttributeValues(Mantid::API::IFunction_sptr function,
-                             std::vector<std::string> const &attributeNames);
-  void updateAttributeValues(
-      Mantid::API::IFunction_sptr function,
-      std::vector<std::string> const &attributeNames,
-      std::unordered_map<std::string, Mantid::API::IFunction::Attribute> const
-          &attributes);
-  void updateFitBrowserAttributeValues();
-  std::unordered_map<std::string, Mantid::API::IFunction::Attribute>
-  getAttributes(Mantid::API::IFunction_sptr const &function,
-                std::vector<std::string> const &attributeNames);
   void updateParameterValues();
   void updateParameterValues(
       const std::unordered_map<std::string, ParameterValue> &parameters);
   void updateFitBrowserParameterValues();
-
+  void updateDataReferences();
   void updateResultOptions();
 
 private slots:
-  void updatePlotGuess();
   void plotSelectedSpectra();
+  void respondToChangeOfSpectraRange(DatasetIndex);
+  void respondToSingleResolutionLoaded();
+  void respondToDataChanged();
+  void respondToSingleDataViewSelected();
+  void respondToMultipleDataViewSelected();
+  void respondToDataAdded();
+  void respondToDataRemoved();
+  void respondToSelectedFitDataChanged(DatasetIndex);
+  void respondToNoFitDataSelected();
+  void respondToPlotSpectrumChanged(WorkspaceIndex);
+  void respondToFwhmChanged(double);
+  void respondToBackgroundChanged(double);
+  void respondToFunctionChanged();
 
 private:
   /// Overidden by child class.
   void setup() override;
   void loadSettings(const QSettings &settings) override;
-  virtual void setupFitTab() = 0;
   bool validate() override;
-
-  void setFileExtensionsByName(bool filter) override;
-  void setSampleSuffixes(std::string const &tab, bool filter);
-  void setResolutionSuffixes(std::string const &tab, bool filter);
-
-  void connectDataAndPlotPresenters();
-  void connectSpectrumAndPlotPresenters();
-  void connectFitBrowserAndPlotPresenter();
-  void connectDataAndSpectrumPresenters();
-  void connectDataAndFitBrowserPresenters();
-
+  virtual void setupFitTab() = 0;
+  virtual EstimationDataSelector getEstimationDataSelector() const = 0;
+  void connectPlotPresenter();
+  void connectSpectrumPresenter();
+  void connectFitPropertyBrowser();
+  void connectDataPresenter();
   void plotSelectedSpectra(std::vector<SpectrumToPlot> const &spectra);
   void plotSpectrum(std::string const &workspaceName, std::size_t const &index);
-
   std::string getOutputBasename() const;
   Mantid::API::WorkspaceGroup_sptr getResultWorkspace() const;
   std::vector<std::string> getFitParameterNames() const;
-
+  QStringList getDatasetNames() const;
   void enableFitButtons(bool enable);
   void enableOutputOptions(bool enable);
   void setPDFWorkspace(std::string const &workspaceName);
+  void updateParameterEstimationData();
 
-  std::unique_ptr<IndirectFittingModelLegacy> m_fittingModel;
-  MantidWidgets::IndirectFitPropertyBrowserLegacy *m_fitPropertyBrowser;
-  std::unique_ptr<IndirectFitDataPresenterLegacy> m_dataPresenter;
-  std::unique_ptr<IndirectFitPlotPresenterLegacy> m_plotPresenter;
+  std::unique_ptr<IndirectFittingModel> m_fittingModel;
+  std::unique_ptr<IndirectFitDataPresenter> m_dataPresenter;
+  std::unique_ptr<IndirectFitPlotPresenter> m_plotPresenter;
   std::unique_ptr<IndirectSpectrumSelectionPresenter> m_spectrumPresenter;
   std::unique_ptr<IndirectFitOutputOptionsPresenter> m_outOptionsPresenter;
-
+  IndirectFitPropertyBrowser *m_fitPropertyBrowser;
   Mantid::API::IAlgorithm_sptr m_fittingAlgorithm;
 };
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.cpp b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.cpp
new file mode 100644
index 00000000000..e8be125e155
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.cpp
@@ -0,0 +1,1123 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "IndirectFitAnalysisTabLegacy.h"
+#include "ui_ConvFit.h"
+#include "ui_IqtFit.h"
+#include "ui_JumpFit.h"
+#include "ui_MSDFit.h"
+
+#include "MantidAPI/FunctionFactory.h"
+#include "MantidAPI/TextAxis.h"
+#include "MantidAPI/WorkspaceFactory.h"
+
+#include "MantidQtWidgets/Common/PropertyHandler.h"
+#include "MantidQtWidgets/Common/SignalBlocker.h"
+
+#include <QString>
+#include <QtCore>
+
+#include <algorithm>
+
+using namespace Mantid::API;
+
+namespace {
+using namespace MantidQt::CustomInterfaces::IDA;
+
+bool doesExistInADS(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().doesExist(workspaceName);
+}
+
+WorkspaceGroup_sptr getADSGroupWorkspace(std::string const &workspaceName) {
+  return AnalysisDataService::Instance().retrieveWS<WorkspaceGroup>(
+      workspaceName);
+}
+
+void updateParameters(
+    IFunction_sptr function,
+    std::unordered_map<std::string, ParameterValue> const &parameters) {
+  for (auto i = 0u; i < function->nParams(); ++i) {
+    auto const value = parameters.find(function->parameterName(i));
+    if (value != parameters.end()) {
+      function->setParameter(i, value->second.value);
+      if (value->second.error)
+        function->setError(i, *value->second.error);
+    }
+  }
+}
+
+void updateAttributes(
+    IFunction_sptr function, std::vector<std::string> const &attributeNames,
+    std::unordered_map<std::string, IFunction::Attribute> const &attributes) {
+  for (const auto &attributeName : attributeNames) {
+    auto const value = attributes.find(attributeName);
+    if (value != attributes.end())
+      function->setAttribute(attributeName, value->second);
+  }
+}
+
+} // namespace
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+IndirectFitAnalysisTabLegacy::IndirectFitAnalysisTabLegacy(IndirectFittingModelLegacy *model,
+                                               QWidget *parent)
+    : IndirectDataAnalysisTabLegacy(parent), m_fittingModel(model) {}
+
+void IndirectFitAnalysisTabLegacy::setup() {
+  setupFitTab();
+  updateResultOptions();
+
+  connect(m_dataPresenter.get(),
+          SIGNAL(startXChanged(double, std::size_t, std::size_t)), this,
+          SLOT(tableStartXChanged(double, std::size_t, std::size_t)));
+  connect(m_dataPresenter.get(),
+          SIGNAL(endXChanged(double, std::size_t, std::size_t)), this,
+          SLOT(tableEndXChanged(double, std::size_t, std::size_t)));
+  connect(
+      m_dataPresenter.get(),
+      SIGNAL(
+          excludeRegionChanged(const std::string &, std::size_t, std::size_t)),
+      this,
+      SLOT(tableExcludeChanged(const std::string &, std::size_t, std::size_t)));
+  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()), this,
+          SLOT(setModelFitFunction()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(fitScheduled()), this,
+          SLOT(singleFit()));
+  connect(m_fitPropertyBrowser, SIGNAL(sequentialFitScheduled()), this,
+          SLOT(executeFit()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)), this,
+          SLOT(setModelStartX(double)));
+  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)), this,
+          SLOT(setModelEndX(double)));
+
+  connect(m_fitPropertyBrowser,
+          SIGNAL(parameterChanged(const Mantid::API::IFunction *)), this,
+          SIGNAL(parameterChanged(const Mantid::API::IFunction *)));
+
+  connect(m_fitPropertyBrowser,
+          SIGNAL(customBoolChanged(const QString &, bool)), this,
+          SIGNAL(customBoolChanged(const QString &, bool)));
+
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(setModelFitFunction()));
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SIGNAL(functionChanged()));
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(updateResultOptions()));
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(updateParameterValues()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(updatePlotGuess()));
+  connect(m_fitPropertyBrowser, SIGNAL(workspaceNameChanged(const QString &)),
+          this, SLOT(updatePlotGuess()));
+
+  connect(m_plotPresenter.get(),
+          SIGNAL(fitSingleSpectrum(std::size_t, std::size_t)), this,
+          SLOT(singleFit(std::size_t, std::size_t)));
+  connect(m_plotPresenter.get(),
+          SIGNAL(runAsPythonScript(const QString &, bool)), this,
+          SIGNAL(runAsPythonScript(const QString &, bool)));
+
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
+          SLOT(updateResultOptions()));
+  connect(m_dataPresenter.get(), SIGNAL(updateAvailableFitTypes()), this,
+          SIGNAL(updateAvailableFitTypes()));
+
+  connect(m_outOptionsPresenter.get(), SIGNAL(plotSpectra()), this,
+          SLOT(plotSelectedSpectra()));
+
+  connectDataAndSpectrumPresenters();
+  connectDataAndPlotPresenters();
+  connectDataAndFitBrowserPresenters();
+  connectSpectrumAndPlotPresenters();
+  connectFitBrowserAndPlotPresenter();
+}
+
+void IndirectFitAnalysisTabLegacy::connectDataAndPlotPresenters() {
+  connect(m_dataPresenter.get(), SIGNAL(multipleDataViewSelected()),
+          m_plotPresenter.get(), SLOT(showMultipleDataSelection()));
+  connect(m_dataPresenter.get(), SIGNAL(singleDataViewSelected()),
+          m_plotPresenter.get(), SLOT(hideMultipleDataSelection()));
+
+  connect(m_dataPresenter.get(), SIGNAL(dataAdded()), m_plotPresenter.get(),
+          SLOT(appendLastDataToSelection()));
+  connect(m_dataPresenter.get(), SIGNAL(dataRemoved()), m_plotPresenter.get(),
+          SLOT(updateDataSelection()));
+
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
+          SLOT(updateAvailableSpectra()));
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
+          SLOT(updatePlots()));
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), m_plotPresenter.get(),
+          SLOT(updateGuess()));
+
+  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()),
+          m_plotPresenter.get(), SLOT(updatePlots()));
+  connect(m_dataPresenter.get(), SIGNAL(singleResolutionLoaded()),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+
+  connect(m_plotPresenter.get(), SIGNAL(startXChanged(double)), this,
+          SLOT(setDataTableStartX(double)));
+  connect(m_plotPresenter.get(), SIGNAL(endXChanged(double)), this,
+          SLOT(setDataTableEndX(double)));
+}
+
+void IndirectFitAnalysisTabLegacy::connectSpectrumAndPlotPresenters() {
+  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
+          m_spectrumPresenter.get(), SLOT(setActiveModelIndex(std::size_t)));
+  connect(m_plotPresenter.get(), SIGNAL(noFitDataSelected()),
+          m_spectrumPresenter.get(), SLOT(disableView()));
+  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
+          m_plotPresenter.get(), SLOT(updateSelectedDataName()));
+  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
+          m_plotPresenter.get(), SLOT(updateAvailableSpectra()));
+}
+
+void IndirectFitAnalysisTabLegacy::connectFitBrowserAndPlotPresenter() {
+  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
+          this, SLOT(setBrowserWorkspace(std::size_t)));
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()), this,
+          SLOT(updateAttributeValues()));
+  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
+          this, SLOT(updateAttributeValues()));
+  connect(m_plotPresenter.get(), SIGNAL(selectedFitDataChanged(std::size_t)),
+          this, SLOT(updateParameterValues()));
+  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
+          SLOT(setBrowserWorkspaceIndex(std::size_t)));
+  // Update attributes before parameters as the parameters may depend on the
+  // attribute values
+  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
+          SLOT(updateAttributeValues()));
+  connect(m_plotPresenter.get(), SIGNAL(plotSpectrumChanged(std::size_t)), this,
+          SLOT(updateParameterValues()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)),
+          m_plotPresenter.get(), SLOT(setStartX(double)));
+  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)),
+          m_plotPresenter.get(), SLOT(setEndX(double)));
+  connect(m_fitPropertyBrowser, SIGNAL(updatePlotSpectrum(int)),
+          m_plotPresenter.get(), SLOT(updatePlotSpectrum(int)));
+  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
+          SLOT(setBrowserWorkspaceIndex(int)));
+  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
+          SLOT(updateAttributeValues()));
+  connect(m_fitPropertyBrowser, SIGNAL(workspaceIndexChanged(int)), this,
+          SLOT(updateParameterValues()));
+
+  connect(m_plotPresenter.get(), SIGNAL(startXChanged(double)), this,
+          SLOT(setBrowserStartX(double)));
+  connect(m_plotPresenter.get(), SIGNAL(endXChanged(double)), this,
+          SLOT(setBrowserEndX(double)));
+  connect(m_plotPresenter.get(), SIGNAL(fwhmChanged(double)), this,
+          SLOT(updateFitBrowserParameterValues()));
+  connect(m_plotPresenter.get(), SIGNAL(backgroundChanged(double)), this,
+          SLOT(updateFitBrowserParameterValues()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(xRangeChanged(double, double)),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+  connect(m_plotPresenter.get(), SIGNAL(fwhmChanged(double)),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+  connect(m_plotPresenter.get(), SIGNAL(backgroundChanged(double)),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+
+  connect(m_fitPropertyBrowser,
+          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
+          m_plotPresenter.get(), SLOT(updateRangeSelectors()));
+  connect(m_fitPropertyBrowser,
+          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()),
+          m_plotPresenter.get(), SLOT(updatePlots()));
+  connect(m_fitPropertyBrowser, SIGNAL(functionChanged()),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+
+  connect(m_fitPropertyBrowser, SIGNAL(plotGuess()), m_plotPresenter.get(),
+          SLOT(enablePlotGuessInSeparateWindow()));
+}
+
+void IndirectFitAnalysisTabLegacy::connectDataAndSpectrumPresenters() {
+  connect(m_dataPresenter.get(), SIGNAL(singleDataViewSelected()),
+          m_spectrumPresenter.get(), SLOT(setActiveIndexToZero()));
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()),
+          m_spectrumPresenter.get(), SLOT(updateSpectra()));
+  connect(m_spectrumPresenter.get(), SIGNAL(spectraChanged(std::size_t)),
+          m_dataPresenter.get(), SLOT(updateSpectraInTable(std::size_t)));
+  connect(m_spectrumPresenter.get(), SIGNAL(maskChanged(const std::string &)),
+          this, SLOT(setDataTableExclude(const std::string &)));
+}
+
+void IndirectFitAnalysisTabLegacy::connectDataAndFitBrowserPresenters() {
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
+          SLOT(updateBrowserFittingRange()));
+  connect(m_dataPresenter.get(), SIGNAL(dataChanged()), this,
+          SLOT(setBrowserWorkspace()));
+  connect(m_fitPropertyBrowser, SIGNAL(startXChanged(double)), this,
+          SLOT(setDataTableStartX(double)));
+  connect(m_fitPropertyBrowser, SIGNAL(endXChanged(double)), this,
+          SLOT(setDataTableEndX(double)));
+}
+
+void IndirectFitAnalysisTabLegacy::setFitDataPresenter(
+    std::unique_ptr<IndirectFitDataPresenterLegacy> presenter) {
+  m_dataPresenter = std::move(presenter);
+}
+
+void IndirectFitAnalysisTabLegacy::setPlotView(IIndirectFitPlotViewLegacy *view) {
+  m_plotPresenter = std::make_unique<IndirectFitPlotPresenterLegacy>(
+      m_fittingModel.get(), view, this);
+}
+
+void IndirectFitAnalysisTabLegacy::setSpectrumSelectionView(
+    IndirectSpectrumSelectionViewLegacy *view) {
+  m_spectrumPresenter = std::make_unique<IndirectSpectrumSelectionPresenterLegacy>(
+      m_fittingModel.get(), view);
+}
+
+void IndirectFitAnalysisTabLegacy::setOutputOptionsView(
+    IIndirectFitOutputOptionsView *view) {
+  m_outOptionsPresenter =
+      std::make_unique<IndirectFitOutputOptionsPresenter>(view);
+}
+
+void IndirectFitAnalysisTabLegacy::setFitPropertyBrowser(
+    MantidWidgets::IndirectFitPropertyBrowserLegacy *browser) {
+  browser->init();
+  m_fitPropertyBrowser = browser;
+}
+
+void IndirectFitAnalysisTabLegacy::loadSettings(const QSettings &settings) {
+  m_dataPresenter->loadSettings(settings);
+}
+
+void IndirectFitAnalysisTabLegacy::setFileExtensionsByName(bool filter) {
+  auto const tab = tabName();
+  setSampleSuffixes(tab, filter);
+  if (hasResolution())
+    setResolutionSuffixes(tab, filter);
+}
+
+void IndirectFitAnalysisTabLegacy::setSampleSuffixes(std::string const &tab,
+                                               bool filter) {
+  QStringList const noSuffixes{""};
+  setSampleWSSuffixes(filter ? getSampleWSSuffixes(tab) : noSuffixes);
+  setSampleFBSuffixes(filter ? getSampleFBSuffixes(tab) : getExtensions(tab));
+  m_dataPresenter->setMultiInputSampleWSSuffixes();
+  m_dataPresenter->setMultiInputSampleFBSuffixes();
+}
+
+void IndirectFitAnalysisTabLegacy::setResolutionSuffixes(std::string const &tab,
+                                                   bool filter) {
+  QStringList const noSuffixes{""};
+  setResolutionWSSuffixes(filter ? getResolutionWSSuffixes(tab) : noSuffixes);
+  setResolutionFBSuffixes(filter ? getResolutionFBSuffixes(tab)
+                                 : getExtensions(tab));
+  m_dataPresenter->setMultiInputResolutionWSSuffixes();
+  m_dataPresenter->setMultiInputResolutionFBSuffixes();
+}
+
+void IndirectFitAnalysisTabLegacy::setSampleWSSuffixes(const QStringList &suffices) {
+  m_dataPresenter->setSampleWSSuffices(suffices);
+}
+
+void IndirectFitAnalysisTabLegacy::setSampleFBSuffixes(const QStringList &suffices) {
+  m_dataPresenter->setSampleFBSuffices(suffices);
+}
+
+void IndirectFitAnalysisTabLegacy::setResolutionWSSuffixes(
+    const QStringList &suffices) {
+  m_dataPresenter->setResolutionWSSuffices(suffices);
+}
+
+void IndirectFitAnalysisTabLegacy::setResolutionFBSuffixes(
+    const QStringList &suffices) {
+  m_dataPresenter->setResolutionFBSuffices(suffices);
+}
+
+std::size_t IndirectFitAnalysisTabLegacy::getSelectedDataIndex() const {
+  return m_plotPresenter->getSelectedDataIndex();
+}
+
+std::size_t IndirectFitAnalysisTabLegacy::getSelectedSpectrum() const {
+  return m_plotPresenter->getSelectedSpectrum();
+}
+
+bool IndirectFitAnalysisTabLegacy::isRangeCurrentlySelected(
+    std::size_t dataIndex, std::size_t spectrum) const {
+  return FittingMode::SEQUENTIAL == m_fittingModel->getFittingMode() ||
+         m_plotPresenter->isCurrentlySelected(dataIndex, spectrum);
+}
+
+IndirectFittingModelLegacy *IndirectFitAnalysisTabLegacy::fittingModel() const {
+  return m_fittingModel.get();
+}
+
+/**
+ * @return  The fit type selected in the custom functions combo box, in the fit
+ *          property browser.
+ */
+QString IndirectFitAnalysisTabLegacy::selectedFitType() const {
+  return m_fitPropertyBrowser->selectedFitType();
+}
+
+/**
+ * @param functionName  The name of the function.
+ * @return              The number of custom functions, with the specified name,
+ *                      included in the selected model.
+ */
+size_t IndirectFitAnalysisTabLegacy::numberOfCustomFunctions(
+    const std::string &functionName) const {
+  return m_fitPropertyBrowser->numberOfCustomFunctions(functionName);
+}
+
+void IndirectFitAnalysisTabLegacy::setModelFitFunction() {
+  try {
+    m_fittingModel->setFitFunction(m_fitPropertyBrowser->getFittingFunction());
+  } catch (const std::out_of_range &) {
+    m_fittingModel->setFitFunction(m_fitPropertyBrowser->compositeFunction());
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::setModelStartX(double startX) {
+  const auto dataIndex = getSelectedDataIndex();
+  if (m_fittingModel->numberOfWorkspaces() > dataIndex) {
+    m_fittingModel->setStartX(startX, dataIndex, getSelectedSpectrum());
+  } else {
+    setBrowserStartX(0);
+    setBrowserEndX(0);
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::setModelEndX(double endX) {
+  const auto dataIndex = getSelectedDataIndex();
+  if (m_fittingModel->numberOfWorkspaces() > dataIndex) {
+    m_fittingModel->setEndX(endX, dataIndex, getSelectedSpectrum());
+  } else {
+    setBrowserStartX(0);
+    setBrowserEndX(0);
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::setDataTableStartX(double startX) {
+  m_dataPresenter->setStartX(startX, m_plotPresenter->getSelectedDataIndex(),
+                             m_plotPresenter->getSelectedSpectrumIndex());
+}
+
+void IndirectFitAnalysisTabLegacy::setDataTableEndX(double endX) {
+  m_dataPresenter->setEndX(endX, m_plotPresenter->getSelectedDataIndex(),
+                           m_plotPresenter->getSelectedSpectrumIndex());
+}
+
+void IndirectFitAnalysisTabLegacy::setDataTableExclude(const std::string &exclude) {
+  m_dataPresenter->setExclude(exclude, m_plotPresenter->getSelectedDataIndex(),
+                              m_plotPresenter->getSelectedSpectrumIndex());
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserStartX(double startX) {
+  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
+  m_fitPropertyBrowser->setStartX(startX);
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserEndX(double endX) {
+  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
+  m_fitPropertyBrowser->setEndX(endX);
+}
+
+void IndirectFitAnalysisTabLegacy::updateBrowserFittingRange() {
+  const auto range = m_fittingModel->getFittingRange(getSelectedDataIndex(),
+                                                     getSelectedSpectrum());
+  setBrowserStartX(range.first);
+  setBrowserEndX(range.second);
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserWorkspace() {
+  if (m_fittingModel->numberOfWorkspaces() > 0) {
+    auto const name =
+        m_fittingModel->getWorkspace(getSelectedDataIndex())->getName();
+    m_fitPropertyBrowser->setWorkspaceName(QString::fromStdString(name));
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserWorkspace(std::size_t dataIndex) {
+  const auto name = m_fittingModel->getWorkspace(dataIndex)->getName();
+  m_fitPropertyBrowser->setWorkspaceName(QString::fromStdString(name));
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserWorkspaceIndex(std::size_t spectrum) {
+  setBrowserWorkspaceIndex(boost::numeric_cast<int>(spectrum));
+}
+
+void IndirectFitAnalysisTabLegacy::setBrowserWorkspaceIndex(int spectrum) {
+  m_fitPropertyBrowser->setWorkspaceIndex(spectrum);
+}
+
+void IndirectFitAnalysisTabLegacy::tableStartXChanged(double startX,
+                                                std::size_t dataIndex,
+                                                std::size_t spectrum) {
+  if (isRangeCurrentlySelected(dataIndex, spectrum)) {
+    m_plotPresenter->setStartX(startX);
+    setBrowserStartX(startX);
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::tableEndXChanged(double endX,
+                                              std::size_t dataIndex,
+                                              std::size_t spectrum) {
+  if (isRangeCurrentlySelected(dataIndex, spectrum)) {
+    m_plotPresenter->setEndX(endX);
+    setBrowserEndX(endX);
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::tableExcludeChanged(const std::string & /*unused*/,
+                                                 std::size_t dataIndex,
+                                                 std::size_t spectrum) {
+  if (isRangeCurrentlySelected(dataIndex, spectrum))
+    m_spectrumPresenter->displayBinMask();
+}
+
+/**
+ * Sets whether fit members should be convolved with the resolution after a fit.
+ *
+ * @param convolveMembers If true, members are to be convolved.
+ */
+void IndirectFitAnalysisTabLegacy::setConvolveMembers(bool convolveMembers) {
+  m_fitPropertyBrowser->setConvolveMembers(convolveMembers);
+}
+
+/**
+ * Updates the ties displayed in the fit property browser, using
+ * the set fitting function.
+ */
+void IndirectFitAnalysisTabLegacy::updateTies() {
+  m_fitPropertyBrowser->updateTies();
+}
+
+/**
+ * Sets whether the custom setting with the specified name is enabled.
+ *
+ * @param settingName The name of the custom setting.
+ * @param enabled     True if custom setting should be enabled, false otherwise.
+ */
+void IndirectFitAnalysisTabLegacy::setCustomSettingEnabled(const QString &customName,
+                                                     bool enabled) {
+  m_fitPropertyBrowser->setCustomSettingEnabled(customName, enabled);
+}
+
+/**
+ * Sets the value of the parameter with the specified name, in the function with
+ * the specified name.
+ *
+ * @param functionName  The name of the function containing the parameter.
+ * @param parameterName The name of the parameter to set.
+ * @param value         The value to set.
+ */
+void IndirectFitAnalysisTabLegacy::setParameterValue(const std::string &functionName,
+                                               const std::string &parameterName,
+                                               double value) {
+  m_fitPropertyBrowser->setParameterValue(functionName, parameterName, value);
+}
+
+/**
+ * Sets the default peak type for the indirect property browser.
+ *
+ * @param function  The name of the default peak function to set.
+ */
+void IndirectFitAnalysisTabLegacy::setDefaultPeakType(const std::string &function) {
+  m_fitPropertyBrowser->setDefaultPeakType(function);
+}
+
+/**
+ * Adds a check-box with the specified name, to the fit property browser, which
+ * when checked adds the specified functions to the mode and when unchecked,
+ * removes them.
+ *
+ * @param groupName     The name/label of the check-box to add.
+ * @param functions     The functions to be added when the check-box is checked.
+ * @param defaultValue  The default value of the check-box.
+ */
+void IndirectFitAnalysisTabLegacy::addCheckBoxFunctionGroup(
+    const QString &groupName, const std::vector<IFunction_sptr> &functions,
+    bool defaultValue) {
+  m_fitPropertyBrowser->addCheckBoxFunctionGroup(groupName, functions,
+                                                 defaultValue);
+}
+
+/**
+ * Adds a number spinner with the specified name, to the fit property browser,
+ * which specifies how many multiples of the specified functions should be added
+ * to the model.
+ *
+ * @param groupName     The name/label of the spinner to add.
+ * @param functions     The functions to be added.
+ * @param minimum       The minimum value of the spinner.
+ * @param maximum       The maximum value of the spinner.
+ * @param defaultValue  The default value of the spinner.
+ */
+void IndirectFitAnalysisTabLegacy::addSpinnerFunctionGroup(
+    const QString &groupName, const std::vector<IFunction_sptr> &functions,
+    int minimum, int maximum, int defaultValue) {
+  m_fitPropertyBrowser->addSpinnerFunctionGroup(groupName, functions, minimum,
+                                                maximum, defaultValue);
+}
+
+/**
+ * Adds an option with the specified name, to the fit type combo-box in the fit
+ * property browser, which adds the specified functions to the model.
+ *
+ * @param groupName The name of the option to be added to the fit type
+ *                  combo-box.
+ * @param functions The functions added by the option.
+ */
+void IndirectFitAnalysisTabLegacy::addComboBoxFunctionGroup(
+    const QString &groupName, const std::vector<IFunction_sptr> &functions) {
+  m_fitPropertyBrowser->addComboBoxFunctionGroup(groupName, functions);
+}
+
+/**
+ * Removes all options from the Fit Type combo-box apart from the 'None' option
+ *
+ */
+void IndirectFitAnalysisTabLegacy::clearFitTypeComboBox() {
+  m_fitPropertyBrowser->clearFitTypeComboBox();
+}
+
+/**
+ * Sets the available background options in this fit analysis tab.
+ *
+ * @param backgrounds A list of the available backgrounds.
+ */
+void IndirectFitAnalysisTabLegacy::setBackgroundOptions(
+    const QStringList &backgrounds) {
+  m_fitPropertyBrowser->setBackgroundOptions(backgrounds);
+}
+
+/**
+ * @param settingKey  The key of the boolean setting whose value to retrieve.
+ * @return            The value of the boolean setting with the specified key.
+ */
+bool IndirectFitAnalysisTabLegacy::boolSettingValue(const QString &settingKey) const {
+  return m_fitPropertyBrowser->boolSettingValue(settingKey);
+}
+
+/**
+ * Sets the value of the custom boolean setting, with the specified key, to the
+ * specified value.
+ *
+ * @param settingKey  The key of the custom boolean setting.
+ * @param value       The value to set the boolean custom setting to.
+ */
+void IndirectFitAnalysisTabLegacy::setCustomBoolSetting(const QString &settingKey,
+                                                  bool value) {
+  m_fitPropertyBrowser->setCustomBoolSetting(settingKey, value);
+}
+
+/**
+ * @param settingKey  The key of the integer setting whose value to retrieve.
+ * @return            The value of the integer setting with the specified key.
+ */
+int IndirectFitAnalysisTabLegacy::intSettingValue(const QString &settingKey) const {
+  return m_fitPropertyBrowser->intSettingValue(settingKey);
+}
+
+/**
+ * @param settingKey  The key of the double setting whose value to retrieve.
+ * @return            The value of the double setting with the specified key.
+ */
+double
+IndirectFitAnalysisTabLegacy::doubleSettingValue(const QString &settingKey) const {
+  return m_fitPropertyBrowser->doubleSettingValue(settingKey);
+}
+
+/**
+ * @param settingKey  The key of the enum setting whose value to retrieve.
+ * @return            The value of the enum setting with the specified key.
+ */
+QString
+IndirectFitAnalysisTabLegacy::enumSettingValue(const QString &settingKey) const {
+  return m_fitPropertyBrowser->enumSettingValue(settingKey);
+}
+
+/**
+ * Adds a boolean custom setting, with the specified key and display name.
+ *
+ * @param settingKey    The key of the boolean setting to add.
+ * @param settingName   The display name of the boolean setting to add.
+ * @param defaultValue  The default value of the boolean setting.
+ */
+void IndirectFitAnalysisTabLegacy::addBoolCustomSetting(const QString &settingKey,
+                                                  const QString &settingName,
+                                                  bool defaultValue) {
+  m_fitPropertyBrowser->addBoolCustomSetting(settingKey, settingName,
+                                             defaultValue);
+}
+
+/**
+ * Adds a double custom setting, with the specified key and display name.
+ *
+ * @param settingKey    The key of the double setting to add.
+ * @param settingName   The display name of the double setting to add.
+ * @param defaultValue  The default value of the double setting.
+ */
+void IndirectFitAnalysisTabLegacy::addDoubleCustomSetting(const QString &settingKey,
+                                                    const QString &settingName,
+                                                    double defaultValue) {
+  m_fitPropertyBrowser->addDoubleCustomSetting(settingKey, settingName,
+                                               defaultValue);
+}
+
+/**
+ * Adds an integer custom setting, with the specified key and display name.
+ *
+ * @param settingKey    The key of the integer setting to add.
+ * @param settingName   The display name of the integer setting to add.
+ * @param defaultValue  The default value of the integer setting.
+ */
+void IndirectFitAnalysisTabLegacy::addIntCustomSetting(const QString &settingKey,
+                                                 const QString &settingName,
+                                                 int defaultValue) {
+  m_fitPropertyBrowser->addIntCustomSetting(settingKey, settingName,
+                                            defaultValue);
+}
+
+/**
+ * Adds an enum custom setting, with the specified key and display name.
+ *
+ * @param settingKey    The key of the enum setting to add.
+ * @param settingName   The display name of the enum setting to add.
+ * @param defaultValue  The default value of the enum setting.
+ */
+void IndirectFitAnalysisTabLegacy::addEnumCustomSetting(const QString &settingKey,
+                                                  const QString &settingName,
+                                                  const QStringList &options) {
+  m_fitPropertyBrowser->addEnumCustomSetting(settingKey, settingName, options);
+}
+
+/**
+ * Adds an optional double custom setting, with the specified key and display
+ * name.
+ *
+ * @param settingKey    The key of the optional double setting to add.
+ * @param settingName   The display name of the optional double setting to add.
+ * @param optionKey     The key of the setting specifying whether to use this
+ *                      this optional setting.
+ * @param optionName    The display name of the setting specifying whether to
+ *                      use this optional setting.
+ * @param defaultValue  The default value of the optional double setting.
+ */
+void IndirectFitAnalysisTabLegacy::addOptionalDoubleSetting(
+    const QString &settingKey, const QString &settingName,
+    const QString &optionKey, const QString &optionName, bool enabled,
+    double defaultValue) {
+  m_fitPropertyBrowser->addOptionalDoubleSetting(
+      settingKey, settingName, optionKey, optionName, enabled, defaultValue);
+}
+
+/**
+ * Sets whether a setting with a specified key affects the fitting function.
+ *
+ * @param settingKey      The key of the setting.
+ * @param changesFunction Boolean specifying whether the setting affects the
+ *                        fitting function.
+ */
+void IndirectFitAnalysisTabLegacy::setCustomSettingChangesFunction(
+    const QString &settingKey, bool changesFunction) {
+  m_fitPropertyBrowser->setCustomSettingChangesFunction(settingKey,
+                                                        changesFunction);
+}
+
+void IndirectFitAnalysisTabLegacy::updateFitOutput(bool error) {
+  disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+             SLOT(updateFitOutput(bool)));
+
+  if (error)
+    m_fittingModel->cleanFailedRun(m_fittingAlgorithm);
+  else
+    m_fittingModel->addOutput(m_fittingAlgorithm);
+}
+
+void IndirectFitAnalysisTabLegacy::updateSingleFitOutput(bool error) {
+  disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+             SLOT(updateSingleFitOutput(bool)));
+
+  if (error)
+    m_fittingModel->cleanFailedSingleRun(m_fittingAlgorithm, 0);
+  else
+    m_fittingModel->addSingleFitOutput(m_fittingAlgorithm, 0);
+}
+
+/**
+ * Performs necessary state changes when the fit algorithm was run
+ * and completed within this interface.
+ */
+void IndirectFitAnalysisTabLegacy::fitAlgorithmComplete(bool error) {
+  setRunIsRunning(false);
+  m_plotPresenter->setFitSingleSpectrumIsFitting(false);
+  enableFitButtons(true);
+  enableOutputOptions(!error);
+  updateParameterValues();
+  m_spectrumPresenter->enableView();
+  m_plotPresenter->updatePlots();
+
+  connect(m_fitPropertyBrowser,
+          SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
+          m_plotPresenter.get(), SLOT(updateGuess()));
+  disconnect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+             SLOT(fitAlgorithmComplete(bool)));
+}
+
+/**
+ * Updates the attribute values which are dependent on which spectrum is
+ * selected. They are updated in the function and in the FitPropertyBrowser.
+ */
+void IndirectFitAnalysisTabLegacy::updateAttributeValues() {
+  auto const attributeNames = m_fittingModel->getSpectrumDependentAttributes();
+  if (!attributeNames.empty()) {
+    for (auto i = 0; i < m_fitPropertyBrowser->count(); ++i) {
+      auto function = m_fitPropertyBrowser->getFunctionAtIndex(i);
+      updateAttributeValues(function, attributeNames);
+    }
+  }
+}
+
+/**
+ * Updates the attribute values in the function provided and in the fit property
+ * browser.
+ * @param function        The function containing the attributes
+ * @param attributeNames  The attributes to update
+ */
+void IndirectFitAnalysisTabLegacy::updateAttributeValues(
+    IFunction_sptr function, std::vector<std::string> const &attributeNames) {
+  auto const attributes = getAttributes(function, attributeNames);
+  if (!attributes.empty())
+    updateAttributeValues(function, attributeNames, attributes);
+}
+
+void IndirectFitAnalysisTabLegacy::updateAttributeValues(
+    IFunction_sptr fitFunction, std::vector<std::string> const &attributeNames,
+    std::unordered_map<std::string, IFunction::Attribute> const &attributes) {
+  try {
+    updateAttributes(fitFunction, attributeNames, attributes);
+    updateFitBrowserAttributeValues();
+  } catch (const std::runtime_error &) {
+    showMessageBox("An unexpected error occured:\n The setting of attribute "
+                   "values failed.");
+  }
+}
+
+/**
+ * Updates the attribute values in the the fit property browser.
+ */
+void IndirectFitAnalysisTabLegacy::updateFitBrowserAttributeValues() {
+  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
+  m_fitPropertyBrowser->updateAttributes();
+}
+
+/**
+ * Gets the new attribute values to be updated in the function and in the fit
+ * property browser.
+ * @param function        The function containing the attributes
+ * @param attributeNames  The names of the attributes to update
+ */
+std::unordered_map<std::string, IFunction::Attribute>
+IndirectFitAnalysisTabLegacy::getAttributes(
+    IFunction_sptr const &function,
+    std::vector<std::string> const &attributeNames) {
+  std::unordered_map<std::string, IFunction::Attribute> attributes;
+  for (auto const &name : attributeNames)
+    if (function->hasAttribute(name))
+      attributes[name] =
+          name == "WorkspaceIndex"
+              ? IFunction::Attribute(m_fitPropertyBrowser->workspaceIndex())
+              : function->getAttribute(name);
+  return attributes;
+}
+
+/**
+ * Updates the parameter values and errors in the fit property browser.
+ */
+void IndirectFitAnalysisTabLegacy::updateParameterValues() {
+  updateParameterValues(m_fittingModel->getParameterValues(
+      getSelectedDataIndex(), getSelectedSpectrum()));
+}
+
+/**
+ * Updates the parameter values and errors in the fit property browser.
+ *
+ * @param parameters  The parameter values to update the browser with.
+ */
+void IndirectFitAnalysisTabLegacy::updateParameterValues(
+    const std::unordered_map<std::string, ParameterValue> &parameters) {
+  try {
+    auto fitFunction = m_fitPropertyBrowser->getFittingFunction();
+    updateParameters(fitFunction, parameters);
+
+    updateFitBrowserParameterValues();
+
+    if (m_fittingModel->isPreviouslyFit(getSelectedDataIndex(),
+                                        getSelectedSpectrum()))
+      m_fitPropertyBrowser->updateErrors();
+    else
+      m_fitPropertyBrowser->clearErrors();
+  } catch (const std::out_of_range &) {
+  }
+}
+
+void IndirectFitAnalysisTabLegacy::updateFitBrowserParameterValues() {
+  MantidQt::API::SignalBlocker blocker(m_fitPropertyBrowser);
+  m_fitPropertyBrowser->updateParameters();
+}
+
+/**
+ * Enables Plot Guess in the FitPropertyBrowser if a sample workspace is loaded
+ */
+void IndirectFitAnalysisTabLegacy::updatePlotGuess() {
+  auto const sampleWorkspace =
+      m_fittingModel->getWorkspace(getSelectedDataIndex());
+  m_fitPropertyBrowser->updatePlotGuess(sampleWorkspace);
+}
+
+/**
+ * Plots the spectra corresponding to the selected parameters
+ */
+void IndirectFitAnalysisTabLegacy::plotSelectedSpectra() {
+  enableFitButtons(false);
+  plotSelectedSpectra(m_outOptionsPresenter->getSpectraToPlot());
+  enableFitButtons(true);
+  m_outOptionsPresenter->setPlotting(false);
+}
+
+/**
+ * Plots the spectra corresponding to the selected parameters
+ * @param spectra :: a vector of spectra to plot from a group workspace
+ */
+void IndirectFitAnalysisTabLegacy::plotSelectedSpectra(
+    std::vector<SpectrumToPlot> const &spectra) {
+  for (auto const &spectrum : spectra)
+    plotSpectrum(spectrum.first, spectrum.second);
+  m_outOptionsPresenter->clearSpectraToPlot();
+}
+
+/**
+ * Plots a spectrum with the specified index in a workspace
+ * @workspaceName :: the workspace containing the spectrum to plot
+ * @index :: the index in the workspace
+ * @errorBars :: true if you want error bars to be plotted
+ */
+void IndirectFitAnalysisTabLegacy::plotSpectrum(std::string const &workspaceName,
+                                          std::size_t const &index) {
+  m_plotter->plotSpectra(workspaceName, std::to_string(index));
+}
+
+/**
+ * Gets the name used for the base of the result workspaces
+ */
+std::string IndirectFitAnalysisTabLegacy::getOutputBasename() const {
+  return m_fittingModel->getOutputBasename();
+}
+
+/**
+ * Gets the Result workspace from a fit
+ */
+WorkspaceGroup_sptr IndirectFitAnalysisTabLegacy::getResultWorkspace() const {
+  return m_fittingModel->getResultWorkspace();
+}
+
+/**
+ * Gets the names of the Fit Parameters
+ */
+std::vector<std::string> IndirectFitAnalysisTabLegacy::getFitParameterNames() const {
+  return m_fittingModel->getFitParameterNames();
+}
+
+/**
+ * Executes the single fit algorithm defined in this indirect fit analysis tab.
+ */
+void IndirectFitAnalysisTabLegacy::singleFit() {
+  singleFit(getSelectedDataIndex(), getSelectedSpectrum());
+}
+
+void IndirectFitAnalysisTabLegacy::singleFit(std::size_t dataIndex,
+                                       std::size_t spectrum) {
+  if (validate()) {
+    m_plotPresenter->setFitSingleSpectrumIsFitting(true);
+    enableFitButtons(false);
+    enableOutputOptions(false);
+    runSingleFit(m_fittingModel->getSingleFit(dataIndex, spectrum));
+  }
+}
+
+/**
+ * Executes the sequential fit algorithm defined in this indirect fit analysis
+ * tab.
+ */
+void IndirectFitAnalysisTabLegacy::executeFit() {
+  if (validate()) {
+    setRunIsRunning(true);
+    enableFitButtons(false);
+    enableOutputOptions(false);
+    runFitAlgorithm(m_fittingModel->getFittingAlgorithm());
+  }
+}
+
+bool IndirectFitAnalysisTabLegacy::validate() {
+  UserInputValidator validator;
+  m_dataPresenter->validate(validator);
+  m_spectrumPresenter->validate(validator);
+
+  const auto invalidFunction = m_fittingModel->isInvalidFunction();
+  if (invalidFunction)
+    validator.addErrorMessage(QString::fromStdString(*invalidFunction));
+  if (m_fittingModel->numberOfWorkspaces() == 0)
+    validator.addErrorMessage(
+        QString::fromStdString("No data has been selected for a fit."));
+
+  const auto error = validator.generateErrorMessage();
+  emit showMessageBox(error);
+  return error.isEmpty();
+}
+
+/**
+ * Called when the 'Run' button is called in the IndirectTab.
+ */
+void IndirectFitAnalysisTabLegacy::run() {
+  setRunIsRunning(true);
+  enableFitButtons(false);
+  enableOutputOptions(false);
+  runFitAlgorithm(m_fittingModel->getFittingAlgorithm());
+}
+
+/**
+ * Enables or disables the 'Run', 'Fit Single Spectrum' and other related
+ * buttons
+ * @param enable :: true to enable buttons
+ */
+void IndirectFitAnalysisTabLegacy::enableFitButtons(bool enable) {
+  setRunEnabled(enable);
+  m_plotPresenter->setFitSingleSpectrumEnabled(enable);
+  m_fitPropertyBrowser->setFitEnabled(enable);
+}
+
+/**
+ * Enables or disables the output options. It also sets the current result and
+ * PDF workspaces to be plotted
+ * @param enable :: true to enable buttons
+ */
+void IndirectFitAnalysisTabLegacy::enableOutputOptions(bool enable) {
+  if (enable) {
+    m_outOptionsPresenter->setResultWorkspace(getResultWorkspace());
+    setPDFWorkspace(getOutputBasename() + "_PDFs");
+    m_outOptionsPresenter->setPlotTypes("Result Group");
+  } else
+    m_outOptionsPresenter->setMultiWorkspaceOptionsVisible(enable);
+
+  m_outOptionsPresenter->setPlotEnabled(
+      enable && m_outOptionsPresenter->isSelectedGroupPlottable());
+  m_outOptionsPresenter->setEditResultEnabled(enable);
+  m_outOptionsPresenter->setSaveEnabled(enable);
+}
+
+/**
+ * Sets the active PDF workspace within the output options if one exists for the
+ * current run
+ * @param workspaceName :: the name of the PDF workspace if it exists
+ */
+void IndirectFitAnalysisTabLegacy::setPDFWorkspace(std::string const &workspaceName) {
+  auto const fabMinimizer = m_fitPropertyBrowser->minimizer() == "FABADA";
+  auto const enablePDFOptions = doesExistInADS(workspaceName) && fabMinimizer;
+
+  if (enablePDFOptions) {
+    m_outOptionsPresenter->setPDFWorkspace(getADSGroupWorkspace(workspaceName));
+    m_outOptionsPresenter->setPlotWorkspaces();
+  } else
+    m_outOptionsPresenter->removePDFWorkspace();
+  m_outOptionsPresenter->setMultiWorkspaceOptionsVisible(enablePDFOptions);
+}
+
+/**
+ * Sets the visiblity of the output options Edit Result button
+ * @param visible :: true to make the edit result button visible
+ */
+void IndirectFitAnalysisTabLegacy::setEditResultVisible(bool visible) {
+  m_outOptionsPresenter->setEditResultVisible(visible);
+}
+
+void IndirectFitAnalysisTabLegacy::setAlgorithmProperties(
+    IAlgorithm_sptr fitAlgorithm) const {
+  fitAlgorithm->setProperty("Minimizer", m_fitPropertyBrowser->minimizer(true));
+  fitAlgorithm->setProperty("MaxIterations",
+                            m_fitPropertyBrowser->maxIterations());
+  fitAlgorithm->setProperty("ConvolveMembers",
+                            m_fitPropertyBrowser->convolveMembers());
+  fitAlgorithm->setProperty("PeakRadius",
+                            m_fitPropertyBrowser->getPeakRadius());
+  fitAlgorithm->setProperty("CostFunction",
+                            m_fitPropertyBrowser->costFunction());
+  fitAlgorithm->setProperty("IgnoreInvalidData",
+                            m_fitPropertyBrowser->ignoreInvalidData());
+
+  if (m_fitPropertyBrowser->isHistogramFit())
+    fitAlgorithm->setProperty("EvaluationType", "Histogram");
+}
+
+/*
+ * Runs the specified fit algorithm and calls the algorithmComplete
+ * method of this fit analysis tab once completed.
+ *
+ * @param fitAlgorithm      The fit algorithm to run.
+ */
+void IndirectFitAnalysisTabLegacy::runFitAlgorithm(IAlgorithm_sptr fitAlgorithm) {
+  connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+          SLOT(updateFitOutput(bool)));
+  setupFit(fitAlgorithm);
+  m_batchAlgoRunner->executeBatchAsync();
+}
+
+void IndirectFitAnalysisTabLegacy::runSingleFit(IAlgorithm_sptr fitAlgorithm) {
+  connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+          SLOT(updateSingleFitOutput(bool)));
+  setupFit(fitAlgorithm);
+  m_batchAlgoRunner->executeBatchAsync();
+}
+
+void IndirectFitAnalysisTabLegacy::setupFit(IAlgorithm_sptr fitAlgorithm) {
+  disconnect(m_fitPropertyBrowser,
+             SIGNAL(parameterChanged(const Mantid::API::IFunction *)),
+             m_plotPresenter.get(), SLOT(updateGuess()));
+
+  setAlgorithmProperties(fitAlgorithm);
+
+  m_fittingAlgorithm = fitAlgorithm;
+  m_spectrumPresenter->disableView();
+  m_batchAlgoRunner->addAlgorithm(fitAlgorithm);
+
+  connect(m_batchAlgoRunner, SIGNAL(batchComplete(bool)), this,
+          SLOT(fitAlgorithmComplete(bool)));
+}
+
+/**
+ * Updates whether the options for plotting and saving fit results are
+ * enabled/disabled.
+ */
+void IndirectFitAnalysisTabLegacy::updateResultOptions() {
+  const bool isFit = m_fittingModel->isPreviouslyFit(getSelectedDataIndex(),
+                                                     getSelectedSpectrum());
+  if (isFit)
+    m_outOptionsPresenter->setResultWorkspace(getResultWorkspace());
+  m_outOptionsPresenter->setPlotEnabled(isFit);
+  m_outOptionsPresenter->setEditResultEnabled(isFit);
+  m_outOptionsPresenter->setSaveEnabled(isFit);
+}
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.h b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.h
new file mode 100644
index 00000000000..0b87d719461
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectFitAnalysisTabLegacy.h
@@ -0,0 +1,243 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTIDQTCUSTOMINTERFACESIDA_IFATAB_H_
+#define MANTIDQTCUSTOMINTERFACESIDA_IFATAB_H_
+
+#include "IndirectDataAnalysisTabLegacy.h"
+#include "IndirectFitDataPresenterLegacy.h"
+#include "IndirectFitOutputOptionsPresenter.h"
+#include "IndirectFitOutputOptionsView.h"
+#include "IndirectFitPlotPresenterLegacy.h"
+#include "IndirectFittingModelLegacy.h"
+#include "IndirectSpectrumSelectionPresenterLegacy.h"
+#include "IndirectSpectrumSelectionViewLegacy.h"
+
+#include "MantidQtWidgets/Common/IndirectFitPropertyBrowserLegacy.h"
+
+#include <boost/optional.hpp>
+
+#include <QtCore>
+
+#include <memory>
+#include <type_traits>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+class DLLExport IndirectFitAnalysisTabLegacy : public IndirectDataAnalysisTabLegacy {
+  Q_OBJECT
+
+public:
+  IndirectFitAnalysisTabLegacy(IndirectFittingModelLegacy *model,
+                         QWidget *parent = nullptr);
+
+  void setFitDataPresenter(std::unique_ptr<IndirectFitDataPresenterLegacy> presenter);
+  void setPlotView(IIndirectFitPlotViewLegacy *view);
+  void setSpectrumSelectionView(IndirectSpectrumSelectionViewLegacy *view);
+  void setOutputOptionsView(IIndirectFitOutputOptionsView *view);
+  void
+  setFitPropertyBrowser(MantidWidgets::IndirectFitPropertyBrowserLegacy *browser);
+
+  virtual std::string tabName() const = 0;
+
+  virtual bool hasResolution() const = 0;
+
+  std::size_t getSelectedDataIndex() const;
+  std::size_t getSelectedSpectrum() const;
+  bool isRangeCurrentlySelected(std::size_t dataIndex,
+                                std::size_t spectrum) const;
+
+  QString selectedFitType() const;
+
+  size_t numberOfCustomFunctions(const std::string &functionName) const;
+
+  void setConvolveMembers(bool convolveMembers);
+
+  void updateTies();
+
+  void setCustomSettingEnabled(const QString &customName, bool enabled);
+
+  void setParameterValue(const std::string &functionName,
+                         const std::string &parameterName, double value);
+
+  void setDefaultPeakType(const std::string &function);
+
+  void addCheckBoxFunctionGroup(
+      const QString &groupName,
+      const std::vector<Mantid::API::IFunction_sptr> &functions,
+      bool defaultValue = false);
+
+  void addSpinnerFunctionGroup(
+      const QString &groupName,
+      const std::vector<Mantid::API::IFunction_sptr> &functions,
+      int minimum = 0, int maximum = 10, int defaultValue = 0);
+
+  void addComboBoxFunctionGroup(
+      const QString &groupName,
+      const std::vector<Mantid::API::IFunction_sptr> &functions);
+  void clearFitTypeComboBox();
+
+  void setBackgroundOptions(const QStringList &backgrounds);
+
+  bool boolSettingValue(const QString &settingKey) const;
+
+  void setCustomBoolSetting(const QString &settingKey, bool value);
+
+  int intSettingValue(const QString &settingKey) const;
+
+  double doubleSettingValue(const QString &settingKey) const;
+
+  QString enumSettingValue(const QString &settingKey) const;
+
+  void addBoolCustomSetting(const QString &settingKey,
+                            const QString &settingName,
+                            bool defaultValue = false);
+
+  void addDoubleCustomSetting(const QString &settingKey,
+                              const QString &settingName,
+                              double defaultValue = 0);
+
+  void addIntCustomSetting(const QString &settingKey,
+                           const QString &settingName, int defaultValue = 0);
+
+  void addEnumCustomSetting(const QString &settingKey,
+                            const QString &settingName,
+                            const QStringList &options);
+
+  void addOptionalDoubleSetting(const QString &settingKey,
+                                const QString &settingName,
+                                const QString &optionKey,
+                                const QString &optionName, bool enabled = false,
+                                double defaultValue = 0);
+
+  void setCustomSettingChangesFunction(const QString &settingKey,
+                                       bool changesFunction);
+
+public slots:
+  void setBrowserWorkspace() override;
+
+protected:
+  IndirectFittingModelLegacy *fittingModel() const;
+
+  void run() override;
+
+  void setSampleWSSuffixes(const QStringList &suffices);
+  void setSampleFBSuffixes(const QStringList &suffices);
+  void setResolutionWSSuffixes(const QStringList &suffices);
+  void setResolutionFBSuffixes(const QStringList &suffices);
+
+  void setAlgorithmProperties(Mantid::API::IAlgorithm_sptr fitAlgorithm) const;
+  void runFitAlgorithm(Mantid::API::IAlgorithm_sptr fitAlgorithm);
+  void runSingleFit(Mantid::API::IAlgorithm_sptr fitAlgorithm);
+  virtual void setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm);
+
+  virtual void setRunIsRunning(bool running) = 0;
+  virtual void setRunEnabled(bool enable) = 0;
+  void setEditResultVisible(bool visible);
+
+signals:
+  void functionChanged();
+  void parameterChanged(const Mantid::API::IFunction * /*_t1*/);
+  void customBoolChanged(const QString &key, bool value);
+  void updateAvailableFitTypes();
+
+protected slots:
+
+  void setModelFitFunction();
+  void setModelStartX(double startX);
+  void setModelEndX(double startX);
+  void setDataTableStartX(double startX);
+  void setDataTableEndX(double endX);
+  void setDataTableExclude(const std::string &exclude);
+  void setBrowserStartX(double startX);
+  void setBrowserEndX(double endX);
+  void updateBrowserFittingRange();
+  void setBrowserWorkspace(std::size_t dataIndex);
+  void setBrowserWorkspaceIndex(std::size_t spectrum);
+  void setBrowserWorkspaceIndex(int spectrum);
+  void tableStartXChanged(double startX, std::size_t dataIndex,
+                          std::size_t spectrum);
+  void tableEndXChanged(double endX, std::size_t dataIndex,
+                        std::size_t spectrum);
+  void tableExcludeChanged(const std::string &exclude, std::size_t dataIndex,
+                           std::size_t spectrum);
+
+  void updateFitOutput(bool error);
+  void updateSingleFitOutput(bool error);
+  void fitAlgorithmComplete(bool error);
+
+  void singleFit();
+  void singleFit(std::size_t dataIndex, std::size_t spectrum);
+  void executeFit();
+
+  void updateAttributeValues();
+  void updateAttributeValues(Mantid::API::IFunction_sptr function,
+                             std::vector<std::string> const &attributeNames);
+  void updateAttributeValues(
+      Mantid::API::IFunction_sptr function,
+      std::vector<std::string> const &attributeNames,
+      std::unordered_map<std::string, Mantid::API::IFunction::Attribute> const
+          &attributes);
+  void updateFitBrowserAttributeValues();
+  std::unordered_map<std::string, Mantid::API::IFunction::Attribute>
+  getAttributes(Mantid::API::IFunction_sptr const &function,
+                std::vector<std::string> const &attributeNames);
+  void updateParameterValues();
+  void updateParameterValues(
+      const std::unordered_map<std::string, ParameterValue> &parameters);
+  void updateFitBrowserParameterValues();
+
+  void updateResultOptions();
+
+private slots:
+  void updatePlotGuess();
+  void plotSelectedSpectra();
+
+private:
+  /// Overidden by child class.
+  void setup() override;
+  void loadSettings(const QSettings &settings) override;
+  virtual void setupFitTab() = 0;
+  bool validate() override;
+
+  void setFileExtensionsByName(bool filter) override;
+  void setSampleSuffixes(std::string const &tab, bool filter);
+  void setResolutionSuffixes(std::string const &tab, bool filter);
+
+  void connectDataAndPlotPresenters();
+  void connectSpectrumAndPlotPresenters();
+  void connectFitBrowserAndPlotPresenter();
+  void connectDataAndSpectrumPresenters();
+  void connectDataAndFitBrowserPresenters();
+
+  void plotSelectedSpectra(std::vector<SpectrumToPlot> const &spectra);
+  void plotSpectrum(std::string const &workspaceName, std::size_t const &index);
+
+  std::string getOutputBasename() const;
+  Mantid::API::WorkspaceGroup_sptr getResultWorkspace() const;
+  std::vector<std::string> getFitParameterNames() const;
+
+  void enableFitButtons(bool enable);
+  void enableOutputOptions(bool enable);
+  void setPDFWorkspace(std::string const &workspaceName);
+
+  std::unique_ptr<IndirectFittingModelLegacy> m_fittingModel;
+  MantidWidgets::IndirectFitPropertyBrowserLegacy *m_fitPropertyBrowser;
+  std::unique_ptr<IndirectFitDataPresenterLegacy> m_dataPresenter;
+  std::unique_ptr<IndirectFitPlotPresenterLegacy> m_plotPresenter;
+  std::unique_ptr<IndirectSpectrumSelectionPresenterLegacy> m_spectrumPresenter;
+  std::unique_ptr<IndirectFitOutputOptionsPresenter> m_outOptionsPresenter;
+
+  Mantid::API::IAlgorithm_sptr m_fittingAlgorithm;
+};
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
+
+#endif /* MANTIDQTCUSTOMINTERFACESIDA_IFATAB_H_ */
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.cpp b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.cpp
index 027df0e20f3..40abda2fcb8 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.cpp
@@ -20,16 +20,15 @@ namespace {
 using namespace MantidQt::CustomInterfaces::IDA;
 using namespace Mantid::Kernel::Strings;
 
-struct SetViewSpectra : boost::static_visitor<> {
+struct SetViewSpectra {
   explicit SetViewSpectra(IndirectSpectrumSelectionView *view) : m_view(view) {}
 
-  void operator()(const std::pair<std::size_t, std::size_t> &spectra) const {
-    m_view->displaySpectra(static_cast<int>(spectra.first),
-                           static_cast<int>(spectra.second));
-  }
-
-  void operator()(const DiscontinuousSpectra<std::size_t> &spectra) const {
-    m_view->displaySpectra(spectra.getString());
+  void operator()(const Spectra &spectra) const {
+    if (spectra.isContinuous()) {
+      m_view->displaySpectra(spectra.getMinMax());
+    } else {
+      m_view->displaySpectra(spectra.getString());
+    }
   }
 
 private:
@@ -117,22 +116,22 @@ namespace CustomInterfaces {
 namespace IDA {
 
 IndirectSpectrumSelectionPresenter::IndirectSpectrumSelectionPresenter(
-    IndirectFittingModelLegacy *model, IndirectSpectrumSelectionView *view)
-    : QObject(nullptr), m_model(model), m_view(view), m_activeIndex(0),
-      m_maskIndex(0) {
+    IndirectFittingModel *model, IndirectSpectrumSelectionView *view)
+    : QObject(nullptr), m_model(model),
+      m_view(view), m_activeIndex{0}, m_maskIndex{0} {
   connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
           this, SLOT(updateSpectraList(const std::string &)));
   connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
           this, SLOT(setMaskSpectraList(const std::string &)));
   connect(m_view.get(),
-          SIGNAL(selectedSpectraChanged(std::size_t, std::size_t)), this,
-          SLOT(updateSpectraRange(std::size_t, std::size_t)));
+          SIGNAL(selectedSpectraChanged(WorkspaceIndex, WorkspaceIndex)), this,
+          SLOT(updateSpectraRange(WorkspaceIndex, WorkspaceIndex)));
   connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
           this, SLOT(displaySpectraList(const std::string &)));
 
-  connect(m_view.get(), SIGNAL(maskSpectrumChanged(int)), this,
-          SLOT(setMaskIndex(int)));
-  connect(m_view.get(), SIGNAL(maskSpectrumChanged(int)), this,
+  connect(m_view.get(), SIGNAL(maskSpectrumChanged(WorkspaceIndex)), this,
+          SLOT(setMaskIndex(WorkspaceIndex)));
+  connect(m_view.get(), SIGNAL(maskSpectrumChanged(WorkspaceIndex)), this,
           SLOT(displayBinMask()));
   connect(m_view.get(), SIGNAL(maskChanged(const std::string &)), this,
           SLOT(setBinMask(const std::string &)));
@@ -140,6 +139,8 @@ IndirectSpectrumSelectionPresenter::IndirectSpectrumSelectionPresenter(
           SLOT(displayBinMask()));
   connect(m_view.get(), SIGNAL(maskChanged(const std::string &)), this,
           SIGNAL(maskChanged(const std::string &)));
+  connect(m_view.get(), SIGNAL(spectraSelectionWidgetChanged(int)), this,
+          SLOT(initSpectraSelectionWidget(int)));
 
   m_view->setSpectraRegex(Regexes::SPECTRA_LIST);
   m_view->setMaskBinsRegex(Regexes::MASK_LIST);
@@ -157,16 +158,25 @@ void IndirectSpectrumSelectionPresenter::enableView() {
   m_view->setEnabled(true);
 }
 
+void IndirectSpectrumSelectionPresenter::initSpectraSelectionWidget(int index) {
+  auto spectra = m_model->getSpectra(m_activeIndex);
+  if (index == 0) {
+    m_view->displaySpectra(spectra.getMinMax());
+  } else {
+    m_view->displaySpectra(spectra.getString());
+  }
+}
+
 void IndirectSpectrumSelectionPresenter::setActiveIndexToZero() {
-  setActiveModelIndex(0);
+  setActiveModelIndex(DatasetIndex{0});
 }
 
 void IndirectSpectrumSelectionPresenter::updateSpectra() {
   const auto ws = m_model->getWorkspace(m_activeIndex);
   if (ws) {
-    setSpectraRange(0, ws->getNumberHistograms() - 1);
-    const auto activeSpectra = m_model->getSpectra(m_activeIndex);
-    boost::apply_visitor(SetViewSpectra(m_view.get()), activeSpectra);
+    const auto spectra = m_model->getSpectra(m_activeIndex);
+    setSpectraRange(spectra.front(), spectra.back());
+    SetViewSpectra(m_view.get())(spectra);
     enableView();
   } else {
     m_view->clear();
@@ -175,16 +185,14 @@ void IndirectSpectrumSelectionPresenter::updateSpectra() {
 }
 
 void IndirectSpectrumSelectionPresenter::setActiveModelIndex(
-    std::size_t index) {
+    DatasetIndex index) {
   m_activeIndex = index;
   updateSpectra();
 }
 
-void IndirectSpectrumSelectionPresenter::setSpectraRange(std::size_t minimum,
-                                                         std::size_t maximum) {
-  int minimumInt = boost::numeric_cast<int>(minimum);
-  int maximumInt = boost::numeric_cast<int>(maximum);
-  m_view->setSpectraRange(minimumInt, maximumInt);
+void IndirectSpectrumSelectionPresenter::setSpectraRange(
+    WorkspaceIndex minimum, WorkspaceIndex maximum) {
+  m_view->setSpectraRange(minimum, maximum);
 }
 
 void IndirectSpectrumSelectionPresenter::setModelSpectra(
@@ -203,22 +211,25 @@ void IndirectSpectrumSelectionPresenter::setModelSpectra(
 
 void IndirectSpectrumSelectionPresenter::updateSpectraList(
     std::string const &spectraList) {
-  setModelSpectra(
-      DiscontinuousSpectra<std::size_t>(createSpectraString(spectraList)));
+  setModelSpectra(Spectra(createSpectraString(spectraList)));
   emit spectraChanged(m_activeIndex);
 }
 
 void IndirectSpectrumSelectionPresenter::updateSpectraRange(
-    std::size_t minimum, std::size_t maximum) {
-  setModelSpectra(std::make_pair(minimum, maximum));
+    WorkspaceIndex minimum, WorkspaceIndex maximum) {
+  setModelSpectra(Spectra(minimum, maximum));
   emit spectraChanged(m_activeIndex);
 }
 
 void IndirectSpectrumSelectionPresenter::setMaskSpectraList(
     std::string const &spectra) {
-  if (m_spectraError.empty())
-    m_view->setMaskSpectraList(vectorFromString<std::size_t>(spectra));
-  else
+  if (m_spectraError.empty()) {
+    auto const intVec = vectorFromString<int>(spectra);
+    std::vector<WorkspaceIndex> vec(intVec.size());
+    std::transform(intVec.begin(), intVec.end(), vec.begin(),
+                   [](int i) { return WorkspaceIndex{i}; });
+    m_view->setMaskSpectraList(vec);
+  } else
     m_view->setMaskSpectraList({});
 }
 
@@ -240,9 +251,9 @@ void IndirectSpectrumSelectionPresenter::setBinMask(
   }
 }
 
-void IndirectSpectrumSelectionPresenter::setMaskIndex(int index) {
-  if (index >= 0)
-    m_maskIndex = boost::numeric_cast<std::size_t>(index);
+void IndirectSpectrumSelectionPresenter::setMaskIndex(WorkspaceIndex index) {
+  if (index.value >= 0)
+    m_maskIndex = index;
 }
 
 void IndirectSpectrumSelectionPresenter::displayBinMask() {
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.h b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.h
index 01335c09592..f29c063f9fb 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.h
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenter.h
@@ -7,7 +7,7 @@
 #ifndef MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONPRESENTER_H_
 #define MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONPRESENTER_H_
 
-#include "IndirectFittingModelLegacy.h"
+#include "IndirectFittingModel.h"
 #include "IndirectSpectrumSelectionView.h"
 
 #include "DllConfig.h"
@@ -27,19 +27,19 @@ class MANTIDQT_INDIRECT_DLL IndirectSpectrumSelectionPresenter
     : public QObject {
   Q_OBJECT
 public:
-  IndirectSpectrumSelectionPresenter(IndirectFittingModelLegacy *model,
+  IndirectSpectrumSelectionPresenter(IndirectFittingModel *model,
                                      IndirectSpectrumSelectionView *view);
   ~IndirectSpectrumSelectionPresenter() override;
   UserInputValidator &validate(UserInputValidator &validator);
 
 signals:
-  void spectraChanged(std::size_t /*_t1*/);
+  void spectraChanged(DatasetIndex /*_t1*/);
   void maskChanged(std::string const & /*_t1*/);
   void invalidSpectraString(QString const &errorMessage);
   void invalidMaskBinsString(QString const &errorMessage);
 
 public slots:
-  void setActiveModelIndex(std::size_t index);
+  void setActiveModelIndex(DatasetIndex index);
   void setActiveIndexToZero();
   void updateSpectra();
   void displayBinMask();
@@ -50,22 +50,23 @@ private slots:
   void setBinMask(std::string const &maskString);
   void setMaskSpectraList(std::string const &spectraList);
   void updateSpectraList(std::string const &spectraList);
-  void updateSpectraRange(std::size_t minimum, std::size_t maximum);
+  void updateSpectraRange(WorkspaceIndex minimum, WorkspaceIndex maximum);
   void displaySpectraList(std::string const &spectra);
-  void setMaskIndex(int index);
+  void setMaskIndex(WorkspaceIndex index);
+  void initSpectraSelectionWidget(int index);
 
 private:
-  void setSpectraRange(std::size_t minimum, std::size_t maximum);
+  void setSpectraRange(WorkspaceIndex minimum, WorkspaceIndex maximum);
   void setModelSpectra(Spectra const &spectra);
 
   UserInputValidator validateSpectraString();
   UserInputValidator &validateSpectraString(UserInputValidator &validator);
   UserInputValidator validateMaskBinsString();
 
-  IndirectFittingModelLegacy *m_model;
+  IndirectFittingModel *m_model;
   std::unique_ptr<IndirectSpectrumSelectionView> m_view;
-  std::size_t m_activeIndex;
-  std::size_t m_maskIndex;
+  DatasetIndex m_activeIndex;
+  WorkspaceIndex m_maskIndex;
   std::string m_spectraError;
 };
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.cpp b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.cpp
new file mode 100644
index 00000000000..148409e45f0
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.cpp
@@ -0,0 +1,280 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "IndirectSpectrumSelectionPresenterLegacy.h"
+
+#include "MantidKernel/ArrayProperty.h"
+#include "MantidKernel/Strings.h"
+#include "MantidQtWidgets/Common/SignalBlocker.h"
+
+#include <algorithm>
+#include <iterator>
+#include <sstream>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace {
+using namespace MantidQt::CustomInterfaces::IDA;
+using namespace Mantid::Kernel::Strings;
+
+struct SetViewSpectra : boost::static_visitor<> {
+  explicit SetViewSpectra(IndirectSpectrumSelectionViewLegacy *view) : m_view(view) {}
+
+  void operator()(const std::pair<std::size_t, std::size_t> &spectra) const {
+    m_view->displaySpectra(static_cast<int>(spectra.first),
+                           static_cast<int>(spectra.second));
+  }
+
+  void operator()(const DiscontinuousSpectra<std::size_t> &spectra) const {
+    m_view->displaySpectra(spectra.getString());
+  }
+
+private:
+  IndirectSpectrumSelectionViewLegacy *m_view;
+};
+
+std::string OR(const std::string &lhs, const std::string &rhs) {
+  return "(" + lhs + "|" + rhs + ")";
+}
+
+std::string NATURAL_NUMBER(std::size_t digits) {
+  return OR("0", "[1-9][0-9]{," + std::to_string(digits - 1) + "}");
+}
+
+std::string constructSpectraString(std::vector<int> const &spectras) {
+  return joinCompress(spectras.begin(), spectras.end());
+}
+
+std::vector<std::string> splitStringBy(std::string const &str,
+                                       std::string const &delimiter) {
+  std::vector<std::string> subStrings;
+  boost::split(subStrings, str, boost::is_any_of(delimiter));
+  subStrings.erase(std::remove_if(subStrings.begin(), subStrings.end(),
+                                  [](std::string const &subString) {
+                                    return subString.empty();
+                                  }),
+                   subStrings.end());
+  return subStrings;
+}
+
+std::string getSpectraRange(std::string const &string) {
+  auto const bounds = splitStringBy(string, "-");
+  return std::stoull(bounds[0]) > std::stoull(bounds[1])
+             ? bounds[1] + "-" + bounds[0]
+             : string;
+}
+
+std::string rearrangeSpectraSubString(std::string const &string) {
+  return string.find("-") != std::string::npos ? getSpectraRange(string)
+                                               : string;
+}
+
+// Swaps the two numbers in a spectra range if they go from large to small
+std::string rearrangeSpectraRangeStrings(std::string const &string) {
+  std::string spectraString;
+  std::vector<std::string> subStrings = splitStringBy(string, ",");
+  for (auto it = subStrings.begin(); it < subStrings.end(); ++it) {
+    spectraString += rearrangeSpectraSubString(*it);
+    spectraString += it != subStrings.end() ? "," : "";
+  }
+  return spectraString;
+}
+
+std::string createSpectraString(std::string string) {
+  string.erase(std::remove_if(string.begin(), string.end(), isspace),
+               string.end());
+  std::vector<int> spectras = parseRange(rearrangeSpectraRangeStrings(string));
+  std::sort(spectras.begin(), spectras.end());
+  // Remove duplicate entries
+  spectras.erase(std::unique(spectras.begin(), spectras.end()), spectras.end());
+  return constructSpectraString(spectras);
+}
+
+namespace Regexes {
+const std::string EMPTY = "^$";
+const std::string SPACE = "[ ]*";
+const std::string COMMA = SPACE + "," + SPACE;
+const std::string MINUS = "\\-";
+
+const std::string NUMBER = NATURAL_NUMBER(4);
+const std::string NATURAL_RANGE = "(" + NUMBER + MINUS + NUMBER + ")";
+const std::string NATURAL_OR_RANGE = OR(NATURAL_RANGE, NUMBER);
+const std::string SPECTRA_LIST =
+    "(" + NATURAL_OR_RANGE + "(" + COMMA + NATURAL_OR_RANGE + ")*)";
+
+const std::string REAL_NUMBER = "(-?" + NUMBER + "(\\.[0-9]*)?)";
+const std::string REAL_RANGE = "(" + REAL_NUMBER + COMMA + REAL_NUMBER + ")";
+const std::string MASK_LIST =
+    "(" + REAL_RANGE + "(" + COMMA + REAL_RANGE + ")*" + ")|" + EMPTY;
+} // namespace Regexes
+} // namespace
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+IndirectSpectrumSelectionPresenterLegacy::IndirectSpectrumSelectionPresenterLegacy(
+    IndirectFittingModelLegacy *model, IndirectSpectrumSelectionViewLegacy *view)
+    : QObject(nullptr), m_model(model), m_view(view), m_activeIndex(0),
+      m_maskIndex(0) {
+  connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
+          this, SLOT(updateSpectraList(const std::string &)));
+  connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
+          this, SLOT(setMaskSpectraList(const std::string &)));
+  connect(m_view.get(),
+          SIGNAL(selectedSpectraChanged(std::size_t, std::size_t)), this,
+          SLOT(updateSpectraRange(std::size_t, std::size_t)));
+  connect(m_view.get(), SIGNAL(selectedSpectraChanged(const std::string &)),
+          this, SLOT(displaySpectraList(const std::string &)));
+
+  connect(m_view.get(), SIGNAL(maskSpectrumChanged(int)), this,
+          SLOT(setMaskIndex(int)));
+  connect(m_view.get(), SIGNAL(maskSpectrumChanged(int)), this,
+          SLOT(displayBinMask()));
+  connect(m_view.get(), SIGNAL(maskChanged(const std::string &)), this,
+          SLOT(setBinMask(const std::string &)));
+  connect(m_view.get(), SIGNAL(maskChanged(const std::string &)), this,
+          SLOT(displayBinMask()));
+  connect(m_view.get(), SIGNAL(maskChanged(const std::string &)), this,
+          SIGNAL(maskChanged(const std::string &)));
+
+  m_view->setSpectraRegex(Regexes::SPECTRA_LIST);
+  m_view->setMaskBinsRegex(Regexes::MASK_LIST);
+  m_view->setEnabled(false);
+}
+
+IndirectSpectrumSelectionPresenterLegacy::~IndirectSpectrumSelectionPresenterLegacy() {}
+
+void IndirectSpectrumSelectionPresenterLegacy::disableView() {
+  MantidQt::API::SignalBlocker blocker(m_view.get());
+  m_view->setDisabled(true);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::enableView() {
+  m_view->setEnabled(true);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setActiveIndexToZero() {
+  setActiveModelIndex(0);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::updateSpectra() {
+  const auto ws = m_model->getWorkspace(m_activeIndex);
+  if (ws) {
+    setSpectraRange(0, ws->getNumberHistograms() - 1);
+    const auto activeSpectra = m_model->getSpectra(m_activeIndex);
+    boost::apply_visitor(SetViewSpectra(m_view.get()), activeSpectra);
+    enableView();
+  } else {
+    m_view->clear();
+    disableView();
+  }
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setActiveModelIndex(
+    std::size_t index) {
+  m_activeIndex = index;
+  updateSpectra();
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setSpectraRange(std::size_t minimum,
+                                                         std::size_t maximum) {
+  int minimumInt = boost::numeric_cast<int>(minimum);
+  int maximumInt = boost::numeric_cast<int>(maximum);
+  m_view->setSpectraRange(minimumInt, maximumInt);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setModelSpectra(
+    Spectra const &spectra) {
+  try {
+    m_model->setSpectra(spectra, m_activeIndex);
+    m_spectraError.clear();
+    m_view->hideSpectraErrorLabel();
+    m_view->setMaskSelectionEnabled(true);
+  } catch (const std::runtime_error &ex) {
+    m_spectraError = ex.what();
+    m_view->showSpectraErrorLabel();
+    m_view->setMaskSelectionEnabled(false);
+  }
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::updateSpectraList(
+    std::string const &spectraList) {
+  setModelSpectra(
+      DiscontinuousSpectra<std::size_t>(createSpectraString(spectraList)));
+  emit spectraChanged(m_activeIndex);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::updateSpectraRange(
+    std::size_t minimum, std::size_t maximum) {
+  setModelSpectra(std::make_pair(minimum, maximum));
+  emit spectraChanged(m_activeIndex);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setMaskSpectraList(
+    std::string const &spectra) {
+  if (m_spectraError.empty())
+    m_view->setMaskSpectraList(vectorFromString<std::size_t>(spectra));
+  else
+    m_view->setMaskSpectraList({});
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::displaySpectraList(
+    std::string const &spectra) {
+  m_view->displaySpectra(createSpectraString(spectra));
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setBinMask(
+    std::string const &maskString) {
+  auto validator = validateMaskBinsString();
+
+  if (validator.isAllInputValid()) {
+    m_model->setExcludeRegion(maskString, m_activeIndex, m_maskIndex);
+    m_view->hideMaskBinErrorLabel();
+  } else {
+    m_view->showMaskBinErrorLabel();
+    emit invalidMaskBinsString(validator.generateErrorMessage());
+  }
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::setMaskIndex(int index) {
+  if (index >= 0)
+    m_maskIndex = boost::numeric_cast<std::size_t>(index);
+}
+
+void IndirectSpectrumSelectionPresenterLegacy::displayBinMask() {
+  m_view->setMaskString(m_model->getExcludeRegion(m_activeIndex, m_maskIndex));
+}
+
+UserInputValidator &
+IndirectSpectrumSelectionPresenterLegacy::validate(UserInputValidator &validator) {
+  validator = validateSpectraString(validator);
+  return m_view->validateMaskBinsString(validator);
+}
+
+UserInputValidator IndirectSpectrumSelectionPresenterLegacy::validateSpectraString() {
+  UserInputValidator validator;
+  return validateSpectraString(validator);
+}
+
+UserInputValidator &IndirectSpectrumSelectionPresenterLegacy::validateSpectraString(
+    UserInputValidator &validator) {
+  validator = m_view->validateSpectraString(validator);
+
+  if (!m_spectraError.empty())
+    validator.addErrorMessage(QString::fromStdString(m_spectraError));
+  return validator;
+}
+
+UserInputValidator
+IndirectSpectrumSelectionPresenterLegacy::validateMaskBinsString() {
+  UserInputValidator uiv;
+  return m_view->validateMaskBinsString(uiv);
+}
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.h b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.h
new file mode 100644
index 00000000000..3e43cd9dfdd
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionPresenterLegacy.h
@@ -0,0 +1,76 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONPRESENTER_H_
+#define MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONPRESENTER_H_
+
+#include "IndirectFittingModelLegacy.h"
+#include "IndirectSpectrumSelectionViewLegacy.h"
+
+#include "DllConfig.h"
+#include "MantidQtWidgets/Common/UserInputValidator.h"
+
+#include <boost/optional.hpp>
+#include <boost/variant.hpp>
+
+#include <unordered_map>
+#include <vector>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+class MANTIDQT_INDIRECT_DLL IndirectSpectrumSelectionPresenterLegacy
+    : public QObject {
+  Q_OBJECT
+public:
+  IndirectSpectrumSelectionPresenterLegacy(IndirectFittingModelLegacy *model,
+                                     IndirectSpectrumSelectionViewLegacy *view);
+  ~IndirectSpectrumSelectionPresenterLegacy() override;
+  UserInputValidator &validate(UserInputValidator &validator);
+
+signals:
+  void spectraChanged(std::size_t /*_t1*/);
+  void maskChanged(std::string const & /*_t1*/);
+  void invalidSpectraString(QString const &errorMessage);
+  void invalidMaskBinsString(QString const &errorMessage);
+
+public slots:
+  void setActiveModelIndex(std::size_t index);
+  void setActiveIndexToZero();
+  void updateSpectra();
+  void displayBinMask();
+  void disableView();
+  void enableView();
+
+private slots:
+  void setBinMask(std::string const &maskString);
+  void setMaskSpectraList(std::string const &spectraList);
+  void updateSpectraList(std::string const &spectraList);
+  void updateSpectraRange(std::size_t minimum, std::size_t maximum);
+  void displaySpectraList(std::string const &spectra);
+  void setMaskIndex(int index);
+
+private:
+  void setSpectraRange(std::size_t minimum, std::size_t maximum);
+  void setModelSpectra(Spectra const &spectra);
+
+  UserInputValidator validateSpectraString();
+  UserInputValidator &validateSpectraString(UserInputValidator &validator);
+  UserInputValidator validateMaskBinsString();
+
+  IndirectFittingModelLegacy *m_model;
+  std::unique_ptr<IndirectSpectrumSelectionViewLegacy> m_view;
+  std::size_t m_activeIndex;
+  std::size_t m_maskIndex;
+  std::string m_spectraError;
+};
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
+
+#endif
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.cpp b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.cpp
index 5ca85d608d5..0bc300ebe40 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.cpp
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.cpp
@@ -36,7 +36,7 @@ IndirectSpectrumSelectionView::IndirectSpectrumSelectionView(QWidget *parent)
           SLOT(emitSpectraStringChanged()));
 
   connect(m_selector->spMaskSpectrum, SIGNAL(valueChanged(int)), this,
-          SIGNAL(maskSpectrumChanged(int)));
+          SLOT(emitMaskSpectrumChanged(int)));
   connect(m_selector->cbMaskSpectrum,
           SIGNAL(currentIndexChanged(const QString &)), this,
           SLOT(emitMaskSpectrumChanged(const QString &)));
@@ -47,6 +47,9 @@ IndirectSpectrumSelectionView::IndirectSpectrumSelectionView(QWidget *parent)
           SLOT(emitSpectraChanged(int)));
   connect(m_selector->cbSelectionMode, SIGNAL(currentIndexChanged(int)), this,
           SLOT(clearMaskString()));
+
+  connect(m_selector->swSpectraSelection, SIGNAL(currentChanged(int)), this,
+          SIGNAL(spectraSelectionWidgetChanged(int)));
 }
 
 IndirectSpectrumSelectionView::~IndirectSpectrumSelectionView() {}
@@ -56,14 +59,12 @@ SpectrumSelectionMode IndirectSpectrumSelectionView::selectionMode() const {
       m_selector->swSpectraSelection->currentIndex());
 }
 
-std::size_t IndirectSpectrumSelectionView::minimumSpectrum() const {
-  return boost::numeric_cast<std::size_t>(
-      m_selector->spMinimumSpectrum->value());
+WorkspaceIndex IndirectSpectrumSelectionView::minimumSpectrum() const {
+  return WorkspaceIndex{m_selector->spMinimumSpectrum->value()};
 }
 
-std::size_t IndirectSpectrumSelectionView::maximumSpectrum() const {
-  return boost::numeric_cast<std::size_t>(
-      m_selector->spMaximumSpectrum->value());
+WorkspaceIndex IndirectSpectrumSelectionView::maximumSpectrum() const {
+  return WorkspaceIndex{m_selector->spMaximumSpectrum->value()};
 }
 
 std::string IndirectSpectrumSelectionView::spectraString() const {
@@ -81,35 +82,39 @@ void IndirectSpectrumSelectionView::displaySpectra(
       static_cast<int>(SpectrumSelectionMode::STRING));
 }
 
-void IndirectSpectrumSelectionView::displaySpectra(int minimum, int maximum) {
-  setMinimumSpectrum(minimum);
-  setMaximumSpectrum(maximum);
+void IndirectSpectrumSelectionView::displaySpectra(
+    std::pair<WorkspaceIndex, WorkspaceIndex> minmax) {
+  setMinimumSpectrum(minmax.first);
+  setMaximumSpectrum(minmax.second);
   m_selector->cbSelectionMode->setCurrentIndex(
       static_cast<int>(SpectrumSelectionMode::RANGE));
 }
 
-void IndirectSpectrumSelectionView::setSpectraRange(int minimum, int maximum) {
+void IndirectSpectrumSelectionView::setSpectraRange(WorkspaceIndex minimum,
+                                                    WorkspaceIndex maximum) {
   setSpectraRangeMinimum(minimum);
   setSpectraRangeMaximum(maximum);
 }
 
-void IndirectSpectrumSelectionView::setSpectraRangeMinimum(int minimum) {
+void IndirectSpectrumSelectionView::setSpectraRangeMinimum(
+    WorkspaceIndex minimum) {
   MantidQt::API::SignalBlocker blocker(m_selector->spMinimumSpectrum);
-  m_selector->spMinimumSpectrum->setMinimum(minimum);
-  setSpectraRangeMiniMax(minimum);
+  m_selector->spMinimumSpectrum->setMinimum(minimum.value);
+  setSpectraRangeMiniMax(minimum.value);
 }
 
-void IndirectSpectrumSelectionView::setSpectraRangeMaximum(int maximum) {
+void IndirectSpectrumSelectionView::setSpectraRangeMaximum(
+    WorkspaceIndex maximum) {
   MantidQt::API::SignalBlocker blocker(m_selector->spMaximumSpectrum);
-  m_selector->spMaximumSpectrum->setMaximum(maximum);
-  setSpectraRangeMaxiMin(maximum);
+  m_selector->spMaximumSpectrum->setMaximum(maximum.value);
+  setSpectraRangeMaxiMin(maximum.value);
 }
 
 void IndirectSpectrumSelectionView::setMaskSpectraList(
-    const std::vector<std::size_t> &spectra) {
+    const std::vector<WorkspaceIndex> &spectra) {
   m_selector->cbMaskSpectrum->clear();
   for (const auto &spectrum : spectra)
-    m_selector->cbMaskSpectrum->addItem(QString::number(spectrum));
+    m_selector->cbMaskSpectrum->addItem(QString::number(spectrum.value));
 }
 
 void IndirectSpectrumSelectionView::setMaskSelectionEnabled(bool enabled) {
@@ -122,7 +127,7 @@ void IndirectSpectrumSelectionView::clear() {
   m_selector->leSpectra->clear();
   m_selector->leMaskBins->clear();
   m_selector->cbMaskSpectrum->clear();
-  setSpectraRange(0, 0);
+  setSpectraRange(WorkspaceIndex{0}, WorkspaceIndex{0});
 }
 
 void IndirectSpectrumSelectionView::setSpectraRegex(const std::string &regex) {
@@ -135,19 +140,24 @@ void IndirectSpectrumSelectionView::setMaskBinsRegex(const std::string &regex) {
       createValidator(QString::fromStdString(regex)));
 }
 
-void IndirectSpectrumSelectionView::setMinimumSpectrum(std::size_t spectrum) {
+void IndirectSpectrumSelectionView::setMinimumSpectrum(
+    WorkspaceIndex spectrum) {
   MantidQt::API::SignalBlocker blocker(m_selector->spMinimumSpectrum);
-  m_selector->spMinimumSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+  m_selector->spMinimumSpectrum->setValue(
+      boost::numeric_cast<int>(spectrum.value));
 }
 
-void IndirectSpectrumSelectionView::setMaximumSpectrum(std::size_t spectrum) {
+void IndirectSpectrumSelectionView::setMaximumSpectrum(
+    WorkspaceIndex spectrum) {
   MantidQt::API::SignalBlocker blocker(m_selector->spMaximumSpectrum);
-  m_selector->spMaximumSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+  m_selector->spMaximumSpectrum->setValue(
+      boost::numeric_cast<int>(spectrum.value));
 }
 
-void IndirectSpectrumSelectionView::setMaskSpectrum(std::size_t spectrum) {
+void IndirectSpectrumSelectionView::setMaskSpectrum(WorkspaceIndex spectrum) {
   MantidQt::API::SignalBlocker blocker(m_selector->spMaskSpectrum);
-  m_selector->spMaskSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+  m_selector->spMaskSpectrum->setValue(
+      boost::numeric_cast<int>(spectrum.value));
 }
 
 void IndirectSpectrumSelectionView::setSpectraString(
@@ -267,7 +277,11 @@ void IndirectSpectrumSelectionView::emitMaskChanged() {
 
 void IndirectSpectrumSelectionView::emitMaskSpectrumChanged(
     const QString &spectrum) {
-  emit maskSpectrumChanged(spectrum.toInt());
+  emit maskSpectrumChanged(WorkspaceIndex{spectrum.toInt()});
+}
+
+void IndirectSpectrumSelectionView::emitMaskSpectrumChanged(int spectrum) {
+  emit maskSpectrumChanged(WorkspaceIndex{spectrum});
 }
 
 } // namespace IDA
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.h b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.h
index 949f2e2786c..1029a6eb05d 100644
--- a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.h
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionView.h
@@ -7,6 +7,7 @@
 #ifndef MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONVIEW_H_
 #define MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONVIEW_H_
 
+#include "IndexTypes.h"
 #include "ui_IndirectSpectrumSelector.h"
 
 #include "DllConfig.h"
@@ -32,16 +33,16 @@ public:
 
   SpectrumSelectionMode selectionMode() const;
 
-  virtual std::size_t minimumSpectrum() const;
-  virtual std::size_t maximumSpectrum() const;
+  virtual WorkspaceIndex minimumSpectrum() const;
+  virtual WorkspaceIndex maximumSpectrum() const;
 
   virtual std::string spectraString() const;
   virtual std::string maskString() const;
 
   virtual void displaySpectra(const std::string &spectraString);
-  virtual void displaySpectra(int minimum, int maximum);
+  virtual void displaySpectra(std::pair<WorkspaceIndex, WorkspaceIndex> minmax);
 
-  virtual void setSpectraRange(int minimum, int maximum);
+  virtual void setSpectraRange(WorkspaceIndex minimum, WorkspaceIndex maximum);
 
   void setSpectraRegex(const std::string &regex);
   void setMaskBinsRegex(const std::string &regex);
@@ -58,13 +59,13 @@ public:
   virtual void clear();
 
 public slots:
-  virtual void setMinimumSpectrum(std::size_t spectrum);
-  virtual void setMaximumSpectrum(std::size_t spectrum);
-  void setMaskSpectrum(std::size_t spectrum);
+  virtual void setMinimumSpectrum(WorkspaceIndex spectrum);
+  virtual void setMaximumSpectrum(WorkspaceIndex spectrum);
+  void setMaskSpectrum(WorkspaceIndex spectrum);
 
   virtual void setSpectraString(const std::string &spectraString);
   virtual void setMaskString(const std::string &maskString);
-  void setMaskSpectraList(const std::vector<std::size_t> &maskSpectra);
+  void setMaskSpectraList(const std::vector<WorkspaceIndex> &maskSpectra);
 
   void hideSpectrumSelector();
   void showSpectrumSelector();
@@ -74,14 +75,16 @@ public slots:
   void clearMaskString();
 
 signals:
-  void selectedSpectraChanged(const std::string & /*_t1*/);
-  void selectedSpectraChanged(std::size_t /*_t1*/, std::size_t /*_t2*/);
-  void maskSpectrumChanged(int /*_t1*/);
-  void maskChanged(const std::string & /*_t1*/);
+  void selectedSpectraChanged(const std::string &);
+  void selectedSpectraChanged(WorkspaceIndex, WorkspaceIndex);
+  void spectraSelectionWidgetChanged(int);
+  void maskSpectrumChanged(WorkspaceIndex);
+  void maskChanged(const std::string &);
 
 private slots:
   void emitMaskChanged();
   void emitMaskSpectrumChanged(const QString &spectrum);
+  void emitMaskSpectrumChanged(int spectrum);
   void emitSpectraChanged(int modeIndex);
   void emitSpectraStringChanged();
   void emitSpectraRangeChanged();
@@ -90,8 +93,8 @@ private slots:
   void enableMaskLineEdit(int doEnable);
 
 private:
-  void setSpectraRangeMinimum(int minimum);
-  void setSpectraRangeMaximum(int maximum);
+  void setSpectraRangeMinimum(WorkspaceIndex minimum);
+  void setSpectraRangeMaximum(WorkspaceIndex maximum);
   void displaySpectraList();
   QValidator *createValidator(const QString &regex);
 
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.cpp b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.cpp
new file mode 100644
index 00000000000..86eb8c58353
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.cpp
@@ -0,0 +1,275 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#include "IndirectSpectrumSelectionViewLegacy.h"
+
+#include "MantidQtWidgets/Common/SignalBlocker.h"
+
+#include <QRegExpValidator>
+
+#include <boost/numeric/conversion/cast.hpp>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+IndirectSpectrumSelectionViewLegacy::IndirectSpectrumSelectionViewLegacy(QWidget *parent)
+    : API::MantidWidget(parent), m_selector(new Ui::IndirectSpectrumSelector) {
+  m_selector->setupUi(this);
+
+  connect(m_selector->cbMaskSpectrum, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(enableMaskLineEdit(int)));
+
+  connect(m_selector->spMaximumSpectrum, SIGNAL(valueChanged(int)), this,
+          SLOT(setSpectraRangeMaxiMin(int)));
+  connect(m_selector->spMinimumSpectrum, SIGNAL(valueChanged(int)), this,
+          SLOT(setSpectraRangeMiniMax(int)));
+
+  connect(m_selector->spMaximumSpectrum, SIGNAL(valueChanged(int)), this,
+          SLOT(emitSpectraRangeChanged()));
+  connect(m_selector->spMinimumSpectrum, SIGNAL(valueChanged(int)), this,
+          SLOT(emitSpectraRangeChanged()));
+  connect(m_selector->leSpectra, SIGNAL(editingFinished()), this,
+          SLOT(emitSpectraStringChanged()));
+
+  connect(m_selector->spMaskSpectrum, SIGNAL(valueChanged(int)), this,
+          SIGNAL(maskSpectrumChanged(int)));
+  connect(m_selector->cbMaskSpectrum,
+          SIGNAL(currentIndexChanged(const QString &)), this,
+          SLOT(emitMaskSpectrumChanged(const QString &)));
+  connect(m_selector->leMaskBins, SIGNAL(editingFinished()), this,
+          SLOT(emitMaskChanged()));
+
+  connect(m_selector->cbSelectionMode, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(emitSpectraChanged(int)));
+  connect(m_selector->cbSelectionMode, SIGNAL(currentIndexChanged(int)), this,
+          SLOT(clearMaskString()));
+}
+
+IndirectSpectrumSelectionViewLegacy::~IndirectSpectrumSelectionViewLegacy() {}
+
+SpectrumSelectionMode IndirectSpectrumSelectionViewLegacy::selectionMode() const {
+  return static_cast<SpectrumSelectionMode>(
+      m_selector->swSpectraSelection->currentIndex());
+}
+
+std::size_t IndirectSpectrumSelectionViewLegacy::minimumSpectrum() const {
+  return boost::numeric_cast<std::size_t>(
+      m_selector->spMinimumSpectrum->value());
+}
+
+std::size_t IndirectSpectrumSelectionViewLegacy::maximumSpectrum() const {
+  return boost::numeric_cast<std::size_t>(
+      m_selector->spMaximumSpectrum->value());
+}
+
+std::string IndirectSpectrumSelectionViewLegacy::spectraString() const {
+  return m_selector->leSpectra->text().toStdString();
+}
+
+std::string IndirectSpectrumSelectionViewLegacy::maskString() const {
+  return m_selector->leMaskBins->text().toStdString();
+}
+
+void IndirectSpectrumSelectionViewLegacy::displaySpectra(
+    const std::string &spectraString) {
+  setSpectraString(spectraString);
+  m_selector->cbSelectionMode->setCurrentIndex(
+      static_cast<int>(SpectrumSelectionMode::STRING));
+}
+
+void IndirectSpectrumSelectionViewLegacy::displaySpectra(int minimum, int maximum) {
+  setMinimumSpectrum(minimum);
+  setMaximumSpectrum(maximum);
+  m_selector->cbSelectionMode->setCurrentIndex(
+      static_cast<int>(SpectrumSelectionMode::RANGE));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRange(int minimum, int maximum) {
+  setSpectraRangeMinimum(minimum);
+  setSpectraRangeMaximum(maximum);
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRangeMinimum(int minimum) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMinimumSpectrum);
+  m_selector->spMinimumSpectrum->setMinimum(minimum);
+  setSpectraRangeMiniMax(minimum);
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRangeMaximum(int maximum) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMaximumSpectrum);
+  m_selector->spMaximumSpectrum->setMaximum(maximum);
+  setSpectraRangeMaxiMin(maximum);
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaskSpectraList(
+    const std::vector<std::size_t> &spectra) {
+  m_selector->cbMaskSpectrum->clear();
+  for (const auto &spectrum : spectra)
+    m_selector->cbMaskSpectrum->addItem(QString::number(spectrum));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaskSelectionEnabled(bool enabled) {
+  m_selector->cbMaskSpectrum->setEnabled(enabled);
+  m_selector->lbMaskSpectrum->setEnabled(enabled);
+  m_selector->leMaskBins->setEnabled(enabled);
+}
+
+void IndirectSpectrumSelectionViewLegacy::clear() {
+  m_selector->leSpectra->clear();
+  m_selector->leMaskBins->clear();
+  m_selector->cbMaskSpectrum->clear();
+  setSpectraRange(0, 0);
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRegex(const std::string &regex) {
+  m_selector->leSpectra->setValidator(
+      createValidator(QString::fromStdString(regex)));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaskBinsRegex(const std::string &regex) {
+  m_selector->leMaskBins->setValidator(
+      createValidator(QString::fromStdString(regex)));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMinimumSpectrum(std::size_t spectrum) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMinimumSpectrum);
+  m_selector->spMinimumSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaximumSpectrum(std::size_t spectrum) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMaximumSpectrum);
+  m_selector->spMaximumSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaskSpectrum(std::size_t spectrum) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMaskSpectrum);
+  m_selector->spMaskSpectrum->setValue(boost::numeric_cast<int>(spectrum));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraString(
+    const std::string &spectraString) {
+  MantidQt::API::SignalBlocker blocker(m_selector->leSpectra);
+  m_selector->leSpectra->setText(QString::fromStdString(spectraString));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setMaskString(
+    const std::string &maskString) {
+  MantidQt::API::SignalBlocker blocker(m_selector->leMaskBins);
+  m_selector->leMaskBins->setText(QString::fromStdString(maskString));
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRangeMaxiMin(int value) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMinimumSpectrum);
+  m_selector->spMinimumSpectrum->setMaximum(value);
+  m_selector->spMaskSpectrum->setMaximum(value);
+}
+
+void IndirectSpectrumSelectionViewLegacy::setSpectraRangeMiniMax(int value) {
+  MantidQt::API::SignalBlocker blocker(m_selector->spMaximumSpectrum);
+  m_selector->spMaximumSpectrum->setMinimum(value);
+  m_selector->spMaskSpectrum->setMinimum(value);
+}
+
+void IndirectSpectrumSelectionViewLegacy::showSpectraErrorLabel() {
+  UserInputValidator().setErrorLabel(m_selector->lbSpectraError, false);
+}
+
+void IndirectSpectrumSelectionViewLegacy::showMaskBinErrorLabel() {
+  UserInputValidator().setErrorLabel(m_selector->lbMaskBinsError, false);
+}
+
+void IndirectSpectrumSelectionViewLegacy::hideSpectraErrorLabel() {
+  m_selector->lbSpectraError->setText("");
+  m_selector->lbSpectraError->setVisible(false);
+}
+
+void IndirectSpectrumSelectionViewLegacy::hideMaskBinErrorLabel() {
+  m_selector->lbMaskBinsError->setText("");
+  m_selector->lbMaskBinsError->setVisible(false);
+}
+
+QValidator *
+IndirectSpectrumSelectionViewLegacy::createValidator(const QString &regex) {
+  return new QRegExpValidator(QRegExp(regex), this);
+}
+
+UserInputValidator &IndirectSpectrumSelectionViewLegacy::validateSpectraString(
+    UserInputValidator &uiv) const {
+  if (selectionMode() == SpectrumSelectionMode::STRING)
+    uiv.checkFieldIsValid("Spectra", m_selector->leSpectra,
+                          m_selector->lbSpectraError);
+  return uiv;
+}
+
+UserInputValidator &IndirectSpectrumSelectionViewLegacy::validateMaskBinsString(
+    UserInputValidator &uiv) const {
+  uiv.checkFieldIsValid("Mask Bins", m_selector->leMaskBins,
+                        m_selector->lbMaskBinsError);
+  return uiv;
+}
+
+void IndirectSpectrumSelectionViewLegacy::hideSpectrumSelector() {
+  m_selector->lbSelectionMode->hide();
+  m_selector->cbSelectionMode->hide();
+  m_selector->swSpectraSelection->hide();
+  m_selector->lbColon->hide();
+}
+
+void IndirectSpectrumSelectionViewLegacy::showSpectrumSelector() {
+  m_selector->lbSelectionMode->show();
+  m_selector->cbSelectionMode->show();
+  m_selector->swSpectraSelection->show();
+  m_selector->lbColon->show();
+}
+
+void IndirectSpectrumSelectionViewLegacy::hideMaskSpectrumSelector() {
+  m_selector->swMaskSpectrumSelection->hide();
+}
+
+void IndirectSpectrumSelectionViewLegacy::showMaskSpectrumSelector() {
+  m_selector->swMaskSpectrumSelection->show();
+}
+
+void IndirectSpectrumSelectionViewLegacy::clearMaskString() {
+  m_selector->leMaskBins->clear();
+}
+
+void IndirectSpectrumSelectionViewLegacy::enableMaskLineEdit(int doEnable) {
+  if (doEnable >= 0 || selectionMode() == SpectrumSelectionMode::RANGE)
+    m_selector->leMaskBins->setEnabled(true);
+  else
+    m_selector->leMaskBins->setEnabled(false);
+}
+
+void IndirectSpectrumSelectionViewLegacy::emitSpectraChanged(int modeIndex) {
+  const auto mode = static_cast<SpectrumSelectionMode>(modeIndex);
+  if (mode == SpectrumSelectionMode::RANGE)
+    emitSpectraRangeChanged();
+  else
+    emitSpectraStringChanged();
+}
+
+void IndirectSpectrumSelectionViewLegacy::emitSpectraRangeChanged() {
+  emit selectedSpectraChanged(minimumSpectrum(), maximumSpectrum());
+}
+
+void IndirectSpectrumSelectionViewLegacy::emitSpectraStringChanged() {
+  emit selectedSpectraChanged(m_selector->leSpectra->text().toStdString());
+}
+
+void IndirectSpectrumSelectionViewLegacy::emitMaskChanged() {
+  emit maskChanged(m_selector->leMaskBins->text().toStdString());
+}
+
+void IndirectSpectrumSelectionViewLegacy::emitMaskSpectrumChanged(
+    const QString &spectrum) {
+  emit maskSpectrumChanged(spectrum.toInt());
+}
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
diff --git a/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.h b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.h
new file mode 100644
index 00000000000..c567bf8747d
--- /dev/null
+++ b/qt/scientific_interfaces/Indirect/IndirectSpectrumSelectionViewLegacy.h
@@ -0,0 +1,105 @@
+// Mantid Repository : https://github.com/mantidproject/mantid
+//
+// Copyright &copy; 2013 ISIS Rutherford Appleton Laboratory UKRI,
+//     NScD Oak Ridge National Laboratory, European Spallation Source
+//     & Institut Laue - Langevin
+// SPDX - License - Identifier: GPL - 3.0 +
+#ifndef MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONVIEW_H_
+#define MANTID_CUSTOMINTERFACES_INDIRECTSPECTRUMSELECTIONVIEW_H_
+
+#include "ui_IndirectSpectrumSelector.h"
+
+#include "DllConfig.h"
+#include "MantidKernel/System.h"
+#include "MantidQtWidgets/Common/MantidWidget.h"
+#include "MantidQtWidgets/Common/UserInputValidator.h"
+
+#include <cstddef>
+
+namespace MantidQt {
+namespace CustomInterfaces {
+namespace IDA {
+
+enum class SpectrumSelectionMode { RANGE, STRING };
+
+class MANTIDQT_INDIRECT_DLL IndirectSpectrumSelectionViewLegacy
+    : public API::MantidWidget {
+  Q_OBJECT
+
+public:
+  IndirectSpectrumSelectionViewLegacy(QWidget *parent = nullptr);
+  virtual ~IndirectSpectrumSelectionViewLegacy() override;
+
+  SpectrumSelectionMode selectionMode() const;
+
+  virtual std::size_t minimumSpectrum() const;
+  virtual std::size_t maximumSpectrum() const;
+
+  virtual std::string spectraString() const;
+  virtual std::string maskString() const;
+
+  virtual void displaySpectra(const std::string &spectraString);
+  virtual void displaySpectra(int minimum, int maximum);
+
+  virtual void setSpectraRange(int minimum, int maximum);
+
+  void setSpectraRegex(const std::string &regex);
+  void setMaskBinsRegex(const std::string &regex);
+
+  UserInputValidator &validateSpectraString(UserInputValidator &uiv) const;
+  UserInputValidator &validateMaskBinsString(UserInputValidator &uiv) const;
+
+  virtual void showSpectraErrorLabel();
+  void showMaskBinErrorLabel();
+  virtual void hideSpectraErrorLabel();
+  void hideMaskBinErrorLabel();
+
+  virtual void setMaskSelectionEnabled(bool enabled);
+  virtual void clear();
+
+public slots:
+  virtual void setMinimumSpectrum(std::size_t spectrum);
+  virtual void setMaximumSpectrum(std::size_t spectrum);
+  void setMaskSpectrum(std::size_t spectrum);
+
+  virtual void setSpectraString(const std::string &spectraString);
+  virtual void setMaskString(const std::string &maskString);
+  void setMaskSpectraList(const std::vector<std::size_t> &maskSpectra);
+
+  void hideSpectrumSelector();
+  void showSpectrumSelector();
+  void hideMaskSpectrumSelector();
+  void showMaskSpectrumSelector();
+
+  void clearMaskString();
+
+signals:
+  void selectedSpectraChanged(const std::string & /*_t1*/);
+  void selectedSpectraChanged(std::size_t /*_t1*/, std::size_t /*_t2*/);
+  void maskSpectrumChanged(int /*_t1*/);
+  void maskChanged(const std::string & /*_t1*/);
+
+private slots:
+  void emitMaskChanged();
+  void emitMaskSpectrumChanged(const QString &spectrum);
+  void emitSpectraChanged(int modeIndex);
+  void emitSpectraStringChanged();
+  void emitSpectraRangeChanged();
+  void setSpectraRangeMiniMax(int value);
+  void setSpectraRangeMaxiMin(int value);
+  void enableMaskLineEdit(int doEnable);
+
+private:
+  void setSpectraRangeMinimum(int minimum);
+  void setSpectraRangeMaximum(int maximum);
+  void displaySpectraList();
+  QValidator *createValidator(const QString &regex);
+
+  std::unique_ptr<Ui::IndirectSpectrumSelector> m_selector;
+};
+
+} // namespace IDA
+} // namespace CustomInterfaces
+} // namespace MantidQt
+
+#endif
diff --git a/qt/scientific_interfaces/Indirect/IqtFit.cpp b/qt/scientific_interfaces/Indirect/IqtFit.cpp
index 48f6421f66c..c26d1031847 100644
--- a/qt/scientific_interfaces/Indirect/IqtFit.cpp
+++ b/qt/scientific_interfaces/Indirect/IqtFit.cpp
@@ -34,7 +34,7 @@ namespace CustomInterfaces {
 namespace IDA {
 
 IqtFit::IqtFit(QWidget *parent)
-    : IndirectFitAnalysisTab(new IqtFitModel, parent),
+    : IndirectFitAnalysisTabLegacy(new IqtFitModel, parent),
       m_uiForm(new Ui::IqtFit) {
   m_uiForm->setupUi(parent);
   m_iqtFittingModel = dynamic_cast<IqtFitModel *>(fittingModel());
@@ -120,7 +120,7 @@ std::string IqtFit::fitTypeString() const {
 void IqtFit::setupFit(Mantid::API::IAlgorithm_sptr fitAlgorithm) {
   fitAlgorithm->setProperty("ExtractMembers",
                             boolSettingValue("ExtractMembers"));
-  IndirectFitAnalysisTab::setupFit(fitAlgorithm);
+  IndirectFitAnalysisTabLegacy::setupFit(fitAlgorithm);
 }
 
 void IqtFit::runClicked() { runTab(); }
diff --git a/qt/scientific_interfaces/Indirect/IqtFit.h b/qt/scientific_interfaces/Indirect/IqtFit.h
index 02621dd609f..c50ae3c751c 100644
--- a/qt/scientific_interfaces/Indirect/IqtFit.h
+++ b/qt/scientific_interfaces/Indirect/IqtFit.h
@@ -7,7 +7,7 @@
 #ifndef MANTIDQTCUSTOMINTERFACESIDA_IQTFIT_H_
 #define MANTIDQTCUSTOMINTERFACESIDA_IQTFIT_H_
 
-#include "IndirectFitAnalysisTab.h"
+#include "IndirectFitAnalysisTabLegacy.h"
 #include "IqtFitModel.h"
 
 #include "MantidAPI/CompositeFunction.h"
@@ -27,7 +27,7 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 
-class DLLExport IqtFit : public IndirectFitAnalysisTab {
+class DLLExport IqtFit : public IndirectFitAnalysisTabLegacy {
   Q_OBJECT
 
 public:
diff --git a/qt/scientific_interfaces/Indirect/IqtFit.ui b/qt/scientific_interfaces/Indirect/IqtFit.ui
index 30eb28c4e66..1b92821f385 100644
--- a/qt/scientific_interfaces/Indirect/IqtFit.ui
+++ b/qt/scientific_interfaces/Indirect/IqtFit.ui
@@ -62,7 +62,7 @@
            <number>0</number>
           </property>
           <item>
-           <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView" name="svSpectrumView" native="true"/>
+           <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy" name="svSpectrumView" native="true"/>
           </item>
           <item>
            <widget class="QGroupBox" name="gbRun">
@@ -126,9 +126,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView</class>
+   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy</class>
    <extends>QWidget</extends>
-   <header>IndirectSpectrumSelectionView.h</header>
+   <header>IndirectSpectrumSelectionViewLegacy.h</header>
    <container>1</container>
   </customwidget>
   <customwidget>
diff --git a/qt/scientific_interfaces/Indirect/JumpFit.cpp b/qt/scientific_interfaces/Indirect/JumpFit.cpp
index 8e6f2b88fb2..fcdc9f410bd 100644
--- a/qt/scientific_interfaces/Indirect/JumpFit.cpp
+++ b/qt/scientific_interfaces/Indirect/JumpFit.cpp
@@ -40,7 +40,7 @@ namespace CustomInterfaces {
 namespace IDA {
 
 JumpFit::JumpFit(QWidget *parent)
-    : IndirectFitAnalysisTab(new JumpFitModel, parent),
+    : IndirectFitAnalysisTabLegacy(new JumpFitModel, parent),
       m_uiForm(new Ui::JumpFit) {
   m_uiForm->setupUi(parent);
 
diff --git a/qt/scientific_interfaces/Indirect/JumpFit.h b/qt/scientific_interfaces/Indirect/JumpFit.h
index 9d4f00c7a94..3532245d5b8 100644
--- a/qt/scientific_interfaces/Indirect/JumpFit.h
+++ b/qt/scientific_interfaces/Indirect/JumpFit.h
@@ -7,7 +7,7 @@
 #ifndef MANTIDQTCUSTOMINTERFACES_JUMPFIT_H_
 #define MANTIDQTCUSTOMINTERFACES_JUMPFIT_H_
 
-#include "IndirectFitAnalysisTab.h"
+#include "IndirectFitAnalysisTabLegacy.h"
 #include "JumpFitModel.h"
 #include "ui_JumpFit.h"
 
@@ -17,7 +17,7 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
-class DLLExport JumpFit : public IndirectFitAnalysisTab {
+class DLLExport JumpFit : public IndirectFitAnalysisTabLegacy {
   Q_OBJECT
 
 public:
diff --git a/qt/scientific_interfaces/Indirect/JumpFit.ui b/qt/scientific_interfaces/Indirect/JumpFit.ui
index 4183d19b9ad..d9f1a10ec7d 100644
--- a/qt/scientific_interfaces/Indirect/JumpFit.ui
+++ b/qt/scientific_interfaces/Indirect/JumpFit.ui
@@ -130,7 +130,7 @@
             </layout>
            </item>
            <item>
-            <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView" name="svSpectrumView" native="true"/>
+            <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy" name="svSpectrumView" native="true"/>
            </item>
           </layout>
          </item>
@@ -216,9 +216,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView</class>
+   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy</class>
    <extends>QWidget</extends>
-   <header>IndirectSpectrumSelectionView.h</header>
+   <header>IndirectSpectrumSelectionViewLegacy.h</header>
    <container>1</container>
   </customwidget>
   <customwidget>
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.cpp b/qt/scientific_interfaces/Indirect/MSDFit.cpp
index 56d1bd7a99a..319395d4f96 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.cpp
+++ b/qt/scientific_interfaces/Indirect/MSDFit.cpp
@@ -29,7 +29,7 @@ namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
 MSDFit::MSDFit(QWidget *parent)
-    : IndirectFitAnalysisTab(new MSDFitModel, parent),
+    : IndirectFitAnalysisTabLegacy(new MSDFitModel, parent),
       m_uiForm(new Ui::MSDFit) {
   m_uiForm->setupUi(parent);
 
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.h b/qt/scientific_interfaces/Indirect/MSDFit.h
index dbe18e1f858..ccfafe9d22c 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.h
+++ b/qt/scientific_interfaces/Indirect/MSDFit.h
@@ -7,7 +7,7 @@
 #ifndef MANTIDQTCUSTOMINTERFACESIDA_MSDFIT_H_
 #define MANTIDQTCUSTOMINTERFACESIDA_MSDFIT_H_
 
-#include "IndirectFitAnalysisTab.h"
+#include "IndirectFitAnalysisTabLegacy.h"
 #include "MSDFitModel.h"
 #include "ui_MSDFit.h"
 
@@ -16,7 +16,7 @@
 namespace MantidQt {
 namespace CustomInterfaces {
 namespace IDA {
-class DLLExport MSDFit : public IndirectFitAnalysisTab {
+class DLLExport MSDFit : public IndirectFitAnalysisTabLegacy {
   Q_OBJECT
 
 public:
diff --git a/qt/scientific_interfaces/Indirect/MSDFit.ui b/qt/scientific_interfaces/Indirect/MSDFit.ui
index f8410efdc67..efea5d9bd43 100644
--- a/qt/scientific_interfaces/Indirect/MSDFit.ui
+++ b/qt/scientific_interfaces/Indirect/MSDFit.ui
@@ -59,7 +59,7 @@
            <number>0</number>
           </property>
           <item>
-           <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView" name="svSpectrumView" native="true"/>
+           <widget class="MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy" name="svSpectrumView" native="true"/>
           </item>
           <item>
            <widget class="QGroupBox" name="gbRun">
@@ -123,9 +123,9 @@
  </widget>
  <customwidgets>
   <customwidget>
-   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionView</class>
+   <class>MantidQt::CustomInterfaces::IDA::IndirectSpectrumSelectionViewLegacy</class>
    <extends>QWidget</extends>
-   <header>IndirectSpectrumSelectionView.h</header>
+   <header>IndirectSpectrumSelectionViewLegacy.h</header>
    <container>1</container>
   </customwidget>
   <customwidget>
diff --git a/qt/scientific_interfaces/Indirect/test/IndirectSpectrumSelectionPresenterTest.h b/qt/scientific_interfaces/Indirect/test/IndirectSpectrumSelectionPresenterTest.h
index 061a16cea7b..bf115603f1e 100644
--- a/qt/scientific_interfaces/Indirect/test/IndirectSpectrumSelectionPresenterTest.h
+++ b/qt/scientific_interfaces/Indirect/test/IndirectSpectrumSelectionPresenterTest.h
@@ -11,7 +11,7 @@
 #include <gmock/gmock.h>
 
 #include "IndirectFittingModelLegacy.h"
-#include "IndirectSpectrumSelectionPresenter.h"
+#include "IndirectSpectrumSelectionPresenterLegacy.h"
 #include "MantidAPI/FrameworkManager.h"
 #include "MantidAPI/IAlgorithm.h"
 #include "MantidAPI/IFunction.h"
@@ -49,7 +49,7 @@ static QApplicationHolder MAIN_QAPPLICATION;
 GNU_DIAG_OFF_SUGGEST_OVERRIDE
 
 /// Mock object to mock the view
-class MockIndirectSpectrumSelectionView : public IndirectSpectrumSelectionView {
+class MockIndirectSpectrumSelectionView : public IndirectSpectrumSelectionViewLegacy {
 public:
   /// Signals
   void emitSelectedSpectraChanged(std::string const &spectra) {
@@ -91,7 +91,7 @@ public:
 };
 
 /// Note that there is limited (if any) interaction going from this model to the
-/// IndirectSpectrumSelectionView, meaning that not many methods are required
+/// IndirectSpectrumSelectionViewLegacy, meaning that not many methods are required
 /// for mocking.
 class MockIndirectSpectrumSelectionModel : public IndirectFittingModelLegacy {
 public:
@@ -133,7 +133,7 @@ public:
   void setUp() override {
     m_view = std::make_unique<NiceMock<MockIndirectSpectrumSelectionView>>();
     m_model = std::make_unique<NiceMock<MockIndirectSpectrumSelectionModel>>();
-    m_presenter = std::make_unique<IndirectSpectrumSelectionPresenter>(
+    m_presenter = std::make_unique<IndirectSpectrumSelectionPresenterLegacy>(
         std::move(m_model.get()), std::move(m_view.get()));
 
     SetUpADSWithWorkspace ads("WorkspaceName", createWorkspace(10));
@@ -362,7 +362,7 @@ public:
 private:
   std::unique_ptr<MockIndirectSpectrumSelectionView> m_view;
   std::unique_ptr<MockIndirectSpectrumSelectionModel> m_model;
-  std::unique_ptr<IndirectSpectrumSelectionPresenter> m_presenter;
+  std::unique_ptr<IndirectSpectrumSelectionPresenterLegacy> m_presenter;
 };
 
 #endif
-- 
GitLab