diff --git a/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh b/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh
index 42162f9deb60279ea104d1c4a88f47f5d13e841d..80ef62ab19a7e7cfc5ace139c08a2ae3c670d54d 100644
--- a/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh
+++ b/appl/lecture/msm/buckleyleverett/buckleyleverettproblem.hh
@@ -216,8 +216,7 @@ public:
             if (this->gridView().comm().rank() == 0)
                 std::cout << "Writing result file for current time step\n";
 
-            this->resultWriter().beginWrite(this->timeManager().time() + this->timeManager().timeStepSize(),
-                                            this->gridView());
+            this->resultWriter().beginWrite(this->timeManager().time() + this->timeManager().timeStepSize());
             this->asImp_().addOutputVtkFields();
             this->resultWriter().endWrite();
 //        }
diff --git a/dumux/boxmodels/common/boxproblem.hh b/dumux/boxmodels/common/boxproblem.hh
index 577d442ad04eaace2baf5b9e02c37c615681ac04..1468bdb10934acceda76cb07b93ae75fe775ab67 100644
--- a/dumux/boxmodels/common/boxproblem.hh
+++ b/dumux/boxmodels/common/boxproblem.hh
@@ -735,7 +735,7 @@ public:
             // calculate the time _after_ the time was updated
             Scalar t = timeManager().time() + timeManager().timeStepSize();
             createResultWriter_();
-            resultWriter_->beginWrite(t, gridView());
+            resultWriter_->beginWrite(t);
             model().addOutputVtkFields(model().curSol(), *resultWriter_);
             asImp_().addOutputVtkFields();
             resultWriter_->endWrite();
@@ -770,7 +770,7 @@ protected:
 private:
     // makes sure that the result writer exists
     void createResultWriter_()
-    { if (!resultWriter_) resultWriter_ = new VtkMultiWriter(asImp_().name()); };
+    { if (!resultWriter_) resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name()); };
 
     std::string simName_; 
     const GridView gridView_;
diff --git a/dumux/decoupled/2p2c/fvpressure2p2c.hh b/dumux/decoupled/2p2c/fvpressure2p2c.hh
index 69029737ae91f607e48ec1184d7c604c1cfff1f0..bd0733b2d7899a20f9784c848118e5381803a905 100644
--- a/dumux/decoupled/2p2c/fvpressure2p2c.hh
+++ b/dumux/decoupled/2p2c/fvpressure2p2c.hh
@@ -260,7 +260,7 @@ public:
     FVPressure2P2C(Problem& problem) :
         problem_(problem), A_(problem.variables().gridSize(), problem.variables().gridSize(), (2 * dim + 1)
                 * problem.variables().gridSize(), Matrix::random), f_(problem.variables().gridSize()),
-                debugWriter_("debugOutput2p2c"), gravity(problem.gravity())
+                debugWriter_(problem.gridView(), "debugOutput2p2c"), gravity(problem.gravity())
     {
         if (pressureType != pw && pressureType != pn)
         {
diff --git a/dumux/decoupled/common/impetproblem.hh b/dumux/decoupled/common/impetproblem.hh
index 52d0a178c4ea3cc46c2be741ef98b6d660896e15..6621d03fdbd3cbd6383f67526af60d8b7afaa4c3 100644
--- a/dumux/decoupled/common/impetproblem.hh
+++ b/dumux/decoupled/common/impetproblem.hh
@@ -532,9 +532,8 @@ public:
             std::cout << "Writing result file for current time step\n";
 
         if (!resultWriter_)
-            resultWriter_ = new VtkMultiWriter(asImp_().name());
-        resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize(),
-                                    gridView());
+            resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name());
+        resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize());
         model().addOutputVtkFields(*resultWriter_);
         asImp_().addOutputVtkFields();
         resultWriter_->endWrite();
@@ -555,14 +554,14 @@ protected:
     VtkMultiWriter& resultWriter()
     {
         if (!resultWriter_)
-            resultWriter_ = new VtkMultiWriter(asImp_().name());
+            resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name());
         return *resultWriter_;
     }
     //! \copydoc Dumux::IMPETProblem::resultWriter()
     VtkMultiWriter& resultWriter() const
     {
         if (!resultWriter_)
-            resultWriter_ = new VtkMultiWriter(asImp_().name());
+            resultWriter_ = new VtkMultiWriter(gridView_, asImp_().name());
         return *resultWriter_;
     }
 
diff --git a/dumux/decoupled/common/onemodelproblem.hh b/dumux/decoupled/common/onemodelproblem.hh
index fd071cee4b1f3cc8bfc02692158c8efbff80554a..40b4c05402730212584413aa903553c7132f03be 100644
--- a/dumux/decoupled/common/onemodelproblem.hh
+++ b/dumux/decoupled/common/onemodelproblem.hh
@@ -230,8 +230,8 @@ public:
         if (gridView().comm().rank() == 0)
             std::cout << "Writing result file for current time step\n";
         if (!resultWriter_)
-            resultWriter_ = new VtkMultiWriter(asImp_().name());
-        resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize(), gridView());
+            resultWriter_ = new VtkMultiWriter(gridView(), asImp_().name());
+        resultWriter_->beginWrite(timeManager_.time() + timeManager_.timeStepSize());
         model().addOutputVtkFields(*resultWriter_);
         asImp_().addOutputVtkFields();
         resultWriter_->endWrite();
diff --git a/dumux/io/vtkmultiwriter.hh b/dumux/io/vtkmultiwriter.hh
index 49f5a0f27802155e850baaa41b18a677961ea9c3..28942d833c9da21cc6ae1d4e6086f11a620d63ab 100644
--- a/dumux/io/vtkmultiwriter.hh
+++ b/dumux/io/vtkmultiwriter.hh
@@ -24,6 +24,8 @@
 #ifndef VTK_MULTI_WRITER_HH
 #define VTK_MULTI_WRITER_HH
 
+#include "vtknestedfunction.hh"
+
 #include <dune/common/fvector.hh>
 #include <dune/istl/bvector.hh>
 
@@ -54,10 +56,27 @@ namespace Dumux {
 template<class GridView>
 class VtkMultiWriter
 {
-public:
+    typedef typename GridView::Grid Grid;
+    enum { dim = GridView::dimension };
+
+    typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGVertexLayout> VertexMapper;
+    typedef Dune::MultipleCodimMultipleGeomTypeMapper<GridView, Dune::MCMGElementLayout> ElementMapper;
+
+    // this constructor won't work anymore. Please use the variant
+    // below which also includes the GridView as an argument.
+    DUNE_DEPRECATED
+    VtkMultiWriter(const std::string &simName = "", 
+                   std::string multiFileName = "")
+    {}
 
+public:
     typedef Dune::VTKWriter<GridView> VtkWriter;
-    VtkMultiWriter(const std::string &simName = "", std::string multiFileName = "")
+    VtkMultiWriter(const GridView &gridView, 
+                   const std::string &simName = "", 
+                   std::string multiFileName = "")
+        : gridView_(gridView)
+        , elementMapper_(gridView)
+        , vertexMapper_(gridView)
     {
         simName_ = (simName.empty())?"sim":simName;
         multiFileName_ = multiFileName;
@@ -84,18 +103,32 @@ public:
             multiFile_.close();
     }
 
+    /*!
+     * \brief Updates the internal data structures after mesh
+     *        refinement.
+     *
+     * If the grid changes between two calls of beginWrite(), this
+     * method _must_ be called before the second beginWrite()!
+     */
+    void gridChanged()
+    {
+        elementMapper_.update();
+        vertexMapper_.update();
+    }
+
     /*!
      * \brief Called when ever a new timestep or a new grid
      *        must be written.
      */
-    void beginWrite(double t, const GridView &gridView)
+    void beginWrite(double t)
     {
         if (!multiFile_.is_open()) {
             startMultiFile_(multiFileName_);
         }
 
 
-        curWriter_ = new VtkWriter(gridView, Dune::VTKOptions::conforming);
+        curWriter_ = new VtkWriter(gridView_,
+                                   Dune::VTKOptions::conforming);
         ++curWriterNum_;
 
         curTime_ = t;
@@ -104,7 +137,7 @@ public:
     
     void beginTimestep(double t, const GridView &gridView)
         DUNE_DEPRECATED // use beginWrite()
-    { beginWrite(t, gridView); }
+    { gridChanged(); beginWrite(t); }
 
     /*!
      * \brief Allocate a managed buffer for a scalar field
@@ -116,10 +149,10 @@ public:
     Dune::BlockVector<Dune::FieldVector<Scalar, nComp> > *allocateManagedBuffer(int nEntities)
     {
         typedef Dune::BlockVector<Dune::FieldVector<Scalar, nComp> > VectorField;
-
-        VtkVectorFieldStoreImpl_<VectorField> *vfs =
-            new VtkVectorFieldStoreImpl_<VectorField>(nEntities);
-        vectorFields_.push_back(vfs);
+        
+        ManagedVectorField_<VectorField> *vfs =
+            new ManagedVectorField_<VectorField>(nEntities);
+        managedObjects_.push_back(vfs);
         return &(vfs->vf);
     }
 
@@ -145,11 +178,18 @@ public:
      * In both cases, modifying the buffer between the call to this
      * method and endWrite() results in _undefined behaviour_.
      */
-    template <class DataArray>
-    void attachVertexData(DataArray &buf, const char *name, int nComps=1)
+    template <class DataBuffer>
+    void attachVertexData(DataBuffer &buf, const char *name, int nComps=1)
     {
-        sanitizeBuffer_(buf, nComps);
-        curWriter_->addVertexData(buf, name, nComps);
+        typedef typename VtkWriter::VTKFunctionPtr FunctionPtr;
+        typedef Dumux::VtkNestedFunction<Grid, VertexMapper, DataBuffer> VtkFn;
+        FunctionPtr fnPtr(new VtkFn(name,
+                                    gridView_.grid(),
+                                    vertexMapper_,
+                                    buf,
+                                    /*codim=*/dim,
+                                    nComps));
+        curWriter_->addVertexData(fnPtr);
     }
 
     template <class DataArray>
@@ -172,12 +212,18 @@ public:
      * In both cases, modifying the buffer between the call to this
      * method and endWrite() results in _undefined behaviour_.
      */
-    template <class VectorField>
-    void attachCellData(VectorField &buf, const char *name, int nComps = 1)
+    template <class DataBuffer>
+    void attachCellData(DataBuffer &buf, const char *name, int nComps = 1)
     { 
-        sanitizeBuffer_(buf, nComps);
-
-        curWriter_->addCellData(buf, name);
+        typedef typename VtkWriter::VTKFunctionPtr FunctionPtr;
+        typedef Dumux::VtkNestedFunction<Grid, ElementMapper, DataBuffer> VtkFn;
+        FunctionPtr fnPtr(new VtkFn(name,
+                                    gridView_.grid(),
+                                    elementMapper_,
+                                    buf,
+                                    /*codim=*/0,
+                                    nComps));
+        curWriter_->addCellData(fnPtr);
     }
 
     template <class VectorField>
@@ -226,11 +272,11 @@ public:
         else
             -- curWriterNum_;
 
-        // discard managed buffers
+        // discard managed objects and the current VTK writer
         delete curWriter_;
-        while (vectorFields_.begin() != vectorFields_.end()) {
-            delete vectorFields_.front();
-            vectorFields_.pop_front();
+        while (managedObjects_.begin() != managedObjects_.end()) {
+            delete managedObjects_.front();
+            managedObjects_.pop_front();
         }
 
         // temporarily write the closing XML mumbo-jumbo to the mashup
@@ -377,8 +423,8 @@ private:
 
     // make sure the field is well defined if running under valgrind
     // and make sure that all values can be displayed by paraview
-    template <class Buffer>
-    void sanitizeBuffer_(Buffer &b, int nComps)
+    template <class DataBuffer>
+    void sanitizeBuffer_(DataBuffer &b, int nComps)
     {
         for (int i = 0; i < b.size(); ++i) {
             for (int j = 0; j < nComps; ++j) {
@@ -413,20 +459,20 @@ private:
 
     /** \todo Please doc me! */
 
-    class VtkVectorFieldStoreBase_
+    class ManagedObject_
     {
     public:
-        virtual ~VtkVectorFieldStoreBase_()
+        virtual ~ManagedObject_()
         {}
     };
 
     /** \todo Please doc me! */
 
     template <class VF>
-    class VtkVectorFieldStoreImpl_ : public VtkVectorFieldStoreBase_
+    class ManagedVectorField_ : public ManagedObject_
     {
     public:
-        VtkVectorFieldStoreImpl_(int size)
+        ManagedVectorField_(int size)
             : vf(size)
         { }
         VF vf;
@@ -434,7 +480,9 @@ private:
     // end hack
     ////////////////////////////////////
 
-    bool wasRestarted_;
+    const GridView gridView_;
+    ElementMapper elementMapper_;
+    VertexMapper vertexMapper_;
 
     std::string simName_;
     std::ofstream multiFile_;
@@ -448,7 +496,7 @@ private:
     std::string curOutFileName_;
     int curWriterNum_;
 
-    std::list<VtkVectorFieldStoreBase_*> vectorFields_;
+    std::list<ManagedObject_*> managedObjects_;
 };
 }
 
diff --git a/dumux/nonlinear/newtoncontroller.hh b/dumux/nonlinear/newtoncontroller.hh
index 4ec9ba467ffc3a72f682ffc0df041c53ae5253c0..3f458d2e2f6c6fd11218eb329af3a30acf6035d5 100644
--- a/dumux/nonlinear/newtoncontroller.hh
+++ b/dumux/nonlinear/newtoncontroller.hh
@@ -116,7 +116,7 @@ struct NewtonConvergenceWriter
     {
         timeStepIndex_ = 0;
         iteration_ = 0;
-        vtkMultiWriter_ = new VtkMultiWriter("convergence");
+        vtkMultiWriter_ = 0;
     }
 
     ~NewtonConvergenceWriter()
@@ -131,8 +131,9 @@ struct NewtonConvergenceWriter
     void beginIteration(const GridView &gv)
     {
         ++ iteration_;
-        vtkMultiWriter_->beginWrite(timeStepIndex_ + iteration_ / 100.0,
-                                    gv);
+        if (!vtkMultiWriter_)
+            vtkMultiWriter_ = new VtkMultiWriter(gv, "convergence");
+        vtkMultiWriter_->beginWrite(timeStepIndex_ + iteration_ / 100.0);
     };
 
     void writeFields(const SolutionVector &uLastIter,
diff --git a/tutorial/tutorialproblem_coupled.hh b/tutorial/tutorialproblem_coupled.hh
index b0611b510a762b6495bf1683b412bd685d21732c..37f3e2ee22c07166dbd1cb8bdb0e42e525e65dc4 100644
--- a/tutorial/tutorialproblem_coupled.hh
+++ b/tutorial/tutorialproblem_coupled.hh
@@ -154,8 +154,9 @@ public:
      */
     bool shouldWriteOutput() const /*@\label{tutorial-coupled:output}@*/
     {
-        return this->timeManager().timeStepIndex() > 0 &&
-        (this->timeManager().timeStepIndex() % 1 == 0);
+        return 
+            this->timeManager().timeStepIndex() > 0 &&
+            (this->timeManager().timeStepIndex() % 1 == 0);
     }
 
     // Return the temperature within a finite volume. We use constant