diff --git a/dumux/freeflow/staggered/model.hh b/dumux/freeflow/staggered/model.hh
index 08ef270ff2b222e8f21f18f2655fbdeac3503700..bae02ce4593f2cb83a42950724429d1270353dd3 100644
--- a/dumux/freeflow/staggered/model.hh
+++ b/dumux/freeflow/staggered/model.hh
@@ -137,7 +137,23 @@ public:
      */
     size_t numDofs() const
     {
-        return this->gridView_().size(0) + this->gridView_().size(1);;
+        return this->gridView_().size(0) + this->gridView_().size(1);
+    }
+
+     /*!
+     * \brief Returns the number of cell center degrees of freedoms (DOFs)
+     */
+    size_t numCellCenterDofs() const
+    {
+        return this->gridView_().size(0);
+    }
+
+     /*!
+     * \brief Returns the number of cell center degrees of freedoms (DOFs)
+     */
+    size_t numFaceDofs() const
+    {
+        return this->gridView_().size(1);
     }
 
     /*!
diff --git a/dumux/implicit/staggered/assembler.hh b/dumux/implicit/staggered/assembler.hh
index 3d9689cbcc76022a1038d15a9a0f5a8ad836086a..e1f528ed885eac6cb7e0c48a1447be76cf2011da 100644
--- a/dumux/implicit/staggered/assembler.hh
+++ b/dumux/implicit/staggered/assembler.hh
@@ -40,11 +40,55 @@ class StaggeredAssembler : public ImplicitAssembler<TypeTag>
     typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
     typedef typename GET_PROP_TYPE(TypeTag, GridView) GridView;
     typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+    typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) JacobianMatrix;
 
     typedef typename GridView::template Codim<0>::Entity Element;
     typedef typename GridView::IndexSet::IndexType IndexType;
 
-    void setRowSizes_()
+    typedef typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockCCToCC CCToCCMatrixBlock;
+    typedef typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockCCToFace CCToFaceMatrixBlock;
+
+    typedef typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockFaceToFace FaceToFaceMatrixBlock;
+    typedef typename GET_PROP(TypeTag, JacobianMatrix)::MatrixBlockFaceToCC FaceToCCMatrixBlock;
+
+    using DofTypeIndices = typename GET_PROP(TypeTag, DofTypeIndices);
+    typename DofTypeIndices::CellCenterIdx cellCenterIdx;
+    typename DofTypeIndices::FaceIdx faceIdx;
+
+    // Construct the multitype matrix for the global jacobian
+    void createMatrix_()
+    {
+        // create the multitype matrix
+        this->matrix_ = std::make_shared<JacobianMatrix>();
+
+        // get sub matrix sizes
+        const auto cellCenterSize = this->problem_().model().numCellCenterDofs();
+        const auto faceSize = this->problem_().model().numFaceDofs();
+
+        // allocate the sub matrices (BCRS matrices)
+        auto A11 = CCToCCMatrixBlock(cellCenterSize, cellCenterSize, CCToCCMatrixBlock::random);
+        auto A12 = CCToFaceMatrixBlock(cellCenterSize, faceSize, CCToFaceMatrixBlock::random);
+
+        auto A21 = FaceToCCMatrixBlock(faceSize, cellCenterSize, FaceToCCMatrixBlock::random);
+        auto A22 = FaceToFaceMatrixBlock(faceSize, faceSize, FaceToFaceMatrixBlock::random);
+
+
+        setRowSizes_(A11, A12, A21, A22);
+        addIndices_(A11, A12, A21, A22);
+
+        (*this->matrix_)[cellCenterIdx][cellCenterIdx] = A11;
+        (*this->matrix_)[cellCenterIdx][faceIdx] = A12;
+        (*this->matrix_)[faceIdx][cellCenterIdx] = A21;
+        (*this->matrix_)[faceIdx][faceIdx] = A22;
+
+        printmatrix(std::cout, A11, "A11", "");
+        printmatrix(std::cout, A12, "A12", "");
+        printmatrix(std::cout, A21, "A21", "");
+        printmatrix(std::cout, A22, "A22", "");
+    }
+
+    void setRowSizes_(CCToCCMatrixBlock &A11, CCToFaceMatrixBlock &A12,
+                      FaceToCCMatrixBlock &A21, FaceToFaceMatrixBlock &A22)
     {
         for (const auto& element : elements(this->gridView_()))
         {
@@ -52,22 +96,27 @@ class StaggeredAssembler : public ImplicitAssembler<TypeTag>
             const auto globalI = this->elementMapper_().index(element);
             const auto& cellCenterToCellCenterStencil = this->model_().stencils(element).cellCenterToCellCenterStencil();
             const auto& cellCenterToFaceStencil = this->model_().stencils(element).cellCenterToFaceStencil();
-            const auto size = cellCenterToCellCenterStencil.size() + cellCenterToFaceStencil.size();
 
-            this->matrix().setrowsize(globalI, size);
+            A11.setrowsize(globalI, cellCenterToCellCenterStencil.size());
+            A12.setrowsize(globalI, cellCenterToFaceStencil.size());
         }
+        A11.endrowsizes();
+        A12.endrowsizes();
 
-        for(int facetIdx = 0; facetIdx < this->gridView_().size(1); ++facetIdx)
+        for(int faceDofxIdx = 0; faceDofxIdx < this->gridView_().size(1); ++faceDofxIdx)
         {
-            const int faceDofxIdx = facetIdx + this->gridView_().size(0);
-            auto size = this->model_().fullFaceToCellCenterStencilSize(facetIdx);
-            size += this->model_().fullfaceToFaceStencilSize(facetIdx);
-            this->matrix().setrowsize(faceDofxIdx, size);
+            const auto faceToCellSize = this->model_().fullFaceToCellCenterStencilSize(faceDofxIdx);
+            const auto faceToFaceSize = this->model_().fullfaceToFaceStencilSize(faceDofxIdx);
+
+            A21.setrowsize(faceDofxIdx, faceToCellSize);
+            A22.setrowsize(faceDofxIdx, faceToFaceSize);
         }
-        this->matrix().endrowsizes();
+        A21.endrowsizes();
+        A22.endrowsizes();
     }
 
-    void addIndices_()
+    void addIndices_(CCToCCMatrixBlock &A11, CCToFaceMatrixBlock &A12,
+                     FaceToCCMatrixBlock &A21, FaceToFaceMatrixBlock &A22)
     {
         for (const auto& element : elements(this->gridView_()))
         {
@@ -78,36 +127,39 @@ class StaggeredAssembler : public ImplicitAssembler<TypeTag>
 
 
             for (auto&& globalJ : cellCenterToCellCenterStencil)
-                this->matrix().addindex(globalI, globalJ);
+                A11.addindex(globalI, globalJ);
             for (auto&& globalJ : cellCenterToFaceStencil)
-                this->matrix().addindex(globalI, globalJ);
+                A12.addindex(globalI, globalJ - this->gridView_().size(0));
         }
+        A11.endindices();
+        A12.endindices();
 
         auto ptr1 = this->model_().getFullFaceToCellCenterStencilsPtr();
         auto ptr2 = this->model_().getFullfaceToFaceStencilsPtr();
 
-        if(ptr1 && ptr2)
-            std::cout << "success!!!" << std::endl;
+        assert((ptr1 && ptr2) && "pointers to full face stencils are empty!");
 
         const auto& fullFaceToCellCenterStencils = ptr1.get()[0];
         const auto& fullfaceToFaceStencils = ptr2.get()[0];
 
-        int globalI = this->gridView_().size(0);
+        int globalI = 0;
         for(const auto& stencil : fullFaceToCellCenterStencils)
         {
             for(auto&& globalJ : stencil)
-            this->matrix().addindex(globalI, globalJ);
+            A21.addindex(globalI, globalJ);
             ++globalI;
         }
-        globalI = this->gridView_().size(0);
+
+        globalI = 0;
         for(const auto& stencil : fullfaceToFaceStencils)
         {
             for(auto&& globalJ : stencil)
-            this->matrix().addindex(globalI, globalJ);
+            A22.addindex(globalI, globalJ - this->gridView_().size(0));
             ++globalI;
         }
 
-        this->matrix().endindices();
+        A21.endindices();
+        A22.endindices();
     }
 
 };
diff --git a/dumux/implicit/staggered/newtoncontroller.hh b/dumux/implicit/staggered/newtoncontroller.hh
new file mode 100644
index 0000000000000000000000000000000000000000..75d750399c7a41e27059cb089431ae37399582f2
--- /dev/null
+++ b/dumux/implicit/staggered/newtoncontroller.hh
@@ -0,0 +1,125 @@
+// -*- 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_STAGGERED_NEWTON_CONTROLLER_HH
+#define DUMUX_STAGGERED_NEWTON_CONTROLLER_HH
+
+#include "properties.hh"
+
+#include <dumux/nonlinear/newtoncontroller.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 TypeTag>
+class StaggeredNewtonController : public NewtonController<TypeTag>
+{
+    typedef NewtonController<TypeTag> ParentType;
+    typedef typename GET_PROP_TYPE(TypeTag, Problem) Problem;
+    typedef typename GET_PROP_TYPE(TypeTag, SolutionVector) SolutionVector;
+    typedef typename GET_PROP_TYPE(TypeTag, JacobianMatrix) JacobianMatrix;
+    typedef typename GET_PROP_TYPE(TypeTag, Scalar) Scalar;
+
+public:
+    StaggeredNewtonController(const Problem &problem)
+        : ParentType(problem)
+    {}
+
+        /*!
+     * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$.
+     *
+     * Throws Dumux::NumericalProblem if the linear solver didn't
+     * converge.
+     *
+     * \param A The matrix of the linear system of equations
+     * \param x The vector which solves the linear system
+     * \param b The right hand side of the linear system
+     */
+    void newtonSolveLinear(JacobianMatrix &A,
+                           SolutionVector &x,
+                           SolutionVector &b)
+    {
+        try {
+            if (this->numSteps_ == 0)
+            {
+                Scalar norm2 = b.two_norm2();
+                if (this->gridView_().comm().size() > 1)
+                    norm2 = this->gridView_().comm().sum(norm2);
+
+                this->initialResidual_ = std::sqrt(norm2);
+            }
+
+            int converged = 1;//this->linearSolver_.solve(A, x, b); //TODO: fix
+
+            // make sure all processes converged
+            int convergedRemote = converged;
+            if (this->gridView_().comm().size() > 1)
+                convergedRemote = this->gridView_().comm().min(converged);
+
+            if (!converged) {
+                DUNE_THROW(NumericalProblem,
+                           "Linear solver did not converge");
+            }
+            else if (!convergedRemote) {
+                DUNE_THROW(NumericalProblem,
+                           "Linear solver did not converge on a remote process");
+            }
+        }
+        catch (Dune::MatrixBlockError e) {
+            // make sure all processes converged
+            int converged = 0;
+            if (this->gridView_().comm().size() > 1)
+                converged = this->gridView_().comm().min(converged);
+
+            Dumux::NumericalProblem p;
+            std::string msg;
+            std::ostringstream ms(msg);
+//             ms << e.what() << "M=" << A[e.r][e.c];
+//             p.message(ms.str());
+//             throw p;
+        }
+        catch (const Dune::Exception &e) {
+            // make sure all processes converged
+            int converged = 0;
+            if (this->gridView_().comm().size() > 1)
+                converged = this->gridView_().comm().min(converged);
+
+            Dumux::NumericalProblem p;
+            p.message(e.what());
+            throw p;
+        }
+    }
+
+};
+}
+
+#endif
diff --git a/dumux/implicit/staggered/properties.hh b/dumux/implicit/staggered/properties.hh
index 73510d65ab1ba9252a7b232c957866f335509b60..bcf6c90cbd0352beebb197b14ae87243db05f3ca 100644
--- a/dumux/implicit/staggered/properties.hh
+++ b/dumux/implicit/staggered/properties.hh
@@ -42,6 +42,15 @@ namespace Properties
 
 //! The type tag for models based on staggered scheme
 NEW_TYPE_TAG(StaggeredModel, INHERITS_FROM(ImplicitBase));
+
+NEW_PROP_TAG(CellCenterPrimaryVariables); //!< A vector of primary variables for cell center dofs
+NEW_PROP_TAG(FacePrimaryVariables); //!< A vector of primary variables for face dofs
+
+NEW_PROP_TAG(NumEqCellCenter); //!< Number of equations per cell center dof
+NEW_PROP_TAG(NumEqFace); //!< Number of equations per face dof
+NEW_PROP_TAG(DofTypeIndices); //!< Indices to choose between cell center and face dofs
+
+
 }
 }
 
diff --git a/dumux/implicit/staggered/propertydefaults.hh b/dumux/implicit/staggered/propertydefaults.hh
index ae7e1ab4e2ad95e4970aed84f6610535d6b8f6cd..9e10b99ec2e99ac201795de15774053a73a8eafb 100644
--- a/dumux/implicit/staggered/propertydefaults.hh
+++ b/dumux/implicit/staggered/propertydefaults.hh
@@ -46,12 +46,21 @@
 #include <dumux/freeflow/staggered/fluxvariables.hh>
 #include <dumux/freeflow/staggered/fluxvariablescache.hh>
 
+#include <dune/common/fvector.hh>
+#include <dune/common/fmatrix.hh>
+#include <dune/common/indices.hh>
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/multitypeblockvector.hh>
+#include <dune/istl/multitypeblockmatrix.hh>
+
 
 
 
 #include "assembler.hh"
 #include "localresidual.hh"
 #include "localjacobian.hh"
+#include "properties.hh"
+#include "newtoncontroller.hh"
 
 namespace Dumux {
 
@@ -132,6 +141,53 @@ SET_TYPE_PROP(StaggeredModel, FluxVariables, FreeFlowFluxVariables<TypeTag>);
 //! The flux variables cache class, by default the one for porous media
 SET_TYPE_PROP(StaggeredModel, FluxVariablesCache, FreeFlowFluxVariablesCache<TypeTag>);
 
+SET_TYPE_PROP(StaggeredModel, NewtonController, StaggeredNewtonController<TypeTag>);
+
+SET_INT_PROP(StaggeredModel, NumEqCellCenter, 1);
+SET_INT_PROP(StaggeredModel, NumEqFace, 1);
+
+//! Set the type of a global jacobian matrix from the solution types
+SET_PROP(StaggeredModel, JacobianMatrix/*New*/)
+{
+private:
+    using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar);
+    enum {
+        numEqCellCenter = GET_PROP_VALUE(TypeTag, NumEqCellCenter),
+        numEqFace = GET_PROP_VALUE(TypeTag, NumEqFace)
+    };
+
+public:
+    // the sub-blocks
+    using MatrixLittleBlockCCToCC = typename Dune::FieldMatrix<Scalar, numEqCellCenter, numEqCellCenter>; // 2x2
+    using MatrixLittleBlockCCToFace = typename Dune::FieldMatrix<Scalar, numEqFace, numEqCellCenter>; // 1x2
+
+    using MatrixLittleBlockFaceToFace = typename Dune::FieldMatrix<Scalar, numEqFace, numEqFace>; // 1x1
+    using MatrixLittleBlockFaceToCC = typename Dune::FieldMatrix<Scalar, numEqCellCenter, numEqFace>; // 2x1
+
+    // the BCRS matrices of the subproblems as big blocks
+    using MatrixBlockCCToCC = typename Dune::BCRSMatrix<MatrixLittleBlockCCToCC>;
+    using MatrixBlockCCToFace = typename Dune::BCRSMatrix<MatrixLittleBlockCCToFace>;
+
+
+    using MatrixBlockFaceToFace = typename Dune::BCRSMatrix<MatrixLittleBlockFaceToFace>;
+    using MatrixBlockFaceToCC = typename Dune::BCRSMatrix<MatrixLittleBlockFaceToCC>;
+
+    // the row types
+    using RowCellCenter = typename Dune::MultiTypeBlockVector<MatrixLittleBlockCCToCC, MatrixLittleBlockCCToFace>;
+    using RowFace = typename Dune::MultiTypeBlockVector<MatrixLittleBlockFaceToCC, MatrixLittleBlockFaceToFace>;
+
+    // the jacobian matrix
+    using type = typename Dune::MultiTypeBlockMatrix<RowCellCenter, RowFace>;
+};
+
+//! Definition of the indices for cell center and face dofs in the global solution vector
+SET_PROP(StaggeredModel, DofTypeIndices)
+{
+    using CellCenterIdx = Dune::index_constant<0>;
+    using FaceIdx = Dune::index_constant<1>;
+};
+
+
 } // namespace Properties
 
 } // namespace Dumux