diff --git a/Framework/CurveFitting/CMakeLists.txt b/Framework/CurveFitting/CMakeLists.txt
index 34fb88a0834b3e5137f0bd5e8fb4db5898cb740d..88a3e7307660eb1bcb9794c92650e36e382bb575 100644
--- a/Framework/CurveFitting/CMakeLists.txt
+++ b/Framework/CurveFitting/CMakeLists.txt
@@ -350,6 +350,7 @@ set ( TEST_FILES
 	FuncMinimizers/FRConjugateGradientTest.h
 	FuncMinimizers/LevenbergMarquardtMDTest.h
 	FuncMinimizers/LevenbergMarquardtTest.h
+        FuncMinimizers/MoreSorensenTest.h
 	FuncMinimizers/PRConjugateGradientTest.h
 	FuncMinimizers/SimplexTest.h
 	FunctionDomain1DSpectrumCreatorTest.h
diff --git a/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h b/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4deba4f3e44e22cb623cdefa570dd41d658171a
--- /dev/null
+++ b/Framework/CurveFitting/test/FuncMinimizers/MoreSorensenTest.h
@@ -0,0 +1,331 @@
+#ifndef CURVEFITTING_MORESORNSENTTEST_H_
+#define CURVEFITTING_MORESORENSENTEST_H_
+
+#include <cxxtest/TestSuite.h>
+
+#include "MantidCurveFitting/CostFunctions/CostFuncLeastSquares.h"
+#include "MantidCurveFitting/FuncMinimizers/MoreSorensenMinimizer.h"
+#include "MantidCurveFitting/Functions/UserFunction.h"
+#include "MantidAPI/FunctionDomain1D.h"
+#include "MantidAPI/FunctionValues.h"
+#include "MantidCurveFitting/Constraints/BoundaryConstraint.h"
+
+#include <sstream>
+
+using namespace Mantid;
+using namespace Mantid::CurveFitting;
+using namespace Mantid::CurveFitting::FuncMinimisers;
+using namespace Mantid::CurveFitting::CostFunctions;
+using namespace Mantid::CurveFitting::Constraints;
+using namespace Mantid::CurveFitting::Functions;
+using namespace Mantid::API;
+
+class MoreSorensenTest : public CxxTest::TestSuite {
+public:
+  // This pair of boilerplate methods prevent the suite being created statically
+  // This means the constructor isn't called when running other tests
+  static MoreSorensenTest *createSuite() {
+    return new MoreSorensenTest();
+  }
+  static void destroySuite(MoreSorensenTest *suite) { delete suite; }
+
+  void test_Linear() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.);
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 2);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+
+    TS_ASSERT_DELTA(fun->getParameter("a"), 1.1, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2.2, 0.01);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void test_Gaussian() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.setParameter("h", 3.3);
+    dataMaker.setParameter("s", 0.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.);
+    fun->setParameter("h", 3.);
+    fun->setParameter("s", 0.1);
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+    TS_ASSERT_DELTA(costFun->val(), 0.0, 0.0001);
+    TS_ASSERT_DELTA(fun->getParameter("a"), 1.1, 0.001);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2.2, 0.001);
+    TS_ASSERT_DELTA(fun->getParameter("h"), 3.3, 0.001);
+    TS_ASSERT_DELTA(fun->getParameter("s"), 0.2, 0.001);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void test_Gaussian_fixed() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.setParameter("h", 3.3);
+    dataMaker.setParameter("s", 0.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.5);
+    fun->setParameter("h", 3.);
+    fun->setParameter("s", 0.1);
+    fun->fix(0);
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 3);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+    TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("a"), 1., 0.000001);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2.90, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("h"), 2.67, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("s"), 0.27, 0.01);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void test_Gaussian_tied() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.setParameter("h", 3.3);
+    dataMaker.setParameter("s", 0.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.5);
+    fun->setParameter("h", 3.);
+    fun->setParameter("s", 0.1);
+    fun->tie("a", "1");
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 3);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+    TS_ASSERT_DELTA(costFun->val(), 0.2, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("a"), 1., 0.000001);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2.90, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("h"), 2.67, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("s"), 0.27, 0.01);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void xtest_Gaussian_tied_with_formula() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.setParameter("h", 3.3);
+    dataMaker.setParameter("s", 0.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b+h*exp(-s*x^2)");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.);
+    fun->setParameter("h", 3.);
+    fun->setParameter("s", 0.1);
+    fun->tie("b", "2*a+0.1");
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 3);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+    TS_ASSERT_DELTA(costFun->val(), 0.002, 0.01);
+
+    double a = fun->getParameter("a");
+    TS_ASSERT_DELTA(a, 1.0895, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2 * a + 0.1, 0.0001);
+    TS_ASSERT_DELTA(fun->getParameter("h"), 3.23, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("s"), 0.207, 0.001);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void xtest_Linear_constrained() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x+b");
+    dataMaker.setParameter("a", 1.1);
+    dataMaker.setParameter("b", 2.2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a*x+b");
+    fun->setParameter("a", 1.);
+    fun->setParameter("b", 2.);
+
+    fun->addConstraint(
+        Kernel::make_unique<BoundaryConstraint>(fun.get(), "a", 0, 0.5));
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 2);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+
+    TS_ASSERT_DELTA(fun->getParameter("a"), 0.5, 0.1);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 5.2, 0.2);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void xtest_Linear_constrained1() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 10.0, 20));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a^2*x+b");
+    dataMaker.setParameter("a", 1);
+    dataMaker.setParameter("b", 2);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a^2*x+b");
+    fun->setParameter("a", -0.5);
+    fun->setParameter("b", 2.2);
+
+    // lower bound is made > 0 because function's derivative over "a" at a=0 is
+    // 0
+    fun->addConstraint(
+        Kernel::make_unique<BoundaryConstraint>(fun.get(), "a", 0.001, 2.0));
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+    TS_ASSERT_EQUALS(costFun->nParams(), 2);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(s.minimize());
+
+    // std::cerr << "a=" << fun->getParameter("a") << '\n';
+    // std::cerr << "b=" << fun->getParameter("b") << '\n';
+
+    TS_ASSERT_DELTA(costFun->val(), 0.00, 0.0001);
+    TS_ASSERT_DELTA(fun->getParameter("a"), 1.0, 0.01);
+    TS_ASSERT_DELTA(fun->getParameter("b"), 2.0, 0.01);
+    TS_ASSERT_EQUALS(s.getError(), "success");
+  }
+
+  void xtest_cannot_reach_tolerance() {
+    API::FunctionDomain1D_sptr domain(
+        new API::FunctionDomain1DVector(0.0, 1.0, 10));
+    API::FunctionValues mockData(*domain);
+    UserFunction dataMaker;
+    dataMaker.setAttributeValue("Formula", "a*x");
+    dataMaker.setParameter("a", 1.0);
+    dataMaker.function(*domain, mockData);
+
+    API::FunctionValues_sptr values(new API::FunctionValues(*domain));
+    values->setFitDataFromCalculated(mockData);
+    values->setFitWeights(1.0);
+
+    boost::shared_ptr<UserFunction> fun = boost::make_shared<UserFunction>();
+    fun->setAttributeValue("Formula", "a+b+0*x");
+
+    boost::shared_ptr<CostFuncLeastSquares> costFun =
+        boost::make_shared<CostFuncLeastSquares>();
+    costFun->setFittingFunction(fun, domain, values);
+
+    MoreSorensenMinimizer s;
+    s.initialize(costFun);
+    TS_ASSERT(!s.minimize());
+
+    TS_ASSERT_EQUALS(s.getError(), "cannot reach the specified tolerance in F");
+  }
+};
+
+#endif /*CURVEFITTING_MORESORENSENTEST_H_*/