diff --git a/.gitignore b/.gitignore
index 7b551f5eb63e26bcd64d480adb982ce6099cbede..3bf554cabd3688d698583b602cc7f5ae25056def 100644
--- a/.gitignore
+++ b/.gitignore
@@ -52,3 +52,5 @@ src/dune_fem_functionals-dune_fem_functionals.o
 tests/functional/.deps
 tests/functional/l2functional_test
 tests/functional/l2functional_test-l2functional_test.o
+tests/functional/discretelinearfunctional_test
+tests/functional/discretelinearfunctional_test-discretelinearfunctional_test.o
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 70fcc37c2d4db6f562941b3ab93f6b0278849a16..79f4076f691bcf43b84a7edb304fb89277bacfd3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -123,4 +123,7 @@ set( COMMON_LIBS "fem" "grid" "common" ${BLAS_LIB} "alugrid" "GL" )
 ADD_EXECUTABLE( l2functional_test "tests/functional/l2functional_test.cc" ${header} ${common} ${grid} ${istl} ${fem} ${femhowto} ${fem-functionals} )
 TARGET_LINK_LIBRARIES( l2functional_test ${COMMON_LIBS}  )
 
+ADD_EXECUTABLE( discretelinearfunctional_test "tests/functional/discretelinearfunctional_test.cc" ${header} ${common} ${grid} ${istl} ${fem} ${femhowto} ${fem-functionals} )
+TARGET_LINK_LIBRARIES( discretelinearfunctional_test ${COMMON_LIBS}  )
+
 #HEADERCHECK( ${header} )
