diff --git a/src/amdis/functions/NodeIndices.hpp b/src/amdis/functions/NodeIndices.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..98fd9463770d0b92df26461b1806e76a7fced29e
--- /dev/null
+++ b/src/amdis/functions/NodeIndices.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include <dune/common/rangeutilities.hh>
+#include <dune/functions/functionspacebases/concepts.hh>
+
+#include <amdis/typetree/MultiIndex.hpp>
+#include <amdis/utility/MappedRangeView.hpp>
+
+namespace AMDiS
+{
+  /// Returns a range over (flat) DOF indices on a node, given by the localView
+  template <class LocalView, class Node>
+  auto nodeIndices(LocalView const& localView, Node const& node)
+  {
+    using namespace Dune::Functions;
+    static_assert(Dune::models<Concept::LocalView<typename LocalView::GlobalBasis>, LocalView>(), "");
+    static_assert(Dune::models<Concept::BasisTree<typename LocalView::GridView>, Node>(), "");
+
+    return mappedRangeView(Dune::range(node.size()), [&](std::size_t j) -> std::size_t {
+      return flatMultiIndex(localView.index(node.localIndex(j)));
+    });
+  }
+
+  /// Returns a range over (flat) DOF indices on the basis tree, given by the localView
+  template <class LocalView>
+  auto nodeIndices(LocalView const& localView)
+  {
+    using namespace Dune::Functions;
+    static_assert(Dune::models<Concept::LocalView<typename LocalView::GlobalBasis>, LocalView>(), "");
+
+    return mappedRangeView(Dune::range(localView.size()), [&](std::size_t i) -> std::size_t {
+      return flatMultiIndex(localView.index(i));
+    });
+  }
+
+
+  /// Returns the number of DOF indices on a node, given by the localView
+  template <class LocalView, class Node>
+  std::size_t nodeIndexCount(LocalView const& /*localView*/, Node const& node)
+  {
+    return node.size();
+  }
+
+  /// Returns the number of DOF indices on the basis tree, given by the localView
+  template <class LocalView>
+  std::size_t nodeIndexCount(LocalView const& localView)
+  {
+    return localView.size();
+  }
+
+} // end namespace AMDiS
diff --git a/src/amdis/functions/Nodes.hpp b/src/amdis/functions/Nodes.hpp
index 5a247083d66b41fe028d9d0a2c3756c8c3e2ada1..79cea5e77ac0e17c3af9b6ea537e30f877f634e2 100644
--- a/src/amdis/functions/Nodes.hpp
+++ b/src/amdis/functions/Nodes.hpp
@@ -34,4 +34,16 @@ namespace AMDiS
 #endif
   }
 
+  // dune version independent creation of node from preBasis
+  template <class PB, class TP>
+  auto makeNodeIndexSet(PB const& preBasis, TP const& treePath)
+  {
+#if DUNE_VERSION_LT(DUNE_FUNCTIONS,2,7)
+    return preBasis.indexSet(treePath);
+#else
+    DUNE_UNUSED_PARAMETER(treePath);
+    return preBasis.makeIndexSet();
+#endif
+  }
+
 } // end namespace AMDiS
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 7e7de14fbbfd00a80a5a2ee1e5196989dfef3b59..f6316ae748f73e6118ec528b2fb23f8c65466635 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -87,6 +87,9 @@ dune_add_test(SOURCES MultiTypeVectorTest.cpp
 dune_add_test(SOURCES MultiTypeMatrixTest.cpp
   LINK_LIBRARIES amdis)
 
+dune_add_test(SOURCES NodeIndicesTest.cpp
+  LINK_LIBRARIES amdis)
+
 dune_add_test(SOURCES OperationsTest.cpp
   LINK_LIBRARIES amdis)
 
diff --git a/test/NodeIndicesTest.cpp b/test/NodeIndicesTest.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b180d9416a97ab0d91fef7161739faa97473b13c
--- /dev/null
+++ b/test/NodeIndicesTest.cpp
@@ -0,0 +1,73 @@
+#include <dune/grid/yaspgrid.hh>
+#include <dune/functions/functionspacebases/compositebasis.hh>
+#include <dune/functions/functionspacebases/powerbasis.hh>
+#include <dune/functions/functionspacebases/lagrangebasis.hh>
+
+#include <amdis/functions/NodeIndices.hpp>
+#include "Tests.hpp"
+
+int main()
+{
+  using namespace AMDiS;
+  using namespace Dune::Functions::BasisFactory;
+
+  // create grid
+  Dune::YaspGrid<2> grid({1.0, 1.0}, {1, 1});
+  auto gridView = grid.leafGridView();
+
+  // create basis
+  auto taylorHoodBasis = makeBasis(
+    gridView,
+    composite(
+      power<2>(lagrange<2>(), flatInterleaved()),
+      lagrange<1>(),
+      flatLexicographic()
+    ));
+
+  auto localView = taylorHoodBasis.localView();
+
+  for (auto const& e : elements(gridView)) {
+    localView.bind(e);
+
+    std::size_t numDofs = 2*(3*3) + (2*2);
+    std::size_t numNodeIndices = nodeIndexCount(localView);
+    AMDIS_TEST_EQ(numNodeIndices, numDofs);
+
+    std::size_t num = 0;
+    for (std::size_t dof : nodeIndices(localView)) {
+      DUNE_UNUSED_PARAMETER(dof);
+      num++;
+    }
+    AMDIS_TEST_EQ(num, numDofs);
+
+    auto node = localView.tree();
+    numNodeIndices = nodeIndexCount(localView, node);
+    AMDIS_TEST_EQ(numNodeIndices, numDofs);
+
+    // count the number of velocity dofs
+    std::size_t numVelDofs = 2*(3*3);
+    auto v_node = Dune::TypeTree::child(node, Dune::Indices::_0);
+    std::size_t numVelNodeIndices = nodeIndexCount(localView, v_node);
+    AMDIS_TEST_EQ(numVelNodeIndices, numVelDofs);
+    num = 0;
+    for (std::size_t dof : nodeIndices(localView, v_node)) {
+      DUNE_UNUSED_PARAMETER(dof);
+      num++;
+    }
+    AMDIS_TEST_EQ(num, numVelDofs);
+
+    // count the number of pressure dofs
+    std::size_t numPDofs = 2*2;
+    auto p_node = Dune::TypeTree::child(node, Dune::Indices::_1);
+    std::size_t numPNodeIndices = nodeIndexCount(localView, p_node);
+    AMDIS_TEST_EQ(numPNodeIndices, numPDofs);
+    num = 0;
+    for (std::size_t dof : nodeIndices(localView, p_node)) {
+      DUNE_UNUSED_PARAMETER(dof);
+      num++;
+    }
+    AMDIS_TEST_EQ(num, numPDofs);
+  }
+
+  return report_errors();
+}