diff --git a/examples/poisson-pq2.cc b/examples/poisson-pq2.cc
index aa127d2fd9662d1af29beba7c16899dbd88c2012..9d42013b901894f456aea05b319f76504d7b6f1f 100644
--- a/examples/poisson-pq2.cc
+++ b/examples/poisson-pq2.cc
@@ -7,6 +7,7 @@
 
 #include <dune/common/bitsetvector.hh>
 #include <dune/common/version.hh>
+#include <dune/common/stringutility.hh>
 
 #include <dune/geometry/quadraturerules.hh>
 
@@ -32,6 +33,7 @@
 #include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh>
 #endif
 
+#include <dune/fufem/logger.hh>
 #include <dune/fufem/parallel/elementcoloring.hh>
 #include <dune/fufem/boundarypatch.hh>
 #include <dune/fufem/functiontools/boundarydofs.hh>
@@ -71,6 +73,9 @@ auto createMixedGrid()
 
 int main (int argc, char *argv[]) try
 {
+
+  auto log = Dune::Fufem::makeLogger(std::cout, "[% 8.3f] [% 8.3f] ");
+
   std::size_t threadCount = 4;
   if (argc>1)
     threadCount = std::stoul(std::string(argv[1]));
@@ -79,10 +84,12 @@ int main (int argc, char *argv[]) try
   if (argc>2)
     refinements = std::stoul(std::string(argv[2]));
 
+  log("Command line processed");
 
-  // Set up MPI, if available
   MPIHelper::instance(argc, argv);
 
+  log("MPI initialized");
+
   ///////////////////////////////////
   //   Generate the grid
   ///////////////////////////////////
@@ -93,8 +100,12 @@ int main (int argc, char *argv[]) try
   auto grid = createUniformCubeGrid<2>();
 #endif
 
+  log("Grid created");
+
   grid->globalRefine(refinements);
 
+  log(Dune::formatString("Grid refined %d times", refinements));
+
   auto gridView = grid->leafGridView();
   using GridView = decltype(gridView);
 
@@ -105,13 +116,15 @@ int main (int argc, char *argv[]) try
   using Basis = Dune::Functions::LagrangeBasis<GridView,2>;
   Basis basis(gridView);
 
+  log(Dune::formatString("Basis created with dimension %d", basis.dimension()));
+
   /////////////////////////////////////////////////////////
   //   Stiffness matrix and right hand side vector
   /////////////////////////////////////////////////////////
 
-  using Vector = Dune::BlockVector<Dune::FieldVector<double,1>>;
-  using BitVector = Dune::BlockVector<Dune::FieldVector<char,1>>;
-  using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double,1,1>>;
+  using Vector = Dune::BlockVector<double>;
+  using BitVector = std::vector<bool>;
+  using Matrix = Dune::BCRSMatrix<double>;
 
   Vector rhs;
   Vector sol;
@@ -122,8 +135,6 @@ int main (int argc, char *argv[]) try
   //  Assemble the system
   /////////////////////////////////////////////////////////
 
-  std::cout << "Number of DOFs is " << basis.dimension() << std::endl;
-
   auto dirichletIndicatorFunction = [](auto x) { return true; };
 
   auto dirichletPatch = BoundaryPatch(basis.gridView());
@@ -137,9 +148,11 @@ int main (int argc, char *argv[]) try
 // Disable parallel assembly for UGGrid before 2.10
 #if DUNE_VERSION_GT(DUNE_FUNCTIONS, 2, 9)
   auto gridViewPartition = Dune::Fufem::coloredGridViewPartition(gridView);
-  auto globalAssembler = GlobalAssembler(basis, basis, 1, std::cref(gridViewPartition), threadCount);
+  log("Grid coloring computed");
+
+  auto globalAssembler = GlobalAssembler(basis, basis, 0, std::cref(gridViewPartition), threadCount);
 #else
-  auto globalAssembler = GlobalAssembler(basis, basis, 1);
+  auto globalAssembler = GlobalAssembler(basis, basis, 0);
 #endif
 
   {
@@ -153,8 +166,11 @@ int main (int argc, char *argv[]) try
     auto a = integrate(dot(grad(u), grad(v)));
     auto b = integrate(f*v);
 
+    log("Assembler set up");
     globalAssembler.assembleOperator(stiffnessMatrix, a);
+    log("Matrix assembled");
     globalAssembler.assembleFunctional(rhs, b);
+    log("RHS assembled");
   }
 
   // *********************************************
@@ -171,11 +187,13 @@ int main (int argc, char *argv[]) try
   Dune::Functions::istlVectorBackend(isConstrained).resize(basis);
   Dune::Functions::istlVectorBackend(isConstrained) = 0;
   Dune::Fufem::markBoundaryPatchDofs(dirichletPatch, basis, isConstrained);
+  log("Boundary DOFs marked");
 
   interpolate(basis, sol, dirichletValues, isConstrained);
+  log("Boundary DOFs interpolated");
 
   incorporateEssentialConstraints(basis, stiffnessMatrix, rhs, isConstrained, sol);
-
+  log("Boundary condition incorporated into system");
 
   ////////////////////////////
   //   Compute solution
@@ -184,22 +202,33 @@ int main (int argc, char *argv[]) try
   // Technicality:  turn the matrix into a linear operator
   MatrixAdapter<Matrix,Vector,Vector> op(stiffnessMatrix);
 
+// FastAMG is not working for non-blocked matrices in 2.10
+#if DUNE_VERSION_GTE(DUNE_ISTL, 2, 11)
+  auto preconditioner = makeAMGPreconditioner<Vector>(stiffnessMatrix);
+#else
   // Sequential incomplete LU decomposition as the preconditioner
-  SeqILDL<Matrix,Vector,Vector> ildl(stiffnessMatrix,1.0);
+  auto preconditioner = SeqILDL<Matrix,Vector,Vector>(stiffnessMatrix,1.0);
+#endif
+
+  log("Preconditioner created");
 
   // Preconditioned conjugate-gradient solver
   CGSolver<Vector> cg(op,
-                          ildl, // preconditioner
+                          preconditioner, // preconditioner
                           1e-4, // desired residual reduction factor
-                          100,   // maximum number of iterations
+                          1000,   // maximum number of iterations
                           2);   // verbosity of the solver
 
+  log("Solver created");
+
   // Object storing some statistics about the solving process
   InverseOperatorResult statistics;
 
   // Solve!
   cg.apply(sol, rhs, statistics);
 
+  log("Linear system solved");
+
   ////////////////////////////////////////////////////////////////////////////
   //  Make a discrete function from the FE basis and the coefficient vector
   ////////////////////////////////////////////////////////////////////////////
@@ -223,7 +252,7 @@ int main (int argc, char *argv[]) try
   vtkWriter.addVertexData(solFunction, VTK::FieldInfo("sol", VTK::FieldInfo::Type::scalar, 1));
   vtkWriter.write("poisson-pq2");
 #endif
-
+  log("Solution written to vtk file");
  }
 // Error handling
  catch (Exception& e) {
diff --git a/examples/stokes-taylorhood.cc b/examples/stokes-taylorhood.cc
index e24c91bf77a1294c0f4647ecb7187e576e16051c..adf3c5cdf3d8c13904f5ab520d0b158fbe6f0328 100644
--- a/examples/stokes-taylorhood.cc
+++ b/examples/stokes-taylorhood.cc
@@ -22,12 +22,6 @@
 #include <dune/istl/multitypeblockmatrix.hh>
 #include <dune/istl/multitypeblockvector.hh>
 
-
-#if DUNE_VERSION_GT(DUNE_ISTL, 2, 10)
-#include <dune/istl/paamg/fastamg.hh>
-#endif
-
-
 #include <dune/functions/functionspacebases/interpolate.hh>
 #include <dune/functions/functionspacebases/taylorhoodbasis.hh>
 #include <dune/functions/backends/istlvectorbackend.hh>
@@ -66,26 +60,7 @@ using namespace Dune;
 
 
 
-#if DUNE_VERSION_GT(DUNE_ISTL, 2, 10)
-template<class V, class M>
-auto makeAMGPreconditioner(const V& x, const M& m)
-{
-  using Operator = Dune::MatrixAdapter<M,V,V>;
-  using Criterion = Dune::Amg::SymmetricCriterion<M, Dune::Amg::RowSum>;
-  using AMG = Dune::Amg::FastAMG<Operator, V>;
-
-  auto parameters = Dune::Amg::Parameters();
-  parameters.setDebugLevel(0);
-  parameters.setNoPreSmoothSteps(1);
-  parameters.setNoPostSmoothSteps(1);
-
-  auto criterion = Criterion();
-  criterion.setDebugLevel(0);
-
-  auto opPtr = std::make_shared<Operator>(m);
-  return AMG(opPtr, criterion, parameters);
-}
-
+#if DUNE_VERSION_GTE(DUNE_ISTL, 2, 10)
 
 template<class V, class... P>
 class BlockDiagonalPreconditioner : public Preconditioner<V,V> {
@@ -329,7 +304,7 @@ int main (int argc, char *argv[]) try
   // Technicality:  turn the matrix into a linear operator
   MatrixAdapter<Matrix,Vector,Vector> stiffnessOperator(stiffnessMatrix);
 
-#if DUNE_VERSION_GT(DUNE_ISTL, 2, 10)
+#if DUNE_VERSION_GTE(DUNE_ISTL, 2, 10)
   // As iterative solver we use MinRes with a block-diagonal preconditioner
   // for the saddle point problem. An optimal preconditioner would be obtained,
   // if the (0,0)-velocity-block is exact, while the (1,1)-block is the Schur-
@@ -355,8 +330,8 @@ int main (int argc, char *argv[]) try
   using namespace Dune::Indices;
 
   auto preconditioner = BlockDiagonalPreconditioner(x,
-                          makeAMGPreconditioner(x[_0], stiffnessMatrix[_0][_0]),
-                          makeAMGPreconditioner(x[_1], pressureMassMatrix));
+                          makeAMGPreconditioner(stiffnessMatrix[_0][_0], x[_0]),
+                          makeAMGPreconditioner(pressureMassMatrix, x[_1]));
 
   // Construct the actual iterative solver
   MINRESSolver<Vector> solver(
diff --git a/examples/utilities.hh b/examples/utilities.hh
index 523f453f659d3f49f6c237bdecf65080ed35c5b1..ceb1b407aea023dada0056ba3c7f8250219b4c6e 100644
--- a/examples/utilities.hh
+++ b/examples/utilities.hh
@@ -10,6 +10,10 @@
 #include <dune/common/typetraits.hh>
 #include <dune/common/concept.hh>
 
+#if DUNE_VERSION_GTE(DUNE_ISTL, 2, 10)
+#include <dune/istl/paamg/fastamg.hh>
+#endif
+
 #include <dune/grid/common/rangegenerators.hh>
 
 #include <dune/functions/backends/concepts.hh>
@@ -141,6 +145,53 @@ void incorporateEssentialConstraints(const Basis& basis, Matrix& matrix, Vector&
 
 
 
+#if DUNE_VERSION_GTE(DUNE_ISTL, 2, 10)
+/**
+ * \brief Create a FastAMG preconditioner
+ * \tparam Matrix Type of the matrix the preconditioner should act on.
+ * \tparam Vector Type of vectors the preconditioner should act on.
+ * \param matrix The matrix used in the preconditioner
+ *
+ * This constructs a Dune::FastAMG preconditioner. With some
+ * standard arguments that are not defaulted in dune-istl.
+ */
+template<class Vector, class Matrix>
+auto makeAMGPreconditioner(const Matrix& matrix)
+{
+  using Operator = Dune::MatrixAdapter<Matrix,Vector,Vector>;
+  using Criterion = Dune::Amg::SymmetricCriterion<Matrix, Dune::Amg::RowSum>;
+  using AMG = Dune::Amg::FastAMG<Operator, Vector>;
+
+  auto parameters = Dune::Amg::Parameters();
+  parameters.setDebugLevel(0);
+  parameters.setNoPreSmoothSteps(1);
+  parameters.setNoPostSmoothSteps(1);
+
+  auto criterion = Criterion();
+  criterion.setDebugLevel(0);
+
+  auto opPtr = std::make_shared<Operator>(matrix);
+  return AMG(opPtr, criterion, parameters);
+}
+
+/**
+ * \brief Create a FastAMG preconditioner
+ * \tparam Matrix Type of the matrix the preconditioner should act on.
+ * \tparam Vector Type of vectors the preconditioner should act on.
+ * \param matrix The matrix used in the preconditioner
+ * \param dummy A dummy vector argument to enable type deduction for the Vector type.
+ *
+ * This constructs a Dune::FastAMG preconditioner.
+ */
+template<class Vector, class Matrix>
+auto makeAMGPreconditioner(const Matrix& matrix, const Vector& dummy)
+{
+  return makeAMGPreconditioner<Vector>(matrix);
+}
+#endif
+
+
+
 // Compute the (i,j)-th cofactor of F
 template<class K, int d>
 constexpr K cofactor(const Dune::FieldMatrix<K,d,d>& F, std::size_t i, std::size_t j)