diff --git a/dune/fem/functional/discretelinearfunctional.hh b/dune/fem/functional/discretelinearfunctional.hh
new file mode 100644
index 0000000000000000000000000000000000000000..77ed1646a3ea0c0f18f5d2cd555153ba1709d2f1
--- /dev/null
+++ b/dune/fem/functional/discretelinearfunctional.hh
@@ -0,0 +1,169 @@
+#ifndef DUNE_FEM_FUNCTIONALS_DISCRETELINEARFUNCTIONAL_HH
+#define DUNE_FEM_FUNCTIONALS_DISCRETELINEARFUNCTIONAL_HH
+
+// dune fem-functionals includes
+#include <dune/fem/dofvector/dofvector.hh>
+
+// include this file after all other includes because some of them might undef the macros we want to use
+#include <dune/common/bartonnackmanifcheck.hh>
+
+namespace Dune {
+
+namespace Functionals {
+
+/**
+  * \brief      This class is the interfac for all discrete linear functionals.
+  *
+  * \todo       Doc me, please!
+  **/
+template <class DiscreteLinearFunctionalTraitsImp>
+class DiscreteLinearFunctionalInterface
+{
+public:
+  //! Traits.
+  typedef DiscreteLinearFunctionalTraitsImp Traits;
+
+private:
+  //! For crtp trick.
+  typedef typename Traits::DiscreteLinearFunctionalType DiscreteLinearFunctionalType;
+
+public:
+  //! Type of the function, which induces the functional.
+  typedef typename Traits::InducingFunctionType InducingFunctionType;
+
+  //! Type of the inducing functions range field.
+  typedef typename InducingFunctionType::RangeFieldType RangeFieldType;
+
+  //! Constructor (empty).
+  DiscreteLinearFunctionalInterface()
+  {
+    std::cout << "DiscreteLinearFunctionalInterface::DiscreteLinearFunctionalInterface()" << std::endl;
+  }
+
+  //! Destructor (empty).
+  ~DiscreteLinearFunctionalInterface()
+  {
+    std::cout << "DiscreteLinearFunctionalInterface::~DiscreteLinearFunctionalInterface()" << std::endl;
+  }
+
+  /**
+    * \brief      This operator represents the application of the functional to a discrete function.
+    *
+    *             This operator calls the operator of the derived class.
+    *
+    * \todo       Doc me, please!
+    **/
+  template <class DiscreteFunctionType>
+  RangeFieldType operator()(const DiscreteFunctionType& discreteFunction) const
+  {
+    std::cout << "DiscreteLinearFunctionalInterface::operator()" << std::endl;
+    CHECK_AND_CALL_INTERFACE_IMPLEMENTATION(asImp().operator()(discreteFunction));
+  }
+
+protected:
+  //! For crtp trick.
+  DiscreteLinearFunctionalType& asImp()
+  {
+    return static_cast<DiscreteLinearFunctionalType&>(*this);
+  }
+
+  //! For crtp trick.
+  const DiscreteLinearFunctionalType& asImp() const
+  {
+    return static_cast<const DiscreteLinearFunctionalType&>(*this);
+  }
+
+}; // end DiscreteLinearFunctionalInterface
+
+// forward declaration
+template <class DiscreteLinearFunctionalDefaultTraitsImp>
+class DiscreteLinearFunctionalDefault;
+
+/**
+  * \brief      This class is the traits class for the class DiscreteLinearFunctionalDefault.
+  *
+  * \todo       Doc me, please!
+  **/
+template <class InducingFunctionImp>
+class DiscreteLinearFunctionalDefaultTraits
+{
+public:
+  //! For crtp trick.
+  typedef DiscreteLinearFunctionalDefault<DiscreteLinearFunctionalDefaultTraits> DiscreteLinearFunctionalType;
+
+  //! Type of the function, which induces the functional.
+  typedef InducingFunctionImp InducingFunctionType;
+
+}; // end DiscreteLinearFunctionalDefaultTraits
+
+
+/**
+  * \brief      This class is the default implementation of a discrete linear functional.
+  *
+  *             This class implements the operator() as a gridwalk and calls applyLocal() of the derived class on
+  *             each entity.
+  *
+  * \todo       Doc me, please!
+  **/
+template <class DiscreteLinearFunctionalDefaultTraitsImp>
+class DiscreteLinearFunctionalDefault
+    : public DiscreteLinearFunctionalInterface<DiscreteLinearFunctionalDefaultTraitsImp>
+{
+public:
+  typedef DiscreteLinearFunctionalDefaultTraitsImp Traits;
+
+private:
+  typedef DiscreteLinearFunctionalDefault<Traits> ThisType;
+
+  typedef DiscreteLinearFunctionalInterface<Traits> BaseType;
+
+public:
+  //! Type of the function, which induces the functional.
+  typedef typename Traits::InducingFunctionType InducingFunctionType;
+
+  //! Type of the inducing functions range field.
+  typedef typename InducingFunctionType::RangeFieldType RangeFieldType;
+
+  /**
+    * \brief    Constructor.
+    *
+    *           Calls the constructor of the base class.
+    **/
+  DiscreteLinearFunctionalDefault()
+    : BaseType()
+  {
+    std::cout << "DiscreteLinearFunctionalDefault::DiscreteLinearFunctionalDefault()" << std::endl;
+  }
+
+  /**
+    * \brief    Destructor (empty).
+    **/
+  ~DiscreteLinearFunctionalDefault()
+  {
+    std::cout << "DiscreteLinearFunctionalDefault::~DiscreteLinearFunctionalDefault()" << std::endl;
+  }
+
+  /**
+    * \brief      This operator represents the application of the functional to a discrete function.
+    *
+    *             This operator does a grid walk and calls applyLocal() of the derived class on each entity.
+    *
+    * \todo       Doc me, please!
+    **/
+  template <class DiscreteFunctionType>
+  RangeFieldType operator()(const DiscreteFunctionType& discreteFunction) const
+  {
+    RangeFieldType ret = 0.0;
+
+    std::cout << "DiscreteLinearFunctionalDefault::operator()" << std::endl;
+
+    return ret;
+  }
+
+}; // end class DiscreteLinearFunctionalDefault
+
+} // end namespace Functionals
+
+} // end namespace Dune
+
+#endif // end DUNE_FEM_FUNCTIONALS_DISCRETELINEARFUNCTIONAL_HH
diff --git a/dune/fem/functional/l2functional.hh b/dune/fem/functional/l2functional.hh
index ba1d323455f4206a2b71291ba93c6bd6e8e770d5..8611b3d241a7f64cd33a430eaba649bd57b00f9c 100644
--- a/dune/fem/functional/l2functional.hh
+++ b/dune/fem/functional/l2functional.hh
@@ -9,6 +9,7 @@
 #include <dune/fem/quadrature/cachingquadrature.hh>
 
 // dune fem-functionals includes
+#include <dune/fem/functional/discretelinearfunctional.hh>
 #include <dune/fem/dofvector/dofvector.hh>
 
 // dune fem-tools includes
@@ -41,8 +42,7 @@ public:
   }
 
   /**
-    * \brief      This function represents the application of the functional to a
-    *             discrete function.
+    * \brief      This operator represents the application of the functional to a discrete function.
     *
     * \todo       Doc me, please!
     **/
diff --git a/tests/functional/Makefile.am b/tests/functional/Makefile.am
index 5d26e8553b0909f986df5260c7ceb8dad3997382..4b40dd8f3727fffd20a8a5bc1d81aacfcd3a383c 100644
--- a/tests/functional/Makefile.am
+++ b/tests/functional/Makefile.am
@@ -1,7 +1,9 @@
 
-SUBDIRS =
+GRIDDIM=2
+GRIDTYPE=YASPGRID
+POLORDER=1
 
