diff --git a/dumux/implicit/staggered/matrixconverter.hh b/dumux/implicit/staggered/matrixconverter.hh
new file mode 100644
index 0000000000000000000000000000000000000000..c967cf87027b2ce29f0984326d49f28f7462f07c
--- /dev/null
+++ b/dumux/implicit/staggered/matrixconverter.hh
@@ -0,0 +1,188 @@
+// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+// vi: set et ts=4 sw=4 sts=4:
+/*****************************************************************************
+ *   See the file COPYING for full copying permissions.                      *
+ *                                                                           *
+ *   This program is free software: you can redistribute it and/or modify    *
+ *   it under the terms of the GNU General Public License as published by    *
+ *   the Free Software Foundation, either version 2 of the License, or       *
+ *   (at your option) any later version.                                     *
+ *                                                                           *
+ *   This program is distributed in the hope that it will be useful,         *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of          *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the            *
+ *   GNU General Public License for more details.                            *
+ *                                                                           *
+ *   You should have received a copy of the GNU General Public License       *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   *
+ *****************************************************************************/
+/*!
+ * \file
+ * \brief A 2p1cni specific controller for the newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the newton method to abort quicker if the solution is
+ * way out of bounds.
+ */
+#ifndef DUMUX_MATRIX_CONVERTER
+#define DUMUX_MATRIX_CONVERTER
+
+#include "properties.hh"
+
+#include <dumux/nonlinear/newtoncontroller.hh>
+#include <dumux/linear/linearsolveracceptsmultitypematrix.hh>
+#include "newtonconvergencewriter.hh"
+#include <dune/common/tupleutility.hh>
+
+namespace Dumux {
+
+/*!
+ * \ingroup PNMModel
+ * \brief A PNM specific controller for the newton solver.
+ *
+ * This controller 'knows' what a 'physically meaningful' solution is
+ * which allows the newton method to abort quicker if the solution is
+ * way out of bounds.
+ */
+
+template <class MultiTypeBlockMatrix, class Scalar=double>
+class MatrixConverter
+{
+    using MatrixBlock = typename Dune::FieldMatrix<Scalar, 1, 1>;
+    using BCRSMatrix = typename Dune::BCRSMatrix<MatrixBlock>;
+
+public:
+
+    // copy the matrix and the vector to types the IterativeSolverBackend can handle
+    static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
+    {
+        // get the number of rows for the converted matrix
+        const auto numRows = getNumRows_(A);
+
+        auto M = BCRSMatrix(numRows, numRows, BCRSMatrix::random);
+
+        setOccupationPattern_(M, A);
+        copyValues_(M, A);
+
+        return M;
+    }
+
+private:
+
+    /*!
+     * \brief Sets the occupation pattern (i.e. indices) for the converted matrix
+     *
+     * \param M The converted matrix
+     * \param A The original subMatrix of the multitype blockmatrix
+     */
+    static void setOccupationPattern_(BCRSMatrix& M, const MultiTypeBlockMatrix& A)
+    {
+        // set the rowsizes
+        const auto numRows = M.N();
+        Dune::MatrixIndexSet occupationPattern;
+        occupationPattern.resize(numRows, numRows);
+
+        // lambda function to fill the occupation pattern
+        auto addIndices = [&occupationPattern](const auto& subMatrix, const std::size_t startRow, const std::size_t startCol)
+        {
+            using BlockType = typename std::decay_t<decltype(subMatrix)>::block_type;
+            const auto blockSizeI = BlockType::rows;
+            const auto blockSizeJ = BlockType::cols;
+            for(auto row = subMatrix.begin(); row != subMatrix.end(); ++row)
+                for(auto col = row->begin(); col != row->end(); ++col)
+                    for(std::size_t i = 0; i < blockSizeI; ++i)
+                        for(std::size_t j = 0; j < blockSizeJ; ++j)
+                            occupationPattern.add(startRow + row.index()*blockSizeI + i, startCol + col.index()*blockSizeJ + j);
+        };
+
+        int rowIndex = 0;
+        Dune::Hybrid::forEach(A, [&addIndices, &rowIndex, &occupationPattern, numRows](const auto& rowOfMultiTypeMatrix)
+        {
+            int colIndex = 0;
+            Dune::Hybrid::forEach(rowOfMultiTypeMatrix, [&addIndices, &occupationPattern, &colIndex, &rowIndex, numRows](const auto& subMatrix)
+            {
+                addIndices(subMatrix, rowIndex, colIndex);
+
+                const auto numEq = std::decay_t<decltype(subMatrix)>::block_type::cols;
+                colIndex += numEq*subMatrix.M();
+
+                // if we arrived at the right side of the matrix, increase the row index
+                if(colIndex == numRows)
+                    rowIndex += numEq*subMatrix.N();
+            });
+        });
+
+        occupationPattern.exportIdx(M);
+    }
+
+    /*!
+     * \brief Sets the occupation pattern (i.e. indices) for the converted matrix
+     *
+     * \param M The converted matrix
+     * \param A The original subMatrix of the multitype blockmatrix
+     */
+    static void copyValues_(BCRSMatrix& M, const MultiTypeBlockMatrix& A)
+    {
+        // set the rowsizes
+        const auto numRows = M.N();
+
+        // lambda function to copy the values
+        auto copyValues = [&M](const auto& subMatrix, const std::size_t startRow, const std::size_t startCol)
+        {
+            using BlockType = typename std::decay_t<decltype(subMatrix)>::block_type;
+            const auto blockSizeI = BlockType::rows;
+            const auto blockSizeJ = BlockType::cols;
+            for (auto row = subMatrix.begin(); row != subMatrix.end(); ++row)
+                for (auto col = row->begin(); col != row->end(); ++col)
+                    for (std::size_t i = 0; i < blockSizeI; ++i)
+                        for (std::size_t j = 0; j < blockSizeJ; ++j)
+                            M[startRow + row.index()*blockSizeI + i][startCol + col.index()*blockSizeJ + j] = subMatrix[row.index()][col.index()][i][j];
+
+        };
+
+        int rowIndex = 0;
+        Dune::Hybrid::forEach(A, [&copyValues, &rowIndex, numRows](const auto& rowOfMultiTypeMatrix)
+        {
+            int colIndex = 0;
+            Dune::Hybrid::forEach(rowOfMultiTypeMatrix, [&copyValues, &colIndex, &rowIndex, numRows](const auto& subMatrix)
+            {
+                copyValues(subMatrix, rowIndex, colIndex);
+
+                const auto numEq = std::decay_t<decltype(subMatrix)>::block_type::cols;
+                colIndex += numEq*subMatrix.M();
+
+                // if we arrived at the right side of the matrix, increase the row index
+                if(colIndex == numRows)
+                    rowIndex += numEq*subMatrix.N();
+            });
+        });
+    }
+
+    /*!
+     * \brief Calculates the total number of rows (== number of cols) for the converted matrix, assuming a block size of one
+     *
+     * \param A The original multitype blockmatrix
+     */
+    static std::size_t getNumRows_(const MultiTypeBlockMatrix& A)
+    {
+        // problem-agnostic version
+        std::size_t numRows = 0;
+        Dune::Hybrid::forEach(A[Dune::Indices::_0], [&numRows](const auto& subMatrixInFirstRow)
+        {
+            // std::cout << "in matrix of first row:\n";
+            // std::cout << "numRows: " << subMatrixInFirstRow.N() << ", numCols: " << subMatrixInFirstRow.M() << std::endl;
+
+            // The number of rows of the individual submatrice's block equals the respective number of equations.
+            const auto numEq = std::decay_t<decltype(subMatrixInFirstRow)>::block_type::cols; // TODO: is this allways correct?
+            numRows += numEq * subMatrixInFirstRow.M();
+            // std::cout << "numEq: " << numEq << std::endl;
+            // std::cout << "totalNumRows: " << numRows  << std::endl;
+        });
+
+        return numRows;
+    }
+
+};
+}
+
+#endif
diff --git a/dumux/implicit/staggered/newtoncontroller.hh b/dumux/implicit/staggered/newtoncontroller.hh
index edb72ac64eac1940448e25f4fcde986658c358d1..6e964fc76854de033ccad4c18530e020e6c80b1a 100644
--- a/dumux/implicit/staggered/newtoncontroller.hh
+++ b/dumux/implicit/staggered/newtoncontroller.hh
@@ -33,6 +33,10 @@
 #include <dumux/linear/linearsolveracceptsmultitypematrix.hh>
 #include "newtonconvergencewriter.hh"
 
+#include "matrixconverter.hh"
+
+#include <dune/common/tupleutility.hh>
+
 namespace Dumux {
 
 namespace Properties
@@ -53,6 +57,7 @@ namespace Properties
  * which allows the newton method to abort quicker if the solution is
  * way out of bounds.
  */
+
 template <class TypeTag>
 class StaggeredNewtonController : public NewtonController<TypeTag>
 {
@@ -77,6 +82,75 @@ public:
         : ParentType(problem)
     {}
 
+
+    auto createMatrix(JacobianMatrix &A)
+    {
+        // copy the matrix and the vector to types the IterativeSolverBackend can handle
+
+        using MatrixBlock = typename Dune::FieldMatrix<Scalar, 1, 1>;
+        using SparseMatrix = typename Dune::BCRSMatrix<MatrixBlock>;
+
+        // problem-agnostic version
+        std::size_t numRows = 0;
+        Dune::Hybrid::forEach(A[Dune::Indices::_0], [&numRows](const auto& subMatrixInFirstRow)
+        {
+            std::cout << "in matrix of first row:\n";
+            std::cout << "numRows: " << subMatrixInFirstRow.N() << ", numCols: " << subMatrixInFirstRow.M() << std::endl;
+
+            // The number of rows of the individual submatrice's block equals the respective number of equations.
+            const auto numEq = std::decay_t<decltype(subMatrixInFirstRow)>::block_type::rows; // TODO: is this allways correct?
+            numRows += numEq * subMatrixInFirstRow.M();
+        });
+
+        // /*const std::size_t*/ numRows = this->model_().numCellCenterDofs()*numEqCellCenter + this->model_().numFaceDofs()*numEqFace;
+
+
+        // set the rowsizes
+        Dune::MatrixIndexSet occupationPattern;
+        occupationPattern.resize(numRows, numRows);
+
+        // lambda function to fill the occupation pattern
+        auto addIndices = [&occupationPattern](const auto& subMatrix, const std::size_t startRow, const std::size_t startCol)
+        {
+            using BlockType = typename std::decay_t<decltype(subMatrix)>::block_type;
+            const auto blockSizeI = BlockType::rows;
+            const auto blockSizeJ = BlockType::cols;
+            for(auto row = subMatrix.begin(); row != subMatrix.end(); ++row)
+                for(auto col = row->begin(); col != row->end(); ++col)
+                    for(std::size_t i = 0; i < blockSizeI; ++i)
+                        for(std::size_t j = 0; j < blockSizeJ; ++j)
+                            occupationPattern.add(startRow + row.index()*blockSizeI + i, startCol + col.index()*blockSizeJ + j);
+
+        };
+
+
+        int rowIndex = 0;
+
+        Dune::Hybrid::forEach(A, [&rowIndex, &addIndices, numRows](const auto& rowOfMultiTypeMatrix)
+        {
+            int colIndex = 0;
+
+            std::cout << "processing one row of multitypeblockmatrix " << std::endl;
+            Dune::Hybrid::forEach(rowOfMultiTypeMatrix, [&colIndex, &addIndices, &rowIndex, numRows](const auto& subMatrix)
+            {
+                std::cout << "numRows: " << subMatrix.N() << ", numCols: " << subMatrix.M() << std::endl;
+                addIndices(subMatrix, rowIndex, colIndex);
+
+                const auto numEq = std::decay_t<decltype(subMatrix)>::block_type::rows;
+                colIndex += numEq*subMatrix.M();
+
+                // if we arrived at the right side of the matrix, increase the row index
+                if(colIndex == numRows)
+                    rowIndex += numEq*subMatrix.N();
+            });
+        });
+
+        auto M = SparseMatrix(numRows, numRows, SparseMatrix::random);
+        occupationPattern.exportIdx(M);
+
+        return M;
+    }
+
     /*!
      * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$.
      *
@@ -96,6 +170,7 @@ public:
                       SolutionVector &x,
                       SolutionVector &b)
     {
+        // createMatrix(A);
         try
         {
             if (this->numSteps_ == 0)
@@ -115,75 +190,7 @@ public:
             assert(numRows == numCols);
 
             // create the bcrs matrix the IterativeSolver backend can handle
-            auto M = SparseMatrix(numRows, numCols, SparseMatrix::random);
-
-            // set the rowsizes
-            // A11 and A12
-            for (auto row = A[cellCenterIdx][cellCenterIdx].begin(); row != A[cellCenterIdx][cellCenterIdx].end(); ++row)
-                for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                    M.setrowsize(numEqCellCenter*row.index() + i, row->size()*numEqCellCenter);
-            for (auto row = A[cellCenterIdx][faceIdx].begin(); row != A[cellCenterIdx][faceIdx].end(); ++row)
-                for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                    M.setrowsize(numEqCellCenter*row.index() + i, M.getrowsize(numEqCellCenter*row.index() + i) + row->size()*numEqFace);
-            // A21 and A22
-            for (auto row = A[faceIdx][cellCenterIdx].begin(); row != A[faceIdx][cellCenterIdx].end(); ++row)
-                for (std::size_t i = 0; i < numEqFace; ++i)
-                    M.setrowsize(numEqFace*row.index() + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter, row->size()*numEqCellCenter);
-            for (auto row = A[faceIdx][faceIdx].begin(); row != A[faceIdx][faceIdx].end(); ++row)
-                for (std::size_t i = 0; i < numEqFace; ++i)
-                    M.setrowsize(numEqFace*row.index() + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter, M.getrowsize(numEqFace*row.index() + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter) + row->size()*numEqFace);
-            M.endrowsizes();
-
-            // set the indices
-            for (auto row = A[cellCenterIdx][cellCenterIdx].begin(); row != A[cellCenterIdx][cellCenterIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                        for (std::size_t j = 0; j < numEqCellCenter; ++j)
-                            M.addindex(row.index()*numEqCellCenter + i, col.index()*numEqCellCenter + j);
-
-            for (auto row = A[cellCenterIdx][faceIdx].begin(); row != A[cellCenterIdx][faceIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                        for (std::size_t j = 0; j < numEqFace; ++j)
-                            M.addindex(row.index()*numEqCellCenter + i, col.index()*numEqFace + j + A[cellCenterIdx][cellCenterIdx].M()*numEqCellCenter);
-
-            for (auto row = A[faceIdx][cellCenterIdx].begin(); row != A[faceIdx][cellCenterIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqFace; ++i)
-                        for (std::size_t j = 0; j < numEqCellCenter; ++j)
-                            M.addindex(row.index()*numEqFace + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter, col.index()*numEqCellCenter + j);
-
-            for (auto row = A[faceIdx][faceIdx].begin(); row != A[faceIdx][faceIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqFace; ++i)
-                        for (std::size_t j = 0; j < numEqFace; ++j)
-                            M.addindex(row.index()*numEqFace + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter, col.index()*numEqFace + j + A[cellCenterIdx][cellCenterIdx].M()*numEqCellCenter);
-            M.endindices();
-
-            // copy values
-            for (auto row = A[cellCenterIdx][cellCenterIdx].begin(); row != A[cellCenterIdx][cellCenterIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                        for (std::size_t j = 0; j < numEqCellCenter; ++j)
-                            M[row.index()*numEqCellCenter + i][col.index()*numEqCellCenter + j] = A[cellCenterIdx][cellCenterIdx][row.index()][col.index()][i][j];
-
-            for (auto row = A[cellCenterIdx][faceIdx].begin(); row != A[cellCenterIdx][faceIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqCellCenter; ++i)
-                        for (std::size_t j = 0; j < numEqFace; ++j)
-                            M[row.index()*numEqCellCenter + i][col.index()*numEqFace + j + A[cellCenterIdx][cellCenterIdx].M()*numEqCellCenter] = A[cellCenterIdx][faceIdx][row.index()][col.index()][i][j];
-
-            for (auto row = A[faceIdx][cellCenterIdx].begin(); row != A[faceIdx][cellCenterIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqFace; ++i)
-                        for (std::size_t j = 0; j < numEqCellCenter; ++j)
-                            M[row.index()*numEqFace + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter][col.index()*numEqCellCenter + j] = A[faceIdx][cellCenterIdx][row.index()][col.index()][i][j];
-
-            for (auto row = A[faceIdx][faceIdx].begin(); row != A[faceIdx][faceIdx].end(); ++row)
-                for (auto col = row->begin(); col != row->end(); ++col)
-                    for (std::size_t i = 0; i < numEqFace; ++i)
-                        for (std::size_t j = 0; j < numEqFace; ++j)
-                            M[row.index()*numEqFace + i + A[cellCenterIdx][cellCenterIdx].N()*numEqCellCenter][col.index()*numEqFace + j + A[cellCenterIdx][cellCenterIdx].M()*numEqCellCenter] = A[faceIdx][faceIdx][row.index()][col.index()][i][j];
+            const auto M = MatrixConverter<JacobianMatrix>::multiTypeToBCRSMatrix(A);
 
             // create the vector the IterativeSolver backend can handle
             using VectorBlock = typename Dune::FieldVector<Scalar, 1>;
@@ -202,7 +209,7 @@ public:
             // printmatrix(std::cout, M, "", "");
 
             // solve
-            bool converged = this->linearSolver_.solve(M, y, bTmp);
+            const bool converged = this->linearSolver_.solve(M, y, bTmp);
 
             // copy back the result y into x
             for (std::size_t i = 0; i < x[cellCenterIdx].N(); ++i)