diff --git a/NumLib/ODESolver/NonlinearSolver-impl.h b/NumLib/ODESolver/NonlinearSolver-impl.h
index 95acaadd1a1dbd868095c00f9725fa3cec6e1cc9..303934b62cff7195310542910b4809f424584072 100644
--- a/NumLib/ODESolver/NonlinearSolver-impl.h
+++ b/NumLib/ODESolver/NonlinearSolver-impl.h
@@ -12,34 +12,31 @@
 // for debugging
 // #include <iostream>
 
+#include "BaseLib/ConfigTree.h"
 #include "MathLib/LinAlg/BLAS.h"
 
 #include "NonlinearSolver.h"
 
 #include "MathLib/LinAlg/VectorNorms.h"
 
-// TODO: change
-#include "ODETypes.h" // for one shot linear solver
-
-
 namespace NumLib
 {
 
 template<typename Matrix, typename Vector>
 void
 NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Picard>::
-assemble(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Picard> &sys,
-         Vector const& x) const
+assemble(Vector const& x) const
 {
-    sys.assembleMatricesPicard(x);
+    _equation_system->assembleMatricesPicard(x);
 }
 
 template<typename Matrix, typename Vector>
 bool
 NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Picard>::
-solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Picard> &sys, Vector &x)
+solve(Vector &x)
 {
     namespace BLAS = MathLib::BLAS;
+    auto& sys = *_equation_system;
 
     bool success = false;
 
@@ -57,11 +54,16 @@ solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Picard> &sys, Vector &
         // std::cout << "A:\n" << Eigen::MatrixXd(A) << "\n";
         // std::cout << "rhs:\n" << rhs << "\n\n";
 
-        oneShotLinearSolve(_A, _rhs, _x_new);
+        if (!_linear_solver.solve(_A, _rhs, _x_new)) {
+            ERR("The linear solver failed.");
+            x = _x_new;
+            success = false;
+            break;
+        }
 
         // x is used as delta_x in order to compute the error.
         BLAS::aypx(x, -1.0, _x_new); // x = _x_new - x
-        auto const error = norm(x);
+        auto const error = BLAS::norm2(x);
         // INFO("  picard iteration %u error: %e", iteration, error);
 
         // Update x s.t. in the next iteration we will compute the right delta x
@@ -86,18 +88,21 @@ solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Picard> &sys, Vector &
 template<typename Matrix, typename Vector>
 void
 NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Newton>::
-assemble(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton> &sys,
-         Vector const& x) const
+assemble(Vector const& x) const
 {
-    sys.assembleResidualNewton(x);
+    _equation_system->assembleResidualNewton(x);
+    // TODO if the equation system would be reset to nullptr after each
+    //      assemble() or solve() call, the user would be forced to set the
+    //      equation every time and could not forget it.
 }
 
 template<typename Matrix, typename Vector>
 bool
 NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Newton>::
-solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton> &sys, Vector &x)
+solve(Vector &x)
 {
     namespace BLAS = MathLib::BLAS;
+    auto& sys = *_equation_system;
 
     bool success = false;
 
@@ -114,7 +119,7 @@ solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton> &sys, Vector &
         // std::cout << "  res:\n" << res << std::endl;
 
         // TODO streamline that, make consistent with Picard.
-        if (norm(_res) < _tol) {
+        if (BLAS::norm2(_res) < _tol) {
             success = true;
             break;
         }
@@ -125,7 +130,12 @@ solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton> &sys, Vector &
 
         // std::cout << "  J:\n" << Eigen::MatrixXd(J) << std::endl;
 
-        oneShotLinearSolve(_J, _res, _minus_delta_x);
+        if (!_linear_solver.solve(_J, _res, _minus_delta_x)) {
+            ERR("The linear solver failed.");
+            BLAS::axpy(x, -_alpha, _minus_delta_x);
+            success = false;
+            break;
+        }
 
         // auto const dx_norm = _minus_delta_x.norm();
         // INFO("  newton iteration %u, norm of delta x: %e", iteration, dx_norm);
@@ -142,4 +152,37 @@ solve(NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton> &sys, Vector &
     return success;
 }
 
+
+template<typename Matrix, typename Vector>
+std::pair<
+    std::unique_ptr<NonlinearSolverBase<Matrix, Vector> >,
+    NonlinearSolverTag
+>
+createNonlinearSolver(MathLib::LinearSolver<Matrix, Vector>& linear_solver,
+                      BaseLib::ConfigTree const& config)
+{
+    using AbstractNLS = NonlinearSolverBase<Matrix, Vector>;
+
+    auto const type      = config.getConfParam<std::string>("type");
+    auto const tol       = config.getConfParam<double>("tol");
+    auto const max_iter  = config.getConfParam<unsigned>("max_iter");
+
+    if (type == "Picard")
+    {
+        auto const tag = NonlinearSolverTag::Picard;
+        using ConcreteNLS = NonlinearSolver<Matrix, Vector, tag>;
+        return std::make_pair(std::unique_ptr<AbstractNLS>(
+            new ConcreteNLS{linear_solver, tol, max_iter}), tag);
+    }
+    else if (type == "Newton")
+    {
+        auto const tag = NonlinearSolverTag::Newton;
+        using ConcreteNLS = NonlinearSolver<Matrix, Vector, tag>;
+        return std::make_pair(std::unique_ptr<AbstractNLS>(
+            new ConcreteNLS{linear_solver, tol, max_iter}), tag);
+    }
+    std::abort();
+}
+
+
 }
diff --git a/NumLib/ODESolver/NonlinearSolver.h b/NumLib/ODESolver/NonlinearSolver.h
index 0077fc3cf8f8bc95339cc107749c4115c6dfa69f..cae9903d359479039e60d8cbbc568fc364853044 100644
--- a/NumLib/ODESolver/NonlinearSolver.h
+++ b/NumLib/ODESolver/NonlinearSolver.h
@@ -10,15 +10,58 @@
 #ifndef NUMLIB_NONLINEARSOLVER_H
 #define NUMLIB_NONLINEARSOLVER_H
 
+#include <memory>
+#include <utility>
 #include <logog/include/logog.hpp>
 
+#include "MathLib/LinAlg/LinearSolver.h"
+
 #include "Types.h"
 #include "NonlinearSystem.h"
 
+namespace BaseLib
+{
+class ConfigTree;
+}
+
+// TODO Document in the ODE solver lib, which matrices and vectors that are passed around
+//      as method arguments are guaranteed to be of the right size (and zeroed out) and
+//      which are not.
 
 namespace NumLib
 {
 
+/*! Common interface for nonlinear solvers.
+ *
+ * \tparam Matrix the type of matrices occuring in the linearization of the equation.
+ * \tparam Vector the type of the solution vector of the equation.
+ */
+template<typename Matrix, typename Vector>
+class NonlinearSolverBase
+{
+public:
+    /*! Only assemble the equation system.
+     *
+     * \note This method is needed to preload CrankNicolson time discretization scheme.
+     *       It is not used for the general solver steps; in those only the solve() method
+     *       is needed.
+     *
+     * \param x   the state at which the equation system will be assembled.
+     */
+    virtual void assemble(Vector const& x) const = 0;
+
+    /*! Assemble and solve the equation system.
+     *
+     * \param x   in: the initial guess, out: the solution.
+     *
+     * \retval true if the equation system could be solved
+     * \retval false otherwise
+     */
+    virtual bool solve(Vector& x) = 0;
+
+    virtual ~NonlinearSolverBase() = default;
+};
+
 //! \addtogroup ODESolver
 //! @{
 
@@ -39,44 +82,38 @@ class NonlinearSolver;
  */
 template<typename Matrix, typename Vector>
 class NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Newton> final
+        : public NonlinearSolverBase<Matrix, Vector>
 {
 public:
     //! Type of the nonlinear equation system to be solved.
     using System = NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Newton>;
+    using LinearSolver = MathLib::LinearSolver<Matrix, Vector>;
 
     /*! Constructs a new instance.
      *
+     * \param linear_solver the linear solver used by this nonlinear solver.
      * \param tol     the tolerance of the solver. \todo Be more specific about that!
      * \param maxiter the maximum number of iterations used to solve the equation.
      */
     explicit
-    NonlinearSolver(double const tol, const unsigned maxiter)
-        : _tol(tol)
+    NonlinearSolver(LinearSolver& linear_solver,
+                    double const tol, const unsigned maxiter)
+        : _linear_solver(linear_solver)
+        , _tol(tol)
         , _maxiter(maxiter)
     {}
 
-    /*! Only assemble the equation system.
-     *
-     * \note This method is needed to preload CrankNicolson time discretization scheme.
-     *       It is not used for the general solver steps; in those only the solve() method
-     *       is needed.
-     *
-     * \param sys the equation system to be assembled.
-     * \param x   the state at which the equation system will be assembled.
-     */
-    void assemble(System& sys, Vector const& x) const;
+    //! Set the nonlinear equation system that will be solved.
+    void setEquationSystem(System& eq) { _equation_system = &eq; }
 
-    /*! Assemble and solve the equation system.
-     *
-     * \param sys the equation system to be solved.
-     * \param x   in: the initial guess, out: the solution.
-     *
-     * \retval true if the equation system could be solved
-     * \retval false otherwise
-     */
-    bool solve(System& sys, Vector& x);
+    void assemble(Vector const& x) const override;
+
+    bool solve(Vector& x) override;
 
 private:
+    LinearSolver& _linear_solver;
+    System*       _equation_system = nullptr;
+
     const double _tol;       //!< tolerance of the solver
     const unsigned _maxiter; //!< maximum number of iterations
 
@@ -95,44 +132,38 @@ private:
  */
 template<typename Matrix, typename Vector>
 class NonlinearSolver<Matrix, Vector, NonlinearSolverTag::Picard> final
+        : public NonlinearSolverBase<Matrix, Vector>
 {
 public:
     //! Type of the nonlinear equation system to be solved.
     using System = NonlinearSystem<Matrix, Vector, NonlinearSolverTag::Picard>;
+    using LinearSolver = MathLib::LinearSolver<Matrix, Vector>;
 
     /*! Constructs a new instance.
      *
+     * \param linear_solver the linear solver used by this nonlinear solver.
      * \param tol     the tolerance of the solver. \todo Be more specific about that!
      * \param maxiter the maximum number of iterations used to solve the equation.
      */
     explicit
-    NonlinearSolver(double const tol, const unsigned maxiter)
-        : _tol(tol)
+    NonlinearSolver(LinearSolver& linear_solver,
+                    double const tol, const unsigned maxiter)
+        : _linear_solver(linear_solver)
+        , _tol(tol)
         , _maxiter(maxiter)
     {}
 
-    /*! Only assemble the equation system.
-     *
-     * \note This method is needed to preload CrankNicolson time discretization scheme.
-     *       It is not used for the general solver steps; in those only the solve() method
-     *       is needed.
-     *
-     * \param sys the equation system to be assembled.
-     * \param x   the state at which the equation system will be assembled.
-     */
-    void assemble(System& sys, Vector const& x) const;
+    //! Set the nonlinear equation system that will be solved.
+    void setEquationSystem(System& eq) { _equation_system = &eq; }
 
-    /*! Assemble and solve the equation system.
-     *
-     * \param sys the equation system to be solved.
-     * \param x   in: the initial guess, out: the solution.
-     *
-     * \retval true if the equation system could be solved
-     * \retval false otherwise
-     */
-    bool solve(System& sys, Vector& x);
+    void assemble(Vector const& x) const override;
+
+    bool solve(Vector& x) override;
 
 private:
+    LinearSolver& _linear_solver;
+    System*       _equation_system = nullptr;
+
     const double _tol;       //!< tolerance of the solver
     const unsigned _maxiter; //!< maximum number of iterations
 
@@ -141,9 +172,27 @@ private:
     Vector _x_new; //!< \c Vector to store solutions of \f$ A \cdot x = \mathit{rhs} \f$.
 };
 
+/*! Creates a new nonlinear solver from the given configuration.
+ *
+ * \param linear_solver the linear solver that will be used by the nonlinear
+ *        solver
+ * \param config configuration settings
+ *
+ * \return a pair <tt>(nl_slv, tag)</tt> where \c nl_slv is the generated
+ *         nonlinear solver instance and the \c tag indicates if it uses the
+ *         Picard or Newton-Raphson method
+ */
+template<typename Matrix, typename Vector>
+std::pair<
+    std::unique_ptr<NonlinearSolverBase<Matrix, Vector> >,
+    NonlinearSolverTag
+>
+createNonlinearSolver(MathLib::LinearSolver<Matrix, Vector>& linear_solver,
+                      BaseLib::ConfigTree const& config);
+
 //! @}
 
-}
+} // namespace NumLib
 
 #include "NonlinearSolver-impl.h"