-noinst_PROGRAMS = l2functional_test
+noinst_PROGRAMS = l2functional_test discretelinearfunctional_test
 
 l2functional_test_SOURCES = l2functional_test.cc
 
@@ -10,7 +12,7 @@ l2functional_test_CPPFLAGS = $(AM_CPPFLAGS) \
 	$(UG_CPPFLAGS) \
 	$(AMIRAMESH_CPPFLAGS) \
 	$(ALBERTA_CPPFLAGS) \
-	$(ALUGRID_CPPFLAGS)
+	$(ALUGRID_CPPFLAGS) -DGRIDDIM=$(GRIDDIM) -D$(GRIDTYPE) -DPOLORDER=$(POLORDER) -Wall -O0 -DDEBUG -funroll-loops -g -ggdb -fno-strict-aliasing -std=c++0x
 # The libraries have to be given in reverse order (most basic libraries
 # last).  Also, due to some misunderstanding, a lot of libraries include the
 # -L option in LDFLAGS instead of LIBS -- so we have to include the LDFLAGS
@@ -31,6 +33,34 @@ l2functional_test_LDFLAGS = $(AM_LDFLAGS) \
 	$(ALUGRID_LDFLAGS) \
 	$(DUNE_LDFLAGS)
 
+discretelinearfunctional_test_SOURCES = discretelinearfunctional_test.cc
+
+discretelinearfunctional_test_CPPFLAGS = $(AM_CPPFLAGS) \
+        $(DUNEMPICPPFLAGS) \
+        $(UG_CPPFLAGS) \
+        $(AMIRAMESH_CPPFLAGS) \
+        $(ALBERTA_CPPFLAGS) \
+        $(ALUGRID_CPPFLAGS) -DGRIDDIM=$(GRIDDIM) -D$(GRIDTYPE) -DPOLORDER=$(POLORDER) -Wall -O0 -DDEBUG -funroll-loops -g -ggdb -fno-strict-aliasing -std=c++0x
+# The libraries have to be given in reverse order (most basic libraries
+# last).  Also, due to some misunderstanding, a lot of libraries include the
+# -L option in LDFLAGS instead of LIBS -- so we have to include the LDFLAGS
+# here as well.
+discretelinearfunctional_test_LDADD = \
+        $(DUNE_LDFLAGS) $(DUNE_LIBS) \
+        $(ALUGRID_LDFLAGS) $(ALUGRID_LIBS) \
+        $(ALBERTA_LDFLAGS) $(ALBERTA_LIBS) \
+        $(AMIRAMESH_LDFLAGS) $(AMIRAMESH_LIBS) \
+        $(UG_LDFLAGS) $(UG_LIBS) \
+        $(DUNEMPILIBS)  \
+        $(LDADD)
+discretelinearfunctional_test_LDFLAGS = $(AM_LDFLAGS) \
+        $(DUNEMPILDFLAGS) \
+        $(UG_LDFLAGS) \
+        $(AMIRAMESH_LDFLAGS) \
+        $(ALBERTA_LDFLAGS) \
+        $(ALUGRID_LDFLAGS) \
+        $(DUNE_LDFLAGS)
+
 # don't follow the full GNU-standard
 # we need automake 1.5
 AUTOMAKE_OPTIONS = foreign 1.5
diff --git a/tests/functional/discretelinearfunctional_test.cc b/tests/functional/discretelinearfunctional_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..70d54bcda93d12ac074476c5cacfc47794dfe452
--- /dev/null
+++ b/tests/functional/discretelinearfunctional_test.cc
@@ -0,0 +1,124 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// system includes
+#include <iostream>
+
+// dune common includes
+#include <dune/common/exceptions.hh>
+
+// dune grid includes
+#include <dune/grid/yaspgrid.hh>
+#include <dune/grid/io/file/dgfparser/dgfparser.hh>
+
+// dune fem includes
+//#include <dune/fem/io/parameter.hh>
+#include <dune/fem/misc/mpimanager.hh>
+#include <dune/fem/gridpart/adaptiveleafgridpart.hh>
+#include <dune/fem/space/common/functionspace.hh>
+#include <dune/fem/function/common/function.hh>
+#include <dune/fem/space/lagrangespace.hh>
+#include <dune/fem/function/adaptivefunction.hh>
+
+// dune fem-functionals includes
+#include <dune/fem/functional/discretelinearfunctional.hh>
+
+// dune fem-tools includes
+#include "../../tools/function/functiontools.hh"
+
+/**
+  * \brief Analytical function which induces the functional.
+  **/
+template <class FunctionSpaceImp>
+class AnalyticalFunction : public Dune::Function<FunctionSpaceImp, AnalyticalFunction<FunctionSpaceImp>>
+{
+public:
+  typedef FunctionSpaceImp FunctionSpaceType;
+  typedef AnalyticalFunction<FunctionSpaceType> ThisType;
+  typedef Dune::Function<FunctionSpaceType, ThisType> BaseType;
+  typedef typename FunctionSpaceType::DomainType DomainType;
+  typedef typename FunctionSpaceType::RangeType RangeType;
+  typedef typename FunctionSpaceType::RangeFieldType RangeFieldType;
+
+  AnalyticalFunction()
+  {
+  }
+
+  ~AnalyticalFunction()
+  {
+  }
+
+  inline void evaluate(const DomainType& arg, RangeType& ret) const
+  {
+    ret = 0.5;
+  }
+};
+
+// main
+int main(int argc, char** argv)
+{
+  try {
+
+    // print welcome
+    std::cout << "Discrete linear functional test:" << std::endl;
+
+    // mpi
+    Dune::MPIManager::initialize(argc, argv);
+
+    // dimension and grid
+    const int dim = 2;
+
+    typedef Dune::YaspGrid<dim> GridType;
+
+    Dune::GridPtr<GridType> gridPtr("unitcube_2d.dgf");
+
+    typedef Dune::AdaptiveLeafGridPart<GridType> GridPartType;
+
+    GridPartType gridPart(*gridPtr);
+
+    // analytical function space and function
+    typedef Dune::FunctionSpace<double, double, dim, 1> AnalyticalFunctionSpaceType;
+    typedef AnalyticalFunction<AnalyticalFunctionSpaceType> AnalyticalFunctionType;
+
+    const AnalyticalFunctionType analyticalFunction;
+
+    // discrete function space and function
+    const int polOrder = 1;
+
+    typedef Dune::LagrangeDiscreteFunctionSpace<AnalyticalFunctionSpaceType, GridPartType, polOrder>
+        DiscreteFunctionSpaceType;
+
+    const DiscreteFunctionSpaceType discreteFunctionSpace(gridPart);
+
+    typedef Dune::AdaptiveDiscreteFunction<DiscreteFunctionSpaceType> DiscreteFunctionType;
+
+    DiscreteFunctionType discreteFunction("discrete_function", discreteFunctionSpace);
+    Dune::FemTools::setDiscreteFunctionToScalarValue(discreteFunction, 2.0);
+
+    // test functional
+    typedef Dune::Functionals::DiscreteLinearFunctionalDefaultTraits<AnalyticalFunctionType>
+        DiscreteLinearFunctionalDefaultTraitsType;
+    typedef Dune::Functionals::DiscreteLinearFunctionalDefault<DiscreteLinearFunctionalDefaultTraitsType>
+        DiscreteLinearFunctionalDefaultType;
+    typedef Dune::Functionals::DiscreteLinearFunctionalInterface<DiscreteLinearFunctionalDefaultTraitsType>
+        DiscreteLinearFunctionalInterfaceType;
+
+    DiscreteLinearFunctionalDefaultType discreteLinearFunctionalDefault;
+
+    //    DiscreteLinearFunctionalInterfaceType discreteLinearFunctionalInterface;
+    discreteLinearFunctionalDefault(discreteFunction);
+
+    //    if ( volume == 1.0 )
+    //      std::cout << "passed!" << std::endl;
+    //    else
+    //      std::cout << "failed (result should equal 1, is " << volume << ")!" << std::endl;
+
+    // we don't make no errors^^
+    return 0;
+  } catch (Dune::Exception& e) {
+    std::cerr << "Dune reported error: " << e << std::endl;
+  } catch (...) {
+    std::cerr << "Unknown exception thrown!" << std::endl;
+  }
+}
diff --git a/tests/functional/l2functional_test.cc b/tests/functional/l2functional_test.cc
index 44763eb7680393d04b6f8b27d0e653a3c4780f2c..b8dd624db4feb2989b9cfd38c9c3db8f45efc735 100644
--- a/tests/functional/l2functional_test.cc
+++ b/tests/functional/l2functional_test.cc
@@ -66,9 +66,6 @@ int main(int argc, char** argv)
     // mpi
     Dune::MPIManager::initialize(argc, argv);
 
-    //    // command line arguments
-    //    Dune::Parameter::append( argc, argv );
-
     // dimension and grid
     const int dim = 2;
 
@@ -103,6 +100,8 @@ int main(int argc, char** argv)
     typedef Dune::Functionals::L2Functional<AnalyticalFunctionType> L2FunctionalType;
     const L2FunctionalType l2Functional(analyticalFunction);
 
+    // functions are chosen to equal 1 when multiplied, thus the application of the functional should yield the volume
+    // of the area, which in turn should be 1 in case of the two-dimensional unitcube
     const double volume = l2Functional(discreteFunction);
 
     if (volume == 1.0)