diff --git a/dune/solvers/solvers/quadraticipopt.hh b/dune/solvers/solvers/quadraticipopt.hh
index 621e2928d1b045f845214e560fdb49f9bf4fddb1..76bb1d7056dd1a10dfbc096c93707db2f7ec88ec 100644
--- a/dune/solvers/solvers/quadraticipopt.hh
+++ b/dune/solvers/solvers/quadraticipopt.hh
@@ -129,7 +129,7 @@ private:
 template <class MatrixType, class VectorType>
 bool QuadraticIPOptProblem<MatrixType,VectorType>::
 get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
-             Ipopt::Index& nnz_h_lag, IndexStyleEnum& index_style)
+             Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style)
 {
     // Number of variables
     n = x_->dim();
@@ -186,7 +186,7 @@ get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
     // here, the n and m we gave IPOPT in get_nlp_info are passed back to us.
     // If desired, we could assert to make sure they are what we think they are.
     assert(n == (Ipopt::Index)x_->dim());
-    assert(m == 0);
+    //assert(m == 0);
 
     if (obstacles_) {
 
@@ -461,9 +461,234 @@ finalize_solution(Ipopt::SolverReturn status,
 
 }
 
+/** \brief Implementation class used to pipe quadratic problems to
+    the IPOpt interior-point solver
+*/
+template <class MatrixType, class VectorType>
+class QuadraticIPOptObstacleProblem : public QuadraticIPOptProblem<MatrixType, VectorType>
+{
+     enum {blocksize = VectorType::block_type::dimension};
+
+    typedef typename VectorType::field_type field_type;
+    typedef QuadraticIPOptProblem<MatrixType, VectorType> Base;
+
+public:
+  /** default constructor */
+    QuadraticIPOptObstacleProblem(const MatrixType* hessian, VectorType* x, const VectorType* rhs,
+                          const Dune::BitSetVector<blocksize>* dirichletNodes,
+                          std::vector<BoxConstraint<field_type, blocksize> >* boundObstacles,
+                          const MatrixType* constraintMatrix,
+                          std::vector<BoxConstraint<field_type, blocksize> >* constraintObstacles)
+        : Base(hessian,x,rhs,dirichletNodes,boundObstacles),
+          constraintMatrix_(constraintMatrix), constraintObstacles_(constraintObstacles),
+          jacobianCutoff_(1e-8)
+    {}
+
+  /** default destructor */
+    virtual ~QuadraticIPOptObstacleProblem() {};
+
+ /**@name Overloaded from QuadraticIPOptProblem */
+  //@{
+  /** Method to return some info about the nlp */
+  virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
+                            Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style);
+
+  /** Method to return the bounds for my problem */
+  virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
+                               Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u);
+
+  /** Method to return the constraint residuals */
+  virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Index m, Ipopt::Number* g);
+
+  /** Method to return:
+   *   1) The structure of the jacobian (if "values" is NULL)
+   *   2) The values of the jacobian (if "values" is not NULL)
+   */
+  virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
+                          Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol,
+                          Ipopt::Number* values);
+  //@}
+
+
+  // /////////////////////////////////
+  //   Data
+  // /////////////////////////////////
+
+  const MatrixType* constraintMatrix_;
+
+  std::vector<BoxConstraint<field_type, blocksize> >* constraintObstacles_;
+
+private:
+  const field_type jacobianCutoff_;
+  /**@name Methods to block default compiler methods.
+  */
+  //@{
+  //  QuadraticIPOptObstacleProblem();
+  QuadraticIPOptObstacleProblem(const QuadraticIPOptObstacleProblem&);
+  QuadraticIPOptObstacleProblem& operator=(const QuadraticIPOptObstacleProblem&);
+  //@}
+};
+
+// returns the size of the problem
+template <class MatrixType, class VectorType>
+bool QuadraticIPOptObstacleProblem<MatrixType,VectorType>::
+get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
+             Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style)
+{
+    Base::get_nlp_info(n,m,nnz_jac_g,nnz_h_lag,index_style);
+
+    // We only need the lower left corner of the Hessian (since it is symmetric)
+    if (!constraintMatrix_)
+        DUNE_THROW(SolverError, "No constraint matrix has been supplied!");
+    assert(constraintMatrix_->N()==constraintObstacles_->size());
+
+    // only change the constraint information
+    m = constraintMatrix_->N()*blocksize;
+
+    int numJacobianNonzeros = 0;
+    for (size_t i=0; i<constraintMatrix_->N(); i++) {
+
+        const auto& row = (*constraintMatrix_)[i];
+
+        // dim for entry in the constraint matrix
+        auto cEnd = row.end();
+        for (auto cIt = row.begin(); cIt!=cEnd; cIt++)
+            for (int k=0; k<blocksize; k++)
+                for (int l=0; l<blocksize; l++)
+                    if (std::abs((*cIt)[k][l]) > jacobianCutoff_ )
+                        numJacobianNonzeros++;
+    }
+
+    nnz_jac_g = numJacobianNonzeros;
+
+    return true;
+}
+
+
+// returns the variable bounds
+template <class MatrixType, class VectorType>
+bool QuadraticIPOptObstacleProblem<MatrixType,VectorType>::
+get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
+                Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)
+{
+    Base::get_bounds_info(n,x_l, x_u, m, g_l ,g_u);
+
+    // initialize with large numbers
+    for (int i=0; i<m; i++) {
+        g_l[i] = -std::numeric_limits<field_type>::max();
+        g_u[i] =  std::numeric_limits<field_type>::max();
+    }
+
+    for (size_t i=0; i<constraintObstacles_->size(); i++) {
+        for (int k=0; k<blocksize; k++) {
+
+                g_l[i*blocksize + k] = (*constraintObstacles_)[i].lower(k);
+                g_u[i*blocksize + k] = (*constraintObstacles_)[i].upper(k);
+        }
+    }
+
+    return true;
+}
+
+// Evaluate the constraints
+template <class MatrixType, class VectorType>
+bool QuadraticIPOptObstacleProblem<MatrixType,VectorType>::eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Index m, Ipopt::Number* g)
+{
+
+    for (int i=0; i<m; i++)
+        g[i] = 0;
+
+    int rowCounter = 0;
+    for (size_t rowIdx=0; rowIdx<constraintMatrix_->N(); rowIdx++) {
+
+        const auto& row = (*constraintMatrix_)[rowIdx];
+        auto cIt = row.begin();
+        auto cEnd = row.end();
+
+        // constraintMatrix times x
+        for (; cIt != cEnd; cIt++)
+            for (int l=0; l<blocksize; l++)
+                for (int k=0; k<blocksize; k++)
+                    if ( std::abs((*cIt)[l][k]) > jacobianCutoff_)
+                        g[rowCounter+l] += (*cIt)[l][k] * x[cIt.index()*blocksize+k];
+
+        // increment constraint counter
+        rowCounter += blocksize;
+    }
+
+    return true;
+}
+
+
+// Evaluate gradient of the constraints
+template <class MatrixType, class VectorType>
+bool QuadraticIPOptObstacleProblem<MatrixType,VectorType>::eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
+        Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol,
+        Ipopt::Number* values)
+{
+
+    int idx = 0;
+    int rowCounter = 0;
+
+    // If the values are null then IpOpt wants the sparsity pattern
+    if (values==NULL) {
+
+        for (size_t rowIdx=0; rowIdx<constraintMatrix_->N(); rowIdx++) {
+
+            const auto& row = (*constraintMatrix_)[rowIdx];
+            auto cIt = row.begin();
+            auto cEnd = row.end();
+
+            for (; cIt != cEnd; ++cIt) {
+
+                for (int l=0; l<blocksize; l++)
+                    for (int k=0; k<blocksize; k++)
+                        if ( std::abs((*cIt)[l][k]) > jacobianCutoff_) {
+
+                            iRow[idx] = rowCounter + l;
+                            jCol[idx] = cIt.index()*blocksize+k;
+                            idx++;
+                        }
+            }
+
+            rowCounter += blocksize;
+        }
+
+    // If the values are not null IpOpt wants the evaluated constraints gradient
+    } else {
+
+        for (size_t rowIdx=0; rowIdx<constraintMatrix_->N(); rowIdx++) {
+
+            const auto& row = (*constraintMatrix_)[rowIdx];
+            auto cIt = row.begin();
+            auto cEnd = row.end();
+
+            for (; cIt != cEnd; ++cIt) {
+
+                for (int l=0; l<blocksize; l++)
+                    for (int k=0; k<blocksize; k++)
+                        if ( std::abs((*cIt)[l][k]) > jacobianCutoff_)
+                            values[idx++] = (*cIt)[l][k];
+            }
+
+            rowCounter += blocksize;
+
+        }
+
+    }
+
+    return true;
+}
 
 /** \brief Wraps the IPOpt interior-point solver for quadratic problems with
-    bound constraints.
+ *    linear constraints and bound constraints.
+ *
+ *   The problems that can be solved are of the form
+ *   \f[
+ *       \min_x \frac{1}{2}x^T A x - b^T x
+ *               x_l \leq x \leq x_u
+ *               g_l \leq G x \leq g_u
+ *   \f]
 */
 template <class MatrixType, class VectorType>
 class QuadraticIPOptSolver
@@ -484,7 +709,8 @@ public:
     QuadraticIPOptSolver () : IterativeSolver<VectorType>(1e-8, 100, NumProc::FULL),
                               hessian_(NULL), rhs_(NULL),
                               obstacles_(NULL),
-                              linearSolverType_("ma27")
+                              linearSolverType_("ma27"),
+                              constraintMatrix_(NULL),constraintObstacles_(NULL)
     {}
 
     /** \brief Constructor for a linear problem */
@@ -495,7 +721,8 @@ public:
                        std::string linearSolverType = "ma27")
         : IterativeSolver<VectorType>(1e-8, 100, verbosity),
           hessian_(&hessian), rhs_(&rhs), obstacles_(NULL),
-          linearSolverType_(linearSolverType)
+          linearSolverType_(linearSolverType),
+          constraintMatrix_(NULL),constraintObstacles_(NULL)
     {
         this->x_ = &x;
     }
@@ -508,22 +735,41 @@ public:
         rhs_ = &rhs;
     }
 
+    void setLinearConstraints(const MatrixType& constraintMatrix,
+                    const std::vector<BoxConstraint<field_type,blocksize> >& obstacles) {
+        constraintMatrix_ = &constraintMatrix;
+        constraintObstacles_ = &obstacles;
+    }
+
     virtual void solve();
 
     ///////////////////////////////////////////////////////
     // Data
     ///////////////////////////////////////////////////////
 
+    //! The quadratic term in the quadratic energy, is assumed to be symmetric
     const MatrixType* hessian_;
 
+    //! Vector to store the solution
     VectorType* x_;
 
+    //! The linear term in the quadratic energy
     const VectorType* rhs_;
 
+    //! Vector containing the bound constraints of the variables
+    // Can stay unset when no bound constraints exist
     std::vector<BoxConstraint<field_type,blocksize> >* obstacles_;
 
     //! The type of the linear solver to be used within IpOpt, default is ma27
     std::string linearSolverType_;
+
+    //! IpOpt expects constraints to be of the type g_l <= g(x) <= g_u
+    // Can stay unset when no linear constraints exist
+    std::vector<BoxConstraint<field_type,blocksize> >* constraintObstacles_;
+
+    //! The matrix corresponding to linear constraints
+    // Can stay unset when no linear constraints exist
+    const MatrixType* constraintMatrix_;
 };
 
 template <class MatrixType, class VectorType>
@@ -531,8 +777,13 @@ void QuadraticIPOptSolver<MatrixType,VectorType>::solve()
 {
   // Create a new instance of your nlp
   //  (use a SmartPtr, not raw)
-    Ipopt::SmartPtr<Ipopt::TNLP> mynlp
-        = new QuadraticIPOptProblem<MatrixType,VectorType>(hessian_, x_, rhs_,
+    Ipopt::SmartPtr<Ipopt::TNLP> mynlp;
+    if (constraintMatrix_) {
+        mynlp= new QuadraticIPOptObstacleProblem<MatrixType,VectorType>(hessian_, x_, rhs_,
+                                                           this->ignoreNodes_, obstacles_,
+                                                            constraintMatrix_,constraintObstacles_);
+    } else
+        mynlp= new QuadraticIPOptProblem<MatrixType,VectorType>(hessian_, x_, rhs_,
                                                            this->ignoreNodes_, obstacles_);
 
   // Create a new instance of IpoptApplication
@@ -546,6 +797,13 @@ void QuadraticIPOptSolver<MatrixType,VectorType>::solve()
   app->Options()->SetStringValue("linear_solver",linearSolverType_);
   app->Options()->SetStringValue("output_file", "ipopt.out");
   app->Options()->SetStringValue("hessian_constant", "yes");
+
+  // We only support linear constraints
+  if (constraintMatrix_) {
+    app->Options()->SetStringValue("jac_d_constant","yes");
+    app->Options()->SetStringValue("jac_c_constant","yes");
+  }
+
   switch (this->verbosity_) {
   case NumProc::QUIET:
       app->Options()->SetIntegerValue("print_level", 0);