diff --git a/dune/matrix-vector/test/CMakeLists.txt b/dune/matrix-vector/test/CMakeLists.txt
index ff2014510d0732066fea5e2d69018bd6e0eab2e1..7519ef82e11269b0f5bbaf657cd61d772bf9f239 100644
--- a/dune/matrix-vector/test/CMakeLists.txt
+++ b/dune/matrix-vector/test/CMakeLists.txt
@@ -1,3 +1,4 @@
 dune_add_test(SOURCES arithmetictest.cc)
+dune_add_test(SOURCES genericvectortoolstest.cc)
 dune_add_test(SOURCES staticmatrixtoolstest.cc)
 dune_add_test(SOURCES triangularsolvetest.cc)
diff --git a/dune/matrix-vector/test/genericvectortoolstest.cc b/dune/matrix-vector/test/genericvectortoolstest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1b0354e7a9679d3d32b3766dfb50fdee4e6b6c62
--- /dev/null
+++ b/dune/matrix-vector/test/genericvectortoolstest.cc
@@ -0,0 +1,246 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dune/common/exceptions.hh>
+#include <dune/common/fvector.hh>
+#include <dune/common/fmatrix.hh>
+#include <dune/common/parallel/mpihelper.hh>
+#include <dune/common/typeutilities.hh>
+
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/bvector.hh>
+#include <dune/istl/matrixindexset.hh>
+#include <dune/istl/multitypeblockmatrix.hh>
+#include <dune/istl/multitypeblockvector.hh>
+
+#include <dune/matrix-vector/algorithm.hh>
+#include <dune/matrix-vector/genericvectortools.hh>
+
+
+/// custom multitype types to allow for BlockVector nesting
+template <class... Args>
+struct CustomMultiTypeBlockVector : public Dune::MultiTypeBlockVector<Args...> {
+  constexpr static int blocklevel = 1; // fake value
+};
+template <class... Args>
+struct CustomMultiTypeBlockMatrix : public Dune::MultiTypeBlockMatrix<Args...> {
+  constexpr static int blocklevel = 1; // fake value
+};
+// inject matrix traits for CustomMultiTypeBlockMatrix
+namespace Dune { namespace MatrixVector {
+  template <class... Args>
+  struct MatrixTraits<CustomMultiTypeBlockMatrix<Args...>> {
+    enum { isMatrix = true };
+  };
+}}
+
+
+class ResizeTestSuite {
+  /// typedefs
+  using BS = std::bitset<2>;
+  using FV = Dune::FieldVector<double, 3>;
+  using BV = Dune::BlockVector<FV>;
+  using MV = CustomMultiTypeBlockVector<BV, BV, FV>;
+  using FM = Dune::FieldMatrix<double, 3, 10>;
+  using BM = Dune::BCRSMatrix<FM>;
+  using MM = CustomMultiTypeBlockMatrix<
+               CustomMultiTypeBlockMatrix<BM>,
+               CustomMultiTypeBlockMatrix<BM>,
+               CustomMultiTypeBlockMatrix<FM>>;
+  /// instanciation helper
+  auto createBM(size_t n) {
+    BM bm;
+    Dune::MatrixIndexSet indices(n, n+10);
+    indices.exportIdx(bm);
+    return bm;
+  }
+  auto createMM(size_t n1, size_t n2) {
+    using namespace Dune::Indices;
+    MM mm;
+    mm[_0][_0] = createBM(n1);
+    mm[_1][_0] = createBM(n2);
+    return mm;
+  }
+
+  bool checkGetSize() {
+    using namespace Dune::MatrixVector::Generic::Impl;
+    std::cout << "Testing getSize... ";
+
+  auto hasSize = [](auto&& c, auto&& size) {
+    if(getSize(c, Dune::PriorityTag<42>()) != size)
+      DUNE_THROW(Dune::Exception, "Unexpected getSize mismatch.");
+  };
+
+  try {
+    // test vector types
+    using BS = std::bitset<2>;
+    hasSize(BS(), (uint) 2);
+    using FV = Dune::FieldVector<double, 3>;
+    hasSize(FV(), (uint) 3);
+    using BV = Dune::BlockVector<FV>;
+    hasSize(BV(4), (uint) 4);
+    using MV = CustomMultiTypeBlockVector<FV, BV, FV, FV, BV>;
+    hasSize(MV(), (uint) 5);
+    // test matrix types
+    using FM = Dune::FieldMatrix<double, 3, 10>;
+    hasSize(FM(), (uint) 3);
+    using BM = Dune::BCRSMatrix<FM>;
+    BM bm;
+    Dune::MatrixIndexSet indices(4, 10);
+    indices.exportIdx(bm);
+    hasSize(bm, (uint) 4);
+    using MM = CustomMultiTypeBlockMatrix<BM, BM, BM, FM, FM>;
+    hasSize(MM(), (uint) 5);
+  } catch (Dune::Exception e) {
+    std::cout << "FAILURE." << std::endl;
+    std::cout << e << std::endl;
+    return false;
+  }
+
+  std::cout << "done." << std::endl;
+  return true;
+}
+
+  //! yield test access to protected ScalarSwitch method subSizeProvider
+  template <class Vector>
+  struct SubSizeProviderAccess : Dune::MatrixVector::Generic::Impl::ScalarSwitch<Vector> {
+    using Base = Dune::MatrixVector::Generic::Impl::ScalarSwitch<Vector>;
+    template <class T>
+    static decltype(auto) test(T&& t) {
+      return Base::subSizeProvider(std::forward<T>(t));
+    }
+  };
+
+bool checkSubSizeProvider() {
+  using namespace Dune::MatrixVector;
+  std::cout << "Testing subSizeProvider... ";
+
+  // check if the sizeProvider yields the same result as given in t
+  auto pointsToSame = [](auto& o1, auto& o2) {
+    if (&o1 != &o2)
+      DUNE_THROW(Dune::Exception, "Unexpected subSizeProvider.");
+  };
+
+  // check if the sizeProvider yields the correct result for given vector type
+  auto testVectorRange = [&](const auto& v) {
+    sparseRangeFor(v, [&](auto&& vi, auto) {
+      pointsToSame(vi, SubSizeProviderAccess<std::decay_t<decltype(v)>>::test(vi));
+    });
+  };
+
+  // check if the sizeProvider yields the correct result for given matrix type
+  auto testMatrixRange = [&](const auto& m) {
+    sparseRangeFor(m, [&](auto&& mi, auto) {
+      sparseRangeFirst(mi, [&](auto&& mii) {
+        pointsToSame(mii, SubSizeProviderAccess<std::decay_t<decltype(m)>>::test(mi));
+      });
+    });
+  };
+
+  try {
+    // test vector types
+    testVectorRange(FV());
+    testVectorRange(BV(4));
+    testVectorRange(MV());
+    // test matrix types
+    testMatrixRange(FM());
+    testMatrixRange(createBM(4));
+    testMatrixRange(createMM(6,0));
+
+  } catch (Dune::Exception e) {
+    std::cout << "FAILURE." << std::endl;
+    std::cout << e << std::endl;
+    return false;
+  }
+
+  std::cout << "done." << std::endl;
+  return true;
+}
+
+bool checkResize() {
+  using namespace Dune::MatrixVector::Generic;
+  std::cout << "Testing resize... ";
+
+  // test failure for invalid static resize
+  try {
+    resize(FV(), Dune::FieldVector<int, 5>());
+    return false;
+  } catch (Dune::Exception) {
+    // TODO make sure the right exception is thrown
+  }
+
+  auto hasSize = [](auto&& size, auto&& expectedSize) {
+    if(size != expectedSize)
+      DUNE_THROW(Dune::Exception, "Resize created unexpected size.");
+  };
+
+  try {
+    // test vector types
+    BS bs, bs2;
+    resize(bs, bs2);
+    FV fv, fv2;
+    resize(fv, fv2);
+    BV bv, bv2(5);
+    resize(bv, bv2);
+    hasSize(bv.size(), (uint) 5);
+    MV mv, mv2;
+    using namespace Dune::Indices;
+    mv2[_0].resize(5);
+    resize(mv, mv2);
+    hasSize(mv[_0].size(), (uint) 5);
+    hasSize(mv[_1].size(), (uint) 0);
+    hasSize(mv[_2].size(), (uint) 3);
+    // test "natural" matrix types
+    FM fm;
+    resize(fv, fm);
+    BM bm = createBM(4);
+    resize(bv, bm);
+    hasSize(bv.size(), (uint) 4);
+    MM mm = createMM(0, 6);
+    resize(mv, mm);
+    hasSize(mv[_0].size(), (uint) 0);
+    hasSize(mv[_1].size(), (uint) 6);
+    hasSize(mv[_2].size(), (uint) 3);
+    // test "unnatural" matrix types
+    // TODO
+
+  } catch (Dune::Exception e) {
+    std::cout << "FAILURE." << std::endl;
+    std::cout << e << std::endl;
+    return false;
+  }
+
+  std::cout << "done." << std::endl;
+  return true;
+}
+
+public:
+
+bool check() {
+  std::cout << "Resize test starting.." << std::endl;
+  bool passed = true;
+
+  passed = passed and checkGetSize();
+  passed = passed and checkSubSizeProvider();
+  passed = passed and checkResize();
+  // TODO test ignore nodes type
+
+  if(passed)
+    std::cout << "Resize test succeeded.\n" << std::endl;
+  return passed;
+}
+
+};
+
+int main(int argc, char* argv[]) {
+  Dune::MPIHelper::instance(argc, argv);
+
+  bool passed = ResizeTestSuite().check();
+
+
+  if(not passed)
+    return 1;
+
+  return 0;
+}