diff --git a/dune/istl/vbvector.hh b/dune/istl/vbvector.hh
index 4eaf4cd3685df4480e9f6c4a70201139c3f27b2f..029b066a2af57a253a0b01a0511e8fb189cc1351 100644
--- a/dune/istl/vbvector.hh
+++ b/dune/istl/vbvector.hh
@@ -12,6 +12,7 @@
 #include <memory>
 
 #include <dune/common/ftraits.hh>
+#include <dune/common/indexediterator.hh>
 #include <dune/common/iteratorfacades.hh>
 #include "istlexception.hh"
 #include "bvector.hh"
@@ -46,10 +47,10 @@ namespace Dune {
                               // overwritten.
   {
     // just a shorthand
-    typedef Imp::BlockVectorWindow<B,A> window_type;
+    using window_type = Imp::BlockVectorWindow<B,A>;
 
     // data-structure holding the windows (but not the actual data)
-    using VectorWindows = std::vector<window_type, typename A::template rebind<window_type>::other>;
+    using VectorWindows = std::vector<window_type, typename std::allocator_traits<A>::template rebind_alloc<window_type>>;
 
   public:
 
@@ -59,74 +60,83 @@ namespace Dune {
     using field_type = typename Imp::BlockTraits<B>::field_type;
 
     //! export the allocator type
-    typedef A allocator_type;
+    using allocator_type = A;
 
     /** \brief Export type used for references to container entries
      *
      * \note This is not B&, but an internal proxy class!
      */
-    typedef window_type& reference;
+    using reference = window_type&;
 
     /** \brief Export type used for const references to container entries
      *
      * \note This is not B&, but an internal proxy class!
      */
-    typedef const window_type& const_reference;
+    using const_reference = const window_type&;
 
     //! The size type for the index access
-    typedef typename A::size_type size_type;
+    using size_type = typename A::size_type;
 
     /** \brief Type of the elements of the outer vector, i.e., dynamic vectors of B
      *
      * Note that this is *not* the type referred to by the iterators and random access operators,
      * which return proxy objects.
      */
-    typedef BlockVector<B,A> value_type;
+    using value_type = BlockVector<B,A>;
 
     /** \brief Same as value_type, here for historical reasons
      */
-    typedef BlockVector<B,A> block_type;
+    using block_type = BlockVector<B,A>;
 
     //===== constructors and such
 
-    /** constructor without arguments makes empty vector,
-            object cannot be used yet
+    /**
+     * \brief Constructor without arguments makes an empty vector.
+     * \note object cannot be used yet. The size and block sizes need to be initialized.
      */
-    VariableBlockVector () : Imp::block_vector_unmanaged<B,size_type>()
+    VariableBlockVector () :
+      Imp::block_vector_unmanaged<B,size_type>()
     {}
 
-    /** make vector with given number of blocks, but size of each block is not yet known,
-            object cannot be used yet
+    /**
+     * \brief Construct a vector with given number of blocks, but size of each
+     * block is not yet known.
+     * \note Object cannot be used yet. Needs to be initialized using the
+     * `createbegin()` and `createend()` create-iterators to fill the block sizes.
      */
-    explicit VariableBlockVector (size_type _nblocks) : Imp::block_vector_unmanaged<B,size_type>()
+    explicit VariableBlockVector (size_type numBlocks) :
+      Imp::block_vector_unmanaged<B,size_type>()
     {
       // we can allocate the windows now
-      block.resize(_nblocks);
+      block.resize(numBlocks);
     }
 
-    /** make vector with given number of blocks each having a constant size,
-            object is fully usable then.
-
-            \param _nblocks Number of blocks
-            \param m Number of elements in each block
+    /**
+     * \brief Construct a vector with given number of blocks each having a
+     * constant size.
+     * \note Object is fully usable after construction.
+     *
+     * \param numBlocks Number of blocks
+     * \param blockSize Number of elements in each block
      */
-    VariableBlockVector (size_type _nblocks, size_type m) : Imp::block_vector_unmanaged<B,size_type>()
+    VariableBlockVector (size_type numBlocks, size_type blockSize) :
+      Imp::block_vector_unmanaged<B,size_type>()
     {
       // and we can allocate the big array in the base class
-      storage_.resize(_nblocks*m);
+      storage_.resize(numBlocks*blockSize);
       syncBaseArray();
 
-      block.resize(_nblocks);
+      block.resize(numBlocks);
 
       // set the windows into the big array
-      for (size_type i=0; i<_nblocks; ++i)
-        block[i].set(m,this->p+(i*m));
+      for (size_type i=0; i<numBlocks; ++i)
+        block[i].set(blockSize,this->p+(i*blockSize));
 
       // and the vector is usable
       initialized = true;
     }
 
-    //! copy constructor, has copy semantics
+    //! Copy constructor, has copy semantics
     VariableBlockVector (const VariableBlockVector& a) :
       block(a.block),
       storage_(a.storage_)
@@ -134,7 +144,7 @@ namespace Dune {
       syncBaseArray();
 
       // and we must set the windows
-      if(block.size()>0) {
+      if (block.size()>0) {
         block[0].set(block[0].getsize(),this->p);           // first block
         for (size_type i=1; i<block.size(); ++i)                         // and the rest
           block[i].set(block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
@@ -144,91 +154,73 @@ namespace Dune {
       initialized = a.initialized;
     }
 
-    ~VariableBlockVector() = default;
+    ~VariableBlockVector () = default;
 
-    void swap(VariableBlockVector& other) {
-      std::swap(storage_, other.storage_);
-      std::swap(block, other.block);
-      std::swap(initialized, other.initialized);
+    //! Move constructor:
+    VariableBlockVector (VariableBlockVector&& tmp) :
+      VariableBlockVector()
+    {
+      tmp.swap(*this);
+    }
 
-      other.syncBaseArray();
-      syncBaseArray();
+    //! Copy and move assignment
+    VariableBlockVector& operator= (VariableBlockVector tmp)
+    {
+      tmp.swap(*this);
+      return *this;
     }
 
-    // move constructor:
-    VariableBlockVector(VariableBlockVector&& tmp) {
-      swap(tmp);
+    //! Exchange the storage and internal state with `other`.
+    void swap (VariableBlockVector& other) noexcept
+    {
+      using std::swap;
+      swap(storage_, other.storage_);
+      swap(block, other.block);
+      swap(initialized, other.initialized);
+
+      other.syncBaseArray();
+      syncBaseArray();
     }
 
-    // move assignment
-    VariableBlockVector& operator=(VariableBlockVector&& tmp) {
-      swap(tmp);
-      return *this;
+    //! Free function to swap the storage and internal state of `lhs` with `rhs`.
+    friend void swap (VariableBlockVector& lhs, VariableBlockVector& rhs) noexcept
+    {
+      lhs.swap(rhs);
     }
 
     //! same effect as constructor with same argument
-    void resize (size_type _nblocks)
+    void resize (size_type numBlocks)
     {
       storage_.clear();
 
       syncBaseArray();
 
       // we can allocate the windows now
-      block.resize(_nblocks);
+      block.resize(numBlocks);
 
       // and the vector not fully usable
       initialized = false;
     }
 
     //! same effect as constructor with same argument
-    void resize (size_type _nblocks, size_type m)
+    void resize (size_type numBlocks, size_type blockSize)
     {
       // and we can allocate the big array in the base class
-      storage_.resize(_nblocks*m);
-      block.resize(_nblocks);
+      storage_.resize(numBlocks*blockSize);
+      block.resize(numBlocks);
       syncBaseArray();
 
       // set the windows into the big array
       for (size_type i=0; i<block.size(); ++i)
-        block[i].set(m,this->p+(i*m));
+        block[i].set(blockSize,this->p+(i*blockSize));
 
       // and the vector is usable
       initialized = true;
     }
 
-    //! assignment
-    VariableBlockVector& operator= (const VariableBlockVector& a)
-    {
-      if (&a!=this)     // check if this and a are different objects
-      {
-        storage_ = a.storage_;
-        syncBaseArray();
-
-        block.resize(a.block.size());
-
-        // copy block structure, might be different although
-        // sizes are the same !
-        if (block.size()>0)
-        {
-          block[0].set(a.block[0].getsize(),this->p);                 // first block
-          for (size_type i=1; i<block.size(); ++i)                               // and the rest
-            block[i].set(a.block[i].getsize(),block[i-1].getptr()+block[i-1].getsize());
-        }
-
-        // and we have a usable vector
-        initialized = a.initialized;;
-      }
-
-      // and we have a usable vector
-      initialized = true;
-
-      return *this;     // Return reference to make constructions like a=b=c; work.
-    }
-
-
     //===== assignment from scalar
 
-    //! assign from scalar
+    //! Set all entries to the given scalar `k`.
     VariableBlockVector& operator= (const field_type& k)
     {
       (static_cast<Imp::block_vector_unmanaged<B,size_type>&>(*this)) = k;
@@ -250,12 +242,12 @@ namespace Dune {
     struct SizeProxy
     {
 
-      operator size_type() const
+      operator size_type () const
       {
         return target->getsize();
       }
 
-      SizeProxy& operator=(size_type size)
+      SizeProxy& operator= (size_type size)
       {
         target->setsize(size);
         return *this;
@@ -265,8 +257,8 @@ namespace Dune {
 
       friend class CreateIterator;
 
-      SizeProxy(window_type& t)
-        : target(&t)
+      SizeProxy (window_type& t) :
+        target(&t)
       {}
 
       window_type* target;
@@ -302,9 +294,11 @@ namespace Dune {
       CreateIterator (VariableBlockVector& _v, int _i, bool _isEnd) :
         v(_v),
         i(_i),
-        isEnd(_isEnd) {}
+        isEnd(_isEnd)
+      {}
 
-      ~CreateIterator() {
+      ~CreateIterator ()
+      {
         // When the iterator gets destructed, we allocate the memory
         // for the VariableBlockVector if
         // 1. the current iterator was not created as enditerator
@@ -413,39 +407,39 @@ namespace Dune {
       return block[i];
     }
 
-    using Iterator = typename VectorWindows::iterator;
+    using Iterator = IndexedIterator<typename VectorWindows::iterator>;
 
     //! begin Iterator
     Iterator begin ()
     {
-      return block.begin();
+      return Iterator{block.begin()};
     }
 
     //! end Iterator
     Iterator end ()
     {
-      return block.end();
+      return Iterator{block.end()};
     }
 
     //! @returns an iterator that is positioned before
     //! the end iterator of the vector, i.e. at the last entry.
     Iterator beforeEnd ()
     {
-      return --block.end();
+      return Iterator{--block.end()};
     }
 
     //! @returns an iterator that is positioned before
     //! the first entry of the vector.
     Iterator beforeBegin ()
     {
-      return --block.begin();
+      return Iterator{--block.begin()};
     }
 
     /** \brief Export the iterator type using std naming rules */
     using iterator = Iterator;
 
     /** \brief Const iterator */
-    using ConstIterator = typename VectorWindows::const_iterator;
+    using ConstIterator = IndexedIterator<typename VectorWindows::const_iterator>;
 
     /** \brief Export the const iterator type using std naming rules */
     using const_iterator = ConstIterator;
@@ -453,47 +447,47 @@ namespace Dune {
     //! begin ConstIterator
     ConstIterator begin () const
     {
-      return block.begin();
+      return ConstIterator{block.begin()};
     }
 
     //! end ConstIterator
     ConstIterator end () const
     {
-      return block.end();
+      return ConstIterator{block.end()};
     }
 
     //! @returns an iterator that is positioned before
     //! the end iterator of the vector. i.e. at the last element.
-    ConstIterator beforeEnd() const
+    ConstIterator beforeEnd () const
     {
-      return --block.end();
+      return ConstIterator{--block.end()};
     }
 
     //! @returns an iterator that is positioned before
     //! the first entry of the vector.
     ConstIterator beforeBegin () const
     {
-      return --block.begin();
+      return ConstIterator{--block.begin()};
     }
 
     //! end ConstIterator
     ConstIterator rend () const
     {
-      return block.rend();
+      return ConstIterator{block.rend()};
     }
 
     //! random access returning iterator (end if not contained)
     Iterator find (size_type i)
     {
-        auto tmp = block.begin();
-        tmp+=std::min(i, block.size());
-        return tmp;
+      Iterator tmp = block.begin();
+      tmp+=std::min(i, block.size());
+      return tmp;
     }
 
     //! random access returning iterator (end if not contained)
     ConstIterator find (size_type i) const
     {
-      auto tmp = block.begin();
+      ConstIterator tmp = block.begin();
       tmp+=std::min(i, block.size());
       return tmp;
     }
@@ -501,24 +495,25 @@ namespace Dune {
     //===== sizes
 
     //! number of blocks in the vector (are of variable size here)
-    size_type N () const
+    size_type N () const noexcept
     {
-      return  block.size();
+      return block.size();
     }
 
     /** Number of blocks in the vector
      *
      * Returns the same value as method N(), because the vector is dense
     */
-    size_type size () const
+    size_type size () const noexcept
     {
-      return  block.size();
+      return block.size();
     }
 
 
   private:
 
-    void allocate() {
+    void allocate ()
+    {
       if (this->initialized)
         DUNE_THROW(ISTLError, "Attempt to re-allocate already initialized VariableBlockVector");
 
@@ -539,7 +534,7 @@ namespace Dune {
       this->initialized = true;
     }
 
-    void syncBaseArray() noexcept
+    void syncBaseArray () noexcept
     {
       this->p = storage_.data();
       this->n = storage_.size();