diff --git a/dune/solvers/iterationsteps/projectedlinegsstep.cc b/dune/solvers/iterationsteps/projectedlinegsstep.cc
new file mode 100755
index 0000000000000000000000000000000000000000..91c2e930006e4ba35724cb8db3895da869ecf67c
--- /dev/null
+++ b/dune/solvers/iterationsteps/projectedlinegsstep.cc
@@ -0,0 +1,231 @@
+#include <dune/istl/scaledidmatrix.hh>
+
+#include <dune/solvers/iterationsteps/projectedblockgsstep.hh>
+
+template<class MatrixType, class VectorType, class BitVectorType>
+void ProjectedLineGSStep<MatrixType, VectorType, BitVectorType >::
+solveLocalSystem(const Dune::BTDMatrix<typename MatrixType::block_type>& matrix,
+                 VectorType& x,
+                 const VectorType& rhs,
+                 const std::vector<BoxConstraint<field_type,BlockSize> >& localObstacles) const
+{
+    typedef Dune::BTDMatrix<typename MatrixType::block_type> LocalMatrixType;
+
+    // ///////////////////////////
+    //   Set initial iterate
+    //   Make rhs the initial iterate: it already contains the correct Dirichlet values.
+    //   The rest doesn't matter
+    // ///////////////////////////
+    x = rhs;
+
+    
+    // //////////////////////////////////////
+    //   The TNNMG loop
+    // //////////////////////////////////////
+
+    // stupid:
+    Dune::BitSetVector<1> hasObstacle(rhs.size(), true);
+    // The nodes to ignore are already written into the matrix/rhs
+    Dune::BitSetVector<1> ignoreNodes(rhs.size(), false);
+
+    do {
+        
+        // ///////////////////////////
+        //   Nonlinear presmoothing
+        // ///////////////////////////
+        VectorType rhsCopy = rhs;  // need a non-const version of rhs
+        
+        ProjectedBlockGSStep<LocalMatrixType, VectorType> nonlinearSmootherStep(matrix, x, rhsCopy);
+
+        nonlinearSmootherStep.ignoreNodes_ = &ignoreNodes;
+        nonlinearSmootherStep.hasObstacle_ = &hasObstacle;
+        nonlinearSmootherStep.obstacles_   = &localObstacles;
+
+        for (int i=0; i<3; i++)
+            nonlinearSmootherStep.iterate();
+        
+        // Compute residual
+        VectorType residual = rhs;
+        matrix.mmv(x,residual);
+        
+        // ///////////////////////////
+        //   Truncation
+        // ///////////////////////////
+        
+        // ///////////////////////////
+        //   Linear correction
+        // ///////////////////////////
+        
+        VectorType corr(residual.size());
+        matrix.solve(corr, residual);   // the direct linear solution algorithm
+        
+        // //////////////////////////////////////////////////////////
+        //   Line search in the direction of the projected coarse
+        //   grid correction to ensure monotonicity.
+        // //////////////////////////////////////////////////////////
+        
+        // L2-projection of the correction onto the defect obstacle
+        for (int i=0; i<corr.size(); i++) {
+            
+            for (int j=0; j<BlockSize; j++) {
+                
+                corr[i][j] = std::max(corr[i][j], localObstacles[i].lower(j) - x[i][j]);
+                corr[i][j] = std::min(corr[i][j], localObstacles[i].upper(j) - x[i][j]);
+                
+            }
+            
+        }
+        
+        // Construct obstacles in the direction of the projected correction
+        BoxConstraint<field_type,1> lineSearchObs;
+        for (int i=0; i<corr.size(); i++) {
+            
+            for (int j=0; j<BlockSize; j++) {
+                
+                if (corr[i][j] > 0) {
+                    
+                    // This division can cause nan on some platforms...
+                    if (!isnan( (localObstacles[i].lower(j)-x[i][j]) / corr[i][j]) )
+                        lineSearchObs.lower(0) = std::max(lineSearchObs.lower(0),
+                                                          (localObstacles[i].lower(j)-x[i][j]) / corr[i][j]);
+                    
+                    if (!isnan( (localObstacles[i].upper(j)-x[i][j]) / corr[i][j]) )
+                        lineSearchObs.upper(0) = std::min(lineSearchObs.upper(0), 
+                                                          (localObstacles[i].upper(j)-x[i][j]) / corr[i][j]);
+                }
+                
+                if (corr[i][j] < 0) {
+                    if (!isnan( (localObstacles[i].upper(j)-x[i][j]) / corr[i][j]) )
+                        lineSearchObs.lower(0) = std::max(lineSearchObs.lower(0), 
+                                                          (localObstacles[i].upper(j)-x[i][j]) / corr[i][j]);
+                    if (!isnan( (localObstacles[i].lower(j)-x[i][j]) / corr[i][j]) )
+                        lineSearchObs.upper(0) = std::min(lineSearchObs.upper(0), 
+                                                          (localObstacles[i].lower(j)-x[i][j]) / corr[i][j]);
+                }
+                
+            }
+            
+        }
+
+        // abort when the linear correction has a small norm
+        field_type correctionNormSquared = EnergyNorm<LocalMatrixType,VectorType>::normSquared(corr,matrix);
+        
+        // If the correction is very small we may leave the loop here
+        // A relative criterion may be more appropriate here
+        if (correctionNormSquared < 1e-10)
+            break;
+
+        // Line search
+        field_type alpha = (residual*corr) / correctionNormSquared;
+        alpha = std::max(std::min(alpha, lineSearchObs.upper(0)), lineSearchObs.lower(0));
+        
+        // Even if the correction has a large norm the scaled norm may be small.
+        // A relative criterion may be more appropriate here
+        if (alpha*correctionNormSquared < 1e-10)
+            break;
+
+        // add scaled correction
+        x.axpy(alpha,corr);
+
+    } while (true);
+
+}
+
+
+
+template<class MatrixType, class VectorType, class BitVectorType>
+void ProjectedLineGSStep<MatrixType, VectorType, BitVectorType>::iterate()
+{
+
+    // input of this method: x^(k) (not the permuted version of x^(k)!)
+
+    const MatrixType& matrix = *this->mat_;
+
+    int number_of_blocks = this->blockStructure_.size();
+
+    // iterate over the blocks
+    for (int b_num=0; b_num < number_of_blocks; b_num++ ) {
+
+        const int current_block_size = this->blockStructure_[b_num].size();
+
+        //! compute and save the residuals for the curent block: 
+        // determine the (permuted) residuals r[p(i)],..., r[p(i+current_block_size-1)]
+        // this means that we determine the residuals for the current block
+        VectorType permuted_r_i(current_block_size);
+        for (int k=0; k<current_block_size; k++)
+          {
+           if ( (*this->ignoreNodes_)[this->blockStructure_[b_num][k]][0])
+               permuted_r_i[k] = 0.0;
+           else
+               residual( this->blockStructure_[b_num][k], permuted_r_i[k]); // get r[p(i+k)]
+          }
+        // permuted_r_i[k] is the residual for r[p(i+k)], which means the residual \tilde{r}[i+k]
+        // note: calling the method 'residual' with the permuted index implies that there is no additional permutation required within 'residual'
+
+        // permuted_v_i is for saving the correction for x[p(i)],..., x[p(i+current_block_size-1)]:
+        VectorType permuted_v_i(current_block_size); // permuted_v_i[k] = v[p(i+k)]
+        // (Later: x_now[p(i+k)] = x_now[p(i+k)] + v[p(i+k)] )
+
+        // //////////////////////////////////////////////////////////////////////////////////////////////////
+        // Copy the linear system for the current line/block into a tridiagonal matrix 
+        // //////////////////////////////////////////////////////////////////////////////////////////////////
+
+        Dune::BTDMatrix<typename MatrixType::block_type> tridiagonalMatrix(current_block_size);
+
+        for (int j=0; j<current_block_size; j++) {
+
+            if ( (*this->ignoreNodes_)[this->blockStructure_[b_num][j]][0] ) {
+
+                // left off-diagonal:
+                if (j>0)
+                    tridiagonalMatrix[j][j-1] = 0;
+                
+                // diagonal
+                tridiagonalMatrix[j][j] = Dune::ScaledIdentityMatrix<field_type,BlockSize>(1);
+                
+                // left off-diagonal:
+                if (j<current_block_size-1)
+                    tridiagonalMatrix[j][j+1] = 0;
+
+            } else {
+
+                // left off-diagonal:
+                if (j>0)
+                    tridiagonalMatrix[j][j-1] = matrix[this->blockStructure_[b_num][j]][this->blockStructure_[b_num][j-1]];
+                
+                // diagonal
+                tridiagonalMatrix[j][j] = matrix[this->blockStructure_[b_num][j]][this->blockStructure_[b_num][j]];
+                
+                // left off-diagonal:
+                if (j<current_block_size-1)
+                    tridiagonalMatrix[j][j+1] = matrix[this->blockStructure_[b_num][j]][this->blockStructure_[b_num][j+1]];
+
+            }
+
+        }
+
+        // ///////////////////////////////////////////////////////////////////
+        //   Get the local set of obstacles for this block
+        // ///////////////////////////////////////////////////////////////////
+
+        std::vector<BoxConstraint<field_type,BlockSize> > localDefectConstraints(current_block_size);
+
+        for (int j=0; j<current_block_size; j++) {
+            localDefectConstraints[j] = (*obstacles_)[this->blockStructure_[b_num][j]];
+            localDefectConstraints[j] -= (*this->x_)[this->blockStructure_[b_num][j]];
+        }
+
+        // ////////////////////////////////////////
+        //   Solve the tridiagonal system
+        // ////////////////////////////////////////
+        this->solveLocalSystem(tridiagonalMatrix, permuted_v_i, permuted_r_i, localDefectConstraints);
+
+        // //////////////////////////////////////////////////////////////////////
+        //   Add the correction to the current iterate
+        // //////////////////////////////////////////////////////////////////////
+       for (int k=0; k<current_block_size; k++)
+           (*this->x_)[this->blockStructure_[b_num][k]] += permuted_v_i[k];
+
+    }
+
+}
diff --git a/dune/solvers/iterationsteps/projectedlinegsstep.hh b/dune/solvers/iterationsteps/projectedlinegsstep.hh
new file mode 100755
index 0000000000000000000000000000000000000000..2cd0c74bd8f91e3a00586ae0d9947c3ecf229f68
--- /dev/null
+++ b/dune/solvers/iterationsteps/projectedlinegsstep.hh
@@ -0,0 +1,49 @@
+#ifndef DUNE_PROJECTED_LINE_GAUSS_SEIDEL_STEP_HH
+#define DUNE_PROJECTED_LINE_GAUSS_SEIDEL_STEP_HH
+
+#include <dune/common/bitsetvector.hh>
+
+#include <dune/istl/btdmatrix.hh>
+
+#include <dune/solvers/boxconstraint.hh>
+#include <dune/solvers/iterationsteps/linegsstep.hh>
+
+template<class MatrixType,
+         class VectorType,
+         class BitVectorType = Dune::BitSetVector<VectorType::block_type::dimension> >
+class ProjectedLineGSStep : public LineGSStep<MatrixType, VectorType, BitVectorType>
+{
+    
+    typedef typename VectorType::block_type VectorBlock;
+    
+    typedef typename VectorType::field_type field_type;
+    
+    enum {BlockSize = VectorBlock::dimension};
+    
+public:
+    
+    //! Default constructor.  Doesn't init anything
+    ProjectedLineGSStep() {}
+    
+    //! Constructor for usage of Permutation Manager
+    ProjectedLineGSStep( const std::vector<std::vector<unsigned int> >& blockStructure)
+        : LineGSStep<MatrixType, VectorType, BitVectorType>( blockStructure )
+    {}
+    
+    /** \brief Solve one tridiagonal system */
+    void solveLocalSystem(const Dune::BTDMatrix<typename MatrixType::block_type>& matrix,
+                          VectorType& x,
+                          const VectorType& rhs,
+                          const std::vector<BoxConstraint<field_type,BlockSize> >& localObstacles) const;
+    
+    //! Perform one iteration
+    virtual void iterate();
+    
+    const std::vector<BoxConstraint<field_type,BlockSize> >* obstacles_;
+    
+};
+
+
+#include "projectedlinegsstep.cc"
+
+#endif