diff --git a/AMDiS/Makefile.in b/AMDiS/Makefile.in
index 3768bc98a23f2c253803f7a135f0bd6d870ed190..6ce691a54c1077750d645d551287594b0e7964b1 100644
--- a/AMDiS/Makefile.in
+++ b/AMDiS/Makefile.in
@@ -97,11 +97,14 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DUNE_DIR = @DUNE_DIR@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_DUNE_FALSE = @ENABLE_DUNE_FALSE@
+ENABLE_DUNE_TRUE = @ENABLE_DUNE_TRUE@
 ENABLE_MKL_FALSE = @ENABLE_MKL_FALSE@
 ENABLE_MKL_TRUE = @ENABLE_MKL_TRUE@
 ENABLE_UMFPACK_FALSE = @ENABLE_UMFPACK_FALSE@
diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am
index 4401ebb1619595dc56843bd45ae14a5df898bdce..f8d7bfc042c17266299a9879050ff23f5e8c91e5 100644
--- a/AMDiS/bin/Makefile.am
+++ b/AMDiS/bin/Makefile.am
@@ -37,6 +37,11 @@ if ENABLE_MKL
   libamdis_la_CXXFLAGS += -DHAVE_MKL=1 -I${MKL_INC}
 endif
 
+if ENABLE_DUNE
+  libamdis_la_CXXFLAGS += -DHAVE_DUNE=1
+  AMDIS_INCLUDES += -I$(DUNE_DIR)
+endif
+
 INCLUDES = $(AMDIS_INCLUDES) $(PARALLEL_INCLUDES)
 
 if AMDIS_DEBUG
@@ -140,6 +145,7 @@ $(SOURCE_DIR)/TFQMR.h $(SOURCE_DIR)/TFQMR.hh \
 $(SOURCE_DIR)/VecSymSolver.h $(SOURCE_DIR)/VecSymSolver.hh \
 $(SOURCE_DIR)/UmfPackSolver.h $(SOURCE_DIR)/UmfPackSolver.hh \
 $(SOURCE_DIR)/PardisoSolver.h $(SOURCE_DIR)/PardisoSolver.hh $(SOURCE_DIR)/PardisoSolver.cc \
+$(SOURCE_DIR)/DuneSolver.h $(SOURCE_DIR)/DuneSolver.hh $(SOURCE_DIR)/DuneSolver.cc \
 $(SOURCE_DIR)/Lagrange.h $(SOURCE_DIR)/Line.h \
 $(SOURCE_DIR)/MacroElement.h $(SOURCE_DIR)/MacroWriter.h \
 $(SOURCE_DIR)/Markings.h $(SOURCE_DIR)/Markings.hh \
diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in
index 1d1f1f49f284ec6dde01ea99c8263b10d56c0e2d..95c21f6abe9f1699e4e1b2a7ca692f20d4ad4a3b 100644
--- a/AMDiS/bin/Makefile.in
+++ b/AMDiS/bin/Makefile.in
@@ -42,8 +42,10 @@ host_triplet = @host@
 @ENABLE_UMFPACK_TRUE@                    -I$(LIB_DIR)/UMFPACK/Include  
 
 @ENABLE_MKL_TRUE@am__append_3 = -DHAVE_MKL=1 -I${MKL_INC}
-@AMDIS_DEBUG_TRUE@am__append_4 = -g -O0 -Wall -DDEBUG=1 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic
-@AMDIS_DEBUG_FALSE@am__append_5 = -O2 -Wall -DDEBUG=0 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic
+@ENABLE_DUNE_TRUE@am__append_4 = -DHAVE_DUNE=1
+@ENABLE_DUNE_TRUE@am__append_5 = -I$(DUNE_DIR)
+@AMDIS_DEBUG_TRUE@am__append_6 = -g -O0 -Wall -DDEBUG=1 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic
+@AMDIS_DEBUG_FALSE@am__append_7 = -O2 -Wall -DDEBUG=0 $(OPENMP_FLAG) -ftemplate-depth-30 $(INCLUDES) #-pedantic
 subdir = bin
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -179,16 +181,18 @@ am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ConditionalEstimator.h \
 	$(SOURCE_DIR)/VecSymSolver.h $(SOURCE_DIR)/VecSymSolver.hh \
 	$(SOURCE_DIR)/UmfPackSolver.h $(SOURCE_DIR)/UmfPackSolver.hh \
 	$(SOURCE_DIR)/PardisoSolver.h $(SOURCE_DIR)/PardisoSolver.hh \
-	$(SOURCE_DIR)/PardisoSolver.cc $(SOURCE_DIR)/Lagrange.h \
-	$(SOURCE_DIR)/Line.h $(SOURCE_DIR)/MacroElement.h \
-	$(SOURCE_DIR)/MacroWriter.h $(SOURCE_DIR)/Markings.h \
-	$(SOURCE_DIR)/Markings.hh $(SOURCE_DIR)/MemoryManager.h \
-	$(SOURCE_DIR)/Mesh.h $(SOURCE_DIR)/ODirSolver.h \
-	$(SOURCE_DIR)/ODirSolver.hh $(SOURCE_DIR)/OEMSolver.h \
-	$(SOURCE_DIR)/OEMSolver.hh $(SOURCE_DIR)/OResSolver.h \
-	$(SOURCE_DIR)/OResSolver.hh $(SOURCE_DIR)/Parameters.h \
-	$(SOURCE_DIR)/Parametric.h $(SOURCE_DIR)/Preconditioner.h \
-	$(SOURCE_DIR)/Quadrature.h $(SOURCE_DIR)/RCNeighbourList.h \
+	$(SOURCE_DIR)/PardisoSolver.cc $(SOURCE_DIR)/DuneSolver.h \
+	$(SOURCE_DIR)/DuneSolver.hh $(SOURCE_DIR)/DuneSolver.cc \
+	$(SOURCE_DIR)/Lagrange.h $(SOURCE_DIR)/Line.h \
+	$(SOURCE_DIR)/MacroElement.h $(SOURCE_DIR)/MacroWriter.h \
+	$(SOURCE_DIR)/Markings.h $(SOURCE_DIR)/Markings.hh \
+	$(SOURCE_DIR)/MemoryManager.h $(SOURCE_DIR)/Mesh.h \
+	$(SOURCE_DIR)/ODirSolver.h $(SOURCE_DIR)/ODirSolver.hh \
+	$(SOURCE_DIR)/OEMSolver.h $(SOURCE_DIR)/OEMSolver.hh \
+	$(SOURCE_DIR)/OResSolver.h $(SOURCE_DIR)/OResSolver.hh \
+	$(SOURCE_DIR)/Parameters.h $(SOURCE_DIR)/Parametric.h \
+	$(SOURCE_DIR)/Preconditioner.h $(SOURCE_DIR)/Quadrature.h \
+	$(SOURCE_DIR)/RCNeighbourList.h \
 	$(SOURCE_DIRe)/RefinementManager.h \
 	$(SOURCE_DIR)/RefinementManager1d.h \
 	$(SOURCE_DIR)/RefinementManager2d.h \
@@ -270,10 +274,11 @@ am_libamdis_la_OBJECTS = $(am__objects_1) \
 	libamdis_la-DOFVector.lo libamdis_la-Estimator.lo \
 	libamdis_la-ResidualEstimator.lo \
 	libamdis_la-ResidualParallelEstimator.lo \
-	libamdis_la-PardisoSolver.lo libamdis_la-ProblemInstat.lo \
-	libamdis_la-ProblemNonLin.lo libamdis_la-NonLinUpdater.lo \
-	libamdis_la-QPsiPhi.lo libamdis_la-BasisFunction.lo \
-	libamdis_la-Boundary.lo libamdis_la-CoarseningManager.lo \
+	libamdis_la-PardisoSolver.lo libamdis_la-DuneSolver.lo \
+	libamdis_la-ProblemInstat.lo libamdis_la-ProblemNonLin.lo \
+	libamdis_la-NonLinUpdater.lo libamdis_la-QPsiPhi.lo \
+	libamdis_la-BasisFunction.lo libamdis_la-Boundary.lo \
+	libamdis_la-CoarseningManager.lo \
 	libamdis_la-CoarseningManager1d.lo \
 	libamdis_la-CoarseningManager2d.lo \
 	libamdis_la-CoarseningManager3d.lo libamdis_la-demangle.lo \
@@ -361,11 +366,14 @@ CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
+DUNE_DIR = @DUNE_DIR@
 ECHO = @ECHO@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
+ENABLE_DUNE_FALSE = @ENABLE_DUNE_FALSE@
+ENABLE_DUNE_TRUE = @ENABLE_DUNE_TRUE@
 ENABLE_MKL_FALSE = @ENABLE_MKL_FALSE@
 ENABLE_MKL_TRUE = @ENABLE_MKL_TRUE@
 ENABLE_UMFPACK_FALSE = @ENABLE_UMFPACK_FALSE@
@@ -453,7 +461,7 @@ SOURCE_DIR = ../src
 LIB_DIR = ../lib
 PARALLEL_DIR = $(SOURCE_DIR)
 PARMETIS_DIR = ../lib/ParMetis-3.1
-AMDIS_INCLUDES = -I$(SOURCE_DIR) $(am__append_2)
+AMDIS_INCLUDES = -I$(SOURCE_DIR) $(am__append_2) $(am__append_5)
 @USE_PARALLEL_AMDIS_FALSE@PARALLEL_AMDIS_SOURCES = 
 @USE_PARALLEL_AMDIS_TRUE@PARALLEL_AMDIS_SOURCES = \
 @USE_PARALLEL_AMDIS_TRUE@  $(PARALLEL_DIR)/ConditionalEstimator.h $(PARALLEL_DIR)/ConditionalEstimator.cc \
@@ -468,7 +476,7 @@ AMDIS_INCLUDES = -I$(SOURCE_DIR) $(am__append_2)
 @USE_PARALLEL_AMDIS_FALSE@PARALLEL_INCLUDES = 
 @USE_PARALLEL_AMDIS_TRUE@PARALLEL_INCLUDES = -I$(MPI_DIR)/include -I$(PARMETIS_DIR)
 libamdis_la_CXXFLAGS = $(am__append_1) $(am__append_3) $(am__append_4) \
-	$(am__append_5)
+	$(am__append_6) $(am__append_7)
 INCLUDES = $(AMDIS_INCLUDES) $(PARALLEL_INCLUDES)
 libamdis_la_SOURCES = \
 $(PARALLEL_AMDIS_SOURCES) \
@@ -564,6 +572,7 @@ $(SOURCE_DIR)/TFQMR.h $(SOURCE_DIR)/TFQMR.hh \
 $(SOURCE_DIR)/VecSymSolver.h $(SOURCE_DIR)/VecSymSolver.hh \
 $(SOURCE_DIR)/UmfPackSolver.h $(SOURCE_DIR)/UmfPackSolver.hh \
 $(SOURCE_DIR)/PardisoSolver.h $(SOURCE_DIR)/PardisoSolver.hh $(SOURCE_DIR)/PardisoSolver.cc \
+$(SOURCE_DIR)/DuneSolver.h $(SOURCE_DIR)/DuneSolver.hh $(SOURCE_DIR)/DuneSolver.cc \
 $(SOURCE_DIR)/Lagrange.h $(SOURCE_DIR)/Line.h \
 $(SOURCE_DIR)/MacroElement.h $(SOURCE_DIR)/MacroWriter.h \
 $(SOURCE_DIR)/Markings.h $(SOURCE_DIR)/Markings.hh \
@@ -758,6 +767,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DiagonalPreconditioner.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DirichletBC.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DualTraverse.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-DuneSolver.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo1d.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ElInfo2d.Plo@am__quote@
@@ -1274,6 +1284,13 @@ libamdis_la-PardisoSolver.lo: $(SOURCE_DIR)/PardisoSolver.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-PardisoSolver.lo `test -f '$(SOURCE_DIR)/PardisoSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/PardisoSolver.cc
 
+libamdis_la-DuneSolver.lo: $(SOURCE_DIR)/DuneSolver.cc
+@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-DuneSolver.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-DuneSolver.Tpo" -c -o libamdis_la-DuneSolver.lo `test -f '$(SOURCE_DIR)/DuneSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DuneSolver.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-DuneSolver.Tpo" "$(DEPDIR)/libamdis_la-DuneSolver.Plo"; else rm -f "$(DEPDIR)/libamdis_la-DuneSolver.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$(SOURCE_DIR)/DuneSolver.cc' object='libamdis_la-DuneSolver.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-DuneSolver.lo `test -f '$(SOURCE_DIR)/DuneSolver.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/DuneSolver.cc
+
 libamdis_la-ProblemInstat.lo: $(SOURCE_DIR)/ProblemInstat.cc
 @am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ProblemInstat.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo" -c -o libamdis_la-ProblemInstat.lo `test -f '$(SOURCE_DIR)/ProblemInstat.cc' || echo '$(srcdir)/'`$(SOURCE_DIR)/ProblemInstat.cc; \
 @am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo" "$(DEPDIR)/libamdis_la-ProblemInstat.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ProblemInstat.Tpo"; exit 1; fi
diff --git a/AMDiS/configure b/AMDiS/configure
index f825ce09863fe0489067800b5933f6eb764b8a07..db73e119c8d65331e80466e76cf6d00aa417ecb0 100755
--- a/AMDiS/configure
+++ b/AMDiS/configure
@@ -462,7 +462,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT AMDIS_DEBUG_TRUE AMDIS_DEBUG_FALSE CXX CC AMDIS_INTEL_TRUE AMDIS_INTEL_FALSE AMDIS_OPENMP_TRUE AMDIS_OPENMP_FALSE OPENMP_FLAG MPI_DIR USE_PARALLEL_AMDIS_TRUE USE_PARALLEL_AMDIS_FALSE ENABLE_UMFPACK_TRUE ENABLE_UMFPACK_FALSE ENABLE_MKL_TRUE ENABLE_MKL_FALSE CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT AMDIS_DEBUG_TRUE AMDIS_DEBUG_FALSE CXX CC AMDIS_INTEL_TRUE AMDIS_INTEL_FALSE AMDIS_OPENMP_TRUE AMDIS_OPENMP_FALSE OPENMP_FLAG MPI_DIR USE_PARALLEL_AMDIS_TRUE USE_PARALLEL_AMDIS_FALSE ENABLE_UMFPACK_TRUE ENABLE_UMFPACK_FALSE ENABLE_MKL_TRUE ENABLE_MKL_FALSE DUNE_DIR ENABLE_DUNE_TRUE ENABLE_DUNE_FALSE CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -1044,6 +1044,7 @@ Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --with-mpi=MPI_DIR
+  --with-dune=DUNE_DIR
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
   --with-pic              try to use only PIC/non-PIC objects [default=use
                           both]
@@ -2147,6 +2148,27 @@ else
 fi
 
 
+
+# Check whether --with-dune or --without-dune was given.
+if test "${with_dune+set}" = set; then
+  withval="$with_dune"
+  dunedir=$withval
+else
+  dunedir=no
+fi;
+DUNE_DIR=$dunedir
+
+
+
+if test $dunedir != no; then
+  ENABLE_DUNE_TRUE=
+  ENABLE_DUNE_FALSE='#'
+else
+  ENABLE_DUNE_TRUE='#'
+  ENABLE_DUNE_FALSE=
+fi
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4337,7 +4359,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4340 "configure"' > conftest.$ac_ext
+  echo '#line 4362 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5472,7 +5494,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:5475:" \
+echo "$as_me:5497:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -6535,11 +6557,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6538: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6560: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6542: \$? = $ac_status" >&5
+   echo "$as_me:6564: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6803,11 +6825,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6806: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6828: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6810: \$? = $ac_status" >&5
+   echo "$as_me:6832: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6907,11 +6929,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6910: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6932: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:6914: \$? = $ac_status" >&5
+   echo "$as_me:6936: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8376,7 +8398,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 8379 "configure"' > conftest.$ac_ext
+    echo '#line 8401 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -9273,7 +9295,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9276 "configure"
+#line 9298 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9373,7 +9395,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9376 "configure"
+#line 9398 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11716,11 +11738,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11719: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11741: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11723: \$? = $ac_status" >&5
+   echo "$as_me:11745: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -11820,11 +11842,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11823: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11845: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11827: \$? = $ac_status" >&5
+   echo "$as_me:11849: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -12356,7 +12378,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 12359 "configure"' > conftest.$ac_ext
+    echo '#line 12381 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -13414,11 +13436,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13417: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13439: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13421: \$? = $ac_status" >&5
+   echo "$as_me:13443: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13518,11 +13540,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13521: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13543: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13525: \$? = $ac_status" >&5
+   echo "$as_me:13547: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14967,7 +14989,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 14970 "configure"' > conftest.$ac_ext
+    echo '#line 14992 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -15745,11 +15767,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15748: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15770: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15752: \$? = $ac_status" >&5
+   echo "$as_me:15774: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16013,11 +16035,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16016: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16038: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16020: \$? = $ac_status" >&5
+   echo "$as_me:16042: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16117,11 +16139,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16120: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16142: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16124: \$? = $ac_status" >&5
+   echo "$as_me:16146: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17586,7 +17608,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 17589 "configure"' > conftest.$ac_ext
+    echo '#line 17611 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -18984,6 +19006,13 @@ echo "$as_me: error: conditional \"ENABLE_MKL\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${ENABLE_DUNE_TRUE}" && test -z "${ENABLE_DUNE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"ENABLE_DUNE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"ENABLE_DUNE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -19573,6 +19602,9 @@ s,@ENABLE_UMFPACK_TRUE@,$ENABLE_UMFPACK_TRUE,;t t
 s,@ENABLE_UMFPACK_FALSE@,$ENABLE_UMFPACK_FALSE,;t t
 s,@ENABLE_MKL_TRUE@,$ENABLE_MKL_TRUE,;t t
 s,@ENABLE_MKL_FALSE@,$ENABLE_MKL_FALSE,;t t
+s,@DUNE_DIR@,$DUNE_DIR,;t t
+s,@ENABLE_DUNE_TRUE@,$ENABLE_DUNE_TRUE,;t t
+s,@ENABLE_DUNE_FALSE@,$ENABLE_DUNE_FALSE,;t t
 s,@CFLAGS@,$CFLAGS,;t t
 s,@LDFLAGS@,$LDFLAGS,;t t
 s,@CPPFLAGS@,$CPPFLAGS,;t t
diff --git a/AMDiS/configure.ac b/AMDiS/configure.ac
index f05d120a5b64b94b2d6a0997b498084a702c3ba4..cff86ad2e4dbf51068ce47cf9ea95463b03812d4 100644
--- a/AMDiS/configure.ac
+++ b/AMDiS/configure.ac
@@ -81,6 +81,10 @@ AC_ARG_ENABLE(mkl,
   esac],[mkl=false])
 AM_CONDITIONAL(ENABLE_MKL, test $mkl = true)
 
+AC_ARG_WITH(dune, [  --with-dune=DUNE_DIR], dunedir=$withval, dunedir=no)
+AC_SUBST(DUNE_DIR, $dunedir)
+AM_CONDITIONAL(ENABLE_DUNE, test $dunedir != no)
+
 AC_PROG_CC
 AC_PROG_CXX
 AC_PROG_LIBTOOL
diff --git a/AMDiS/src/BiCGStab2.hh b/AMDiS/src/BiCGStab2.hh
index 421876e5bdab6bced69015dc5ef86127667ca50f..5b13cbea399d1521611a688a5132938af0915dc0 100644
--- a/AMDiS/src/BiCGStab2.hh
+++ b/AMDiS/src/BiCGStab2.hh
@@ -103,7 +103,6 @@ namespace AMDiS
     rho0 = 1.0; 
     alpha = 0.0; 
     omega2 = 1.0;
-    //    u->set(0.0);
     setValue(*u, 0.0);
 
     /*------------------------------------------------------------------------*/
@@ -159,7 +158,7 @@ namespace AMDiS
       *u += *r;
       axpy(-alpha, *v, *r);
       axpy(-alpha, *w, *s);
-      
+
       // computing t
       mv->matVec(NoTranspose, *s, *t);
       if (this->leftPrecon) 
@@ -187,7 +186,6 @@ namespace AMDiS
       // updating r
       axpy(-omega1, *s, *r);
       axpy(-omega2, *t, *r);
-      
       /*---  checking accuracy  ----------------------------------------------*/
       
       res = norm(r);
@@ -215,8 +213,8 @@ namespace AMDiS
     }
     
     // returned solution is first with minimal residual
-    *x       = *xmin;
-    iter     = imin;
+    *x = *xmin;
+    iter = imin;
     this->residual = normrmin;
     
     if (this->relative) 
diff --git a/AMDiS/src/CreatorMap.cc b/AMDiS/src/CreatorMap.cc
index 7540681ab8223beab0a2e36720e83bd09e639eef..13694e00fbc770ed42871b6fc04c0435974c6367 100644
--- a/AMDiS/src/CreatorMap.cc
+++ b/AMDiS/src/CreatorMap.cc
@@ -29,6 +29,7 @@
 #include "VecSymSolver.h"
 #include "UmfPackSolver.h"
 #include "PardisoSolver.h"
+#include "DuneSolver.h"
 
 namespace AMDiS {
 
@@ -66,6 +67,11 @@ namespace AMDiS {
 
     creator = NEW TFQMR<DOFVector<double> >::Creator;
     addCreator("tfqmr", creator);
+
+#ifdef HAVE_DUNE
+    creator = NEW DuneSolver< DOFVector<double> >::Creator;
+    addCreator("dune", creator);
+#endif
   }
 
 
@@ -166,6 +172,11 @@ namespace AMDiS {
     creator = NEW PardisoSolver<SystemVector>::Creator;
     addCreator("pardiso", creator);
 #endif
+
+#ifdef HAVE_DUNE
+    creator = NEW DuneSolver<SystemVector>::Creator;
+    addCreator("dune", creator);
+#endif
   }
 
 
diff --git a/AMDiS/src/DOFVector.hh b/AMDiS/src/DOFVector.hh
index 6750a2df439ea4786e05b49b19fdc0f7933c09d1..9e1b315c412b2c2216e2e19ca6df35f04c331334 100644
--- a/AMDiS/src/DOFVector.hh
+++ b/AMDiS/src/DOFVector.hh
@@ -1014,28 +1014,13 @@ namespace AMDiS {
       ("y.size = %d too small: admin->size = %d\n", y.getSize(), 
        x.getFESpace()->getAdmin()->getUsedSize());
     
-      // This is the old implementation of the mv-multiplication. It have been changed
-      // because of the OpenMP-parallelization:
-//     typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS);
-//     typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS);
-//     for(xIterator.reset(), yIterator.reset();
-// 	!xIterator.end();
-// 	++xIterator, ++yIterator) 
-//       {  
-// 	*yIterator += alpha * (*xIterator); 
-//       };
-
-      int i;
-      int maxI = y.getSize();
-
-#ifdef _OPENMP
-#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i)
-#endif
-      for (i = 0; i < maxI; i++) {
-	if (!x.getFESpace()->getAdmin()->isDOFFree(i)) {
-	  y[i] += alpha * x[i];
-	}
-      }
+    typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS);
+    typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS);
+    for (xIterator.reset(), yIterator.reset();
+	 !xIterator.end();
+	 ++xIterator, ++yIterator) {
+      *yIterator += alpha * (*xIterator); 
+    };
   }
 
   template<typename T>
@@ -1081,30 +1066,13 @@ namespace AMDiS {
       ("y.size = %d too small: admin->size = %d\n", y.getSize(), 
        x.getFESpace()->getAdmin()->getUsedSize());
     
-    // This is the old implementation of the mv-multiplication. It have been changed
-    // because of the OpenMP-parallelization:
-    //     typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS);
-    //     typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS);
-    //     for(xIterator.reset(), yIterator.reset();
-    // 	!xIterator.end();
-    // 	++xIterator, ++yIterator) 
-    //       {  
-    // 	*yIterator = alpha *(*yIterator)+ (*xIterator); 
-    //       };
-
-      int i;
-      int maxI = y.getSize();
-
-      const DOFAdmin* admin = x.getFESpace()->getAdmin();
-
-#ifdef _OPENMP
-#pragma omp parallel for schedule(dynamic, 25000) default(shared) private(i)
-#endif
-      for (i = 0; i < maxI; i++) {
-	if (!admin->isDOFFree(i)) {
-	  y[i] = alpha * y[i] + x[i];
-	}
-      }
+    typename DOFVector<T>::Iterator xIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&x)), USED_DOFS);
+    typename DOFVector<T>::Iterator yIterator(dynamic_cast<DOFIndexed<T>*>(&y), USED_DOFS);
+    for (xIterator.reset(), yIterator.reset();
+	 !xIterator.end();
+	 ++xIterator, ++yIterator) {
+      *yIterator = alpha *(*yIterator)+ (*xIterator); 
+    };
   }
 
   template<typename T>
@@ -1114,12 +1082,11 @@ namespace AMDiS {
   {
     typename DOFVector<T>::Iterator vIterator(dynamic_cast<DOFIndexed<T>*>(const_cast<DOFVector<T>*>(&v)), USED_DOFS);
     typename DOFVector<T>::Iterator rIterator(dynamic_cast<DOFIndexed<T>*>(&result), USED_DOFS);
-    for(vIterator.reset(), rIterator.reset();
-	!vIterator.end();
-	++vIterator, ++rIterator) 
-      {  
-	*rIterator = scal * (*vIterator);
-      };
+    for (vIterator.reset(), rIterator.reset();
+	 !vIterator.end();
+	 ++vIterator, ++rIterator) {
+      *rIterator = scal * (*vIterator);
+    };
 
     return result;
   }
diff --git a/AMDiS/src/DuneSolver.cc b/AMDiS/src/DuneSolver.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f0f9d34aab0701248ac000be2a1e35cd03a29adc
--- /dev/null
+++ b/AMDiS/src/DuneSolver.cc
@@ -0,0 +1,139 @@
+#ifdef HAVE_DUNE
+
+#define DUNE_MINIMAL_DEBUG_LEVEL 4
+
+#include <dune/common/fmatrix.hh>
+#include <dune/istl/bvector.hh>
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/ilu.hh>
+#include <dune/istl/operators.hh>
+#include <dune/istl/solvers.hh>
+#include <dune/istl/preconditioners.hh>
+#include <dune/istl/matrix.hh>
+
+#include "DuneSolver.h"
+#include "DOFVector.h"
+
+namespace AMDiS {
+
+  template<>
+  int DuneSolver< DOFVector<double> >::solveSystem(MatVecMultiplier< DOFVector<double> > *mv,
+ 						   DOFVector<double> *x,
+ 						   DOFVector<double> *b)
+  {
+    FUNCNAME("DuneSolver::solveSystem()");
+
+    TEST_EXIT(x->getSize() == b->getSize())("Vectors x and b must have the same size!");
+
+    StandardMatVec<DOFMatrix, DOFVector<double> > *stdMatVec = 
+      dynamic_cast<StandardMatVec<DOFMatrix, DOFVector<double> > *>(mv);
+  
+    DOFMatrix *m = stdMatVec->getMatrix();
+    int nRows = m->getFESpace()->getAdmin()->getUsedSize();
+
+    DuneMatrix duneMatrix(nRows, nRows, DuneMatrix::random);
+    DuneVector duneVecX(nRows);
+    DuneVector duneVecB(nRows);
+
+    mapDOFMatrix(m, &duneMatrix);
+    mapDOFVector(x, &duneVecX);
+    mapDOFVector(b, &duneVecB);
+      
+    MSG("solving system with DUNE ...\n");
+    
+    Dune::MatrixAdapter<DuneMatrix, DuneVector, DuneVector> op(duneMatrix);
+    Dune::InverseOperatorResult opRes;
+    Dune::Preconditioner<DuneVector, DuneVector> *dunePreconditioner = 
+      getPreconditioner<DuneMatrix, DuneVector>(&duneMatrix);
+    Dune::InverseOperator<DuneVector, DuneVector> *duneSolver = 
+      getSolver<DuneMatrix, DuneVector>(&op, dunePreconditioner);
+
+    duneSolver->apply(duneVecX, duneVecB, opRes);
+
+    DuneVector::Iterator duneVecIt;    
+    DOFVector<double>::Iterator vecXIter(x, USED_DOFS);
+    for (vecXIter.reset(), duneVecIt = duneVecX.begin(); 
+	 !vecXIter.end(); 
+	 ++vecXIter, ++duneVecIt) {
+      *vecXIter = *duneVecIt;
+    }
+
+    delete dunePreconditioner;
+    delete duneSolver;
+   
+    return opRes.iterations;
+  }
+
+
+  template<>
+  int DuneSolver<SystemVector>::solveSystem(MatVecMultiplier<SystemVector> *mv,
+					    SystemVector *x, SystemVector *b)
+  {
+    FUNCNAME("DuneSolver::solveSystem()");
+
+    typedef Dune::Matrix<DuneMatrix> SystemDuneMatrix;
+    typedef Dune::BlockVector<DuneVector> SystemDuneVector;
+
+    TEST_EXIT(x->getSize() == b->getSize())("Vectors x and b must have the same size!");
+
+    StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *stdMatVec = 
+      dynamic_cast<StandardMatVec<Matrix<DOFMatrix*>, SystemVector> *>(mv);
+    Matrix<DOFMatrix*> *m = stdMatVec->getMatrix();
+
+    // Number of systems.
+    int nComponents = m->getSize();  
+    // Size of one DOF matrix.
+    int oneMatrixSize = ((*m)[0][0])->getFESpace()->getAdmin()->getUsedSize();
+
+    SystemDuneMatrix duneMatrix(nComponents, nComponents);
+    SystemDuneVector duneVecX(nComponents);
+    SystemDuneVector duneVecB(nComponents);
+
+    for (int i = 0; i < nComponents; i++) {
+      for (int j = 0; j < nComponents; j++) {
+	if ((*m)[i][j]) {
+	  duneMatrix[i][j].setSize(oneMatrixSize, oneMatrixSize);
+	  duneMatrix[i][j].setBuildMode(DuneMatrix::random);
+
+	  mapDOFMatrix((*m)[i][j], &duneMatrix[i][j]);
+	} else {
+	  duneMatrix[i][j].setSize(0, 0);
+	}
+      }
+
+      duneVecX[i].resize(oneMatrixSize, false);      
+      mapDOFVector(x->getDOFVector(i), &duneVecX[i]);      
+
+      duneVecB[i].resize(oneMatrixSize, false);
+      mapDOFVector(b->getDOFVector(i), &duneVecB[i]);
+    }
+
+    MSG("solving system with DUNE ...\n");
+    
+    Dune::MatrixAdapter<SystemDuneMatrix, SystemDuneVector, SystemDuneVector> op(duneMatrix);
+    Dune::InverseOperatorResult opRes;
+    Dune::Preconditioner<SystemDuneVector, SystemDuneVector> *dunePreconditioner =
+      getSystemPreconditioner<SystemDuneMatrix, SystemDuneVector>(&duneMatrix);
+    Dune::InverseOperator<SystemDuneVector, SystemDuneVector> *duneSolver =
+      getSolver<SystemDuneMatrix, SystemDuneVector>(&op, dunePreconditioner);
+
+    duneSolver->apply(duneVecX, duneVecB, opRes);
+
+    for (int i = 0; i < nComponents; i++) {
+      DuneVector::Iterator duneVecIt;    
+      DOFVector<double>::Iterator vecXIter(x->getDOFVector(i), USED_DOFS);
+      for (vecXIter.reset(), duneVecIt = duneVecX[i].begin(); 
+	   !vecXIter.end(); 
+	   ++vecXIter, ++duneVecIt) {
+	*vecXIter = *duneVecIt;
+      }
+    }
+
+    delete dunePreconditioner;
+    delete duneSolver;
+   
+    return opRes.iterations;
+  }
+}
+
+#endif // HAVE_DUNE
diff --git a/AMDiS/src/DuneSolver.h b/AMDiS/src/DuneSolver.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4c24cb24168d30144cc3e0c30437f8090e5c24e
--- /dev/null
+++ b/AMDiS/src/DuneSolver.h
@@ -0,0 +1,178 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  crystal growth group                                                  ==
+// ==                                                                        ==
+// ==  Stiftung caesar                                                       ==
+// ==  Ludwig-Erhard-Allee 2                                                 ==
+// ==  53175 Bonn                                                            ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  http://www.caesar.de/cg/AMDiS                                         ==
+// ==                                                                        ==
+// ============================================================================
+
+/** \file DuneSolver.h */
+
+#ifndef AMDIS_DUNESOLVER_H
+#define AMDIS_DUNESOLVER_H
+
+#ifdef HAVE_DUNE
+
+#define DUNE_MINIMAL_DEBUG_LEVEL 4
+
+#include <dune/common/fmatrix.hh>
+#include <dune/istl/bvector.hh>
+#include <dune/istl/bcrsmatrix.hh>
+
+#include <dune/istl/bvector.hh>
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/ilu.hh>
+#include <dune/istl/operators.hh>
+#include <dune/istl/solvers.hh>
+#include <dune/istl/preconditioners.hh>
+#include <dune/istl/matrix.hh>
+
+#include "DOFVector.h"
+#include "OEMSolver.h"
+#include "MemoryManager.h"
+
+namespace AMDiS {
+  // ============================================================================
+  // ===== class DuneSolver =====================================================
+  // ============================================================================
+
+  typedef Dune::BCRSMatrix< Dune::FieldMatrix<double, 1, 1> > DuneMatrix;
+  typedef Dune::BlockVector< Dune::FieldVector<double, 1> > DuneVector;
+  
+  /**
+   * \ingroup Solver
+   * 
+   * \brief
+   * Uses ISTL-module from the DUNE project (www.dune-project.com) to solve a
+   * linear system of equations.
+   */
+  template<typename VectorType>
+  class DuneSolver : public OEMSolver<VectorType>
+  {
+  public:
+    MEMORY_MANAGED(DuneSolver<VectorType>);
+
+    /** \brief
+     * Creator class used in the OEMSolverMap.
+     */
+    class Creator : public OEMSolverCreator<VectorType>
+    {
+    public:
+      MEMORY_MANAGED(Creator);
+      
+      virtual ~Creator() {};
+      
+      /** \brief
+       * Returns a new DuneSolver object.
+       */
+      OEMSolver<VectorType>* create() { 
+	return NEW DuneSolver<VectorType>(this->name); 
+      };
+    };
+
+    /** \brief
+     * constructor
+     */
+    DuneSolver(::std::string name);
+    
+    /** \brief
+     * destructor
+     */
+    ~DuneSolver();
+
+  protected:
+    /** \brief
+     * DUNE's solver verbose mode:
+     *   0 : print nothing
+     *   1 : print initial and final defect and statistics
+     *   2 : print line for each iteration
+     */
+    int verbose_;
+
+    /** \brief
+     * DUNE's solver to be used.
+     */
+    ::std::string solverType_;
+
+    /** \brief
+     * DUNE's preconditioner to be used.
+     */
+    ::std::string preconType_;
+
+    /** \brief
+     * Relaxation factor for the preconditioner.
+     */
+    double preconRelaxation_;
+
+    /** \brief
+     * Number of iterations for the preconditioner.
+     */
+    int preconIterations_;
+
+    /** \brief
+     * Implements OEMSolver<VectorType>::init().
+     */
+    void init() {};
+    
+    /** \brief
+     * Implements OEMSolver<VectorType>::exit().
+     */
+    void exit() {};
+
+    /** \brief
+     * Creates a dune preconditioner using the informations in the used init file. 
+     */
+    template<typename M, typename V>
+    Dune::Preconditioner<V, V>* getPreconditioner(M *matrix);
+
+
+    /** \brief
+     * Creates a dune preconditioner for systems of equations using the informations
+     * in the used init file.
+     */
+    template<typename M, typename V>
+    Dune::Preconditioner<V, V>* getSystemPreconditioner(M *matrix);
+
+
+    /** \brief
+     * Creates a dune solver using the informations in the used init file.
+     */
+    template<typename M, typename V>
+    Dune::InverseOperator<V, V>* getSolver(Dune::MatrixAdapter<M, V, V>* ma,
+					   Dune::Preconditioner<V, V>* precon);
+
+    /** \brief
+     * Implements OEMSolver<VectorType>::solve().
+     */
+    int solveSystem(MatVecMultiplier<VectorType> *mv, VectorType *x, VectorType *b);
+
+    /** \brief
+     * Copies the data of one DOFMatrix to one DuneMatrix. The DuneMatrix has
+     * to be allocated before.
+     */
+    void mapDOFMatrix(DOFMatrix *dofMatrix, DuneMatrix *duneMatrix);
+
+    /** \brief
+     * Copies the data of one DOFVector to one DuneVector. The DuneVector has
+     * to be allocated before.
+     */
+    void mapDOFVector(DOFVector<double> *dofVector, DuneVector *duneVector);
+  };
+}
+
+#include "DuneSolver.hh"
+
+#endif // HAVE_DUNE
+
+#endif // AMDIS_DUNESOLVER_H
diff --git a/AMDiS/src/DuneSolver.hh b/AMDiS/src/DuneSolver.hh
new file mode 100644
index 0000000000000000000000000000000000000000..6b016ff85b94c30f3438c0c58b1c69398f389b1b
--- /dev/null
+++ b/AMDiS/src/DuneSolver.hh
@@ -0,0 +1,148 @@
+#include "DOFVector.h"
+
+#include <dune/istl/bvector.hh>
+#include <dune/istl/bcrsmatrix.hh>
+#include <dune/istl/ilu.hh>
+#include <dune/istl/operators.hh>
+#include <dune/istl/solvers.hh>
+#include <dune/istl/preconditioners.hh>
+#include <dune/istl/matrix.hh>
+
+namespace AMDiS {
+
+  template<typename VectorType>
+  DuneSolver<VectorType>::DuneSolver(::std::string name)   
+    : OEMSolver<VectorType>(name),
+      verbose_(1),
+      solverType_(""),
+      preconType_(""),
+      preconRelaxation_(1.0),
+      preconIterations_(1)
+  {
+    GET_PARAMETER(0, name + "->dune verbose", "%d", &verbose_);
+    GET_PARAMETER(0, name + "->dune solver", &solverType_);
+    GET_PARAMETER(0, name + "->dune precon", &preconType_);
+
+    GET_PARAMETER(0, name + "->dune precon->relaxation", "%f", &preconRelaxation_);
+    GET_PARAMETER(0, name + "->dune precon->iterations", "%d", &preconIterations_);
+
+    TEST_EXIT(solverType_ != "")("No DUNE solver chosen!\n");
+    TEST_EXIT(preconType_ != "")("No DUNE preconditioner chosen!\n");
+  }
+
+
+  template<typename VectorType>
+  DuneSolver<VectorType>::~DuneSolver()
+  {}
+
+
+  template<typename VectorType> 
+  template<typename M, typename V>
+  Dune::Preconditioner<V, V>* DuneSolver<VectorType>::getPreconditioner(M *matrix)
+  {
+    if (preconType_ == "ilu0") {
+      return new Dune::SeqILU0<M, V, V>(*matrix, preconRelaxation_);
+    } else if (preconType_ == "ilun") {
+      return new Dune::SeqILUn<M, V, V>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "jac") {
+      return new Dune::SeqJac<M, V, V>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "gs") {
+      return new Dune::SeqGS<M, V, V>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "sor") {
+      return new Dune::SeqSOR<M, V, V>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "ssor") {
+      return new Dune::SeqSSOR<M, V, V>(*matrix, preconIterations_, preconRelaxation_);
+    };
+
+    ERROR_EXIT("Wrong DUNE preconditioner type!\n");
+
+    return NULL;
+  }
+
+
+  template<typename VectorType> 
+  template<typename M, typename V>
+  Dune::Preconditioner<V, V>* DuneSolver<VectorType>::getSystemPreconditioner(M *matrix)
+  {
+    if (preconType_ == "ilu0") {
+      ERROR_EXIT("ILU0 is not supported for systems!\n");
+    } else if (preconType_ == "ilun") {
+      ERROR_EXIT("ILUN is not supported for systems!\n");
+    } else if (preconType_ == "jac") {
+      return new Dune::SeqJac<M, V, V, 2>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "gs") {
+      return new Dune::SeqGS<M, V, V, 2>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "sor") {
+      return new Dune::SeqSOR<M, V, V, 2>(*matrix, preconIterations_, preconRelaxation_);
+    } else if (preconType_ == "ssor") {
+      return new Dune::SeqSSOR<M, V, V, 2>(*matrix, preconIterations_, preconRelaxation_);
+    };
+
+    ERROR_EXIT("Wrong DUNE preconditioner type!\n");
+
+    return NULL;
+  }
+
+
+  template<typename VectorType>
+  template<typename M, typename V>
+  Dune::InverseOperator<V, V>* DuneSolver<VectorType>::getSolver(Dune::MatrixAdapter<M, V, V>* ma,
+								 Dune::Preconditioner<V, V>* precon)
+  {
+    if (solverType_ == "bicgstab") {      
+      return new Dune::BiCGSTABSolver<V>(*ma, *precon, this->tolerance, this->max_iter, verbose_);
+    } else if (solverType_ == "cg") {
+      return new Dune::CGSolver<V>(*ma, *precon, this->tolerance, this->max_iter, verbose_);
+    } else if (solverType_ == "gradient") {
+      return new Dune::GradientSolver<V>(*ma, *precon, this->tolerance, this->max_iter, verbose_); 
+    } else if (solverType_ == "loop") {
+      return new Dune::LoopSolver<V>(*ma, *precon, this->tolerance, this->max_iter, verbose_);
+    }
+
+    ERROR_EXIT("Wrong DUNE solver type!\n");
+    
+    return NULL;
+  }
+ 
+
+  template<typename VectorType>
+  void DuneSolver<VectorType>::mapDOFMatrix(DOFMatrix *dofMatrix, DuneMatrix *duneMatrix)
+  {
+    int rowIndex = 0;
+    DOFMatrix::Iterator matrixRowIt(dofMatrix, USED_DOFS);
+    for (matrixRowIt.reset(); !matrixRowIt.end(); ++matrixRowIt, rowIndex++) {
+      duneMatrix->setrowsize(rowIndex, (*matrixRowIt).size());
+    }
+    
+    duneMatrix->endrowsizes();
+    
+    rowIndex = 0;
+    for (matrixRowIt.reset(); !matrixRowIt.end(); ++matrixRowIt, rowIndex++) {
+      int nCols = static_cast<int>((*matrixRowIt).size());
+      for (int i = 0; i < nCols; i++) {
+	duneMatrix->addindex(rowIndex, (*matrixRowIt)[i].col);
+      }   
+    }
+    
+    duneMatrix->endindices();
+    
+    DuneMatrix::Iterator duneMatIt = duneMatrix->begin();
+    for (matrixRowIt.reset(); !matrixRowIt.end(); ++matrixRowIt, ++duneMatIt) {   
+      int nCols = static_cast<int>((*matrixRowIt).size());
+      for (int i = 0; i < nCols; i++) {
+	(*duneMatIt)[(*matrixRowIt)[i].col] = (*matrixRowIt)[i].entry;
+      }   
+    }
+
+  }
+
+  template<typename VectorType>
+  void DuneSolver<VectorType>::mapDOFVector(DOFVector<double> *dofVector, DuneVector *duneVector)
+  {
+    DuneVector::Iterator duneVecIt = duneVector->begin();
+    DOFVector<double>::Iterator dofVecIt(dofVector, USED_DOFS);
+    for (dofVecIt.reset(); !dofVecIt.end(); ++dofVecIt, ++duneVecIt) {
+      *duneVecIt = *dofVecIt;
+    }
+  }
+}
diff --git a/AMDiS/src/Preconditioner.h b/AMDiS/src/Preconditioner.h
index eb3c0f96ebe3c845bd7594f29b5196c49cd5ab54..ccea6bd7aeed0ee5205d6273a6086d8171f31c1d 100644
--- a/AMDiS/src/Preconditioner.h
+++ b/AMDiS/src/Preconditioner.h
@@ -237,7 +237,11 @@ namespace AMDiS {
      * Initialisation of the preconditioner
      */
     virtual void init() {
-      for (int i = 0; i < scalPrecons.getSize(); i++) {
+      int i;
+      int size = scalPrecons.getSize();
+
+#pragma omp parallel for
+      for (i = 0; i < size; i++) {
 	scalPrecons[i]->init();
       }
     };
@@ -246,7 +250,11 @@ namespace AMDiS {
      * Preconditioning method
      */
     virtual void precon(SystemVector *x) {
-      for (int i = 0; i < scalPrecons.getSize(); i++) {
+      int i;
+      int size = scalPrecons.getSize();
+
+#pragma omp parallel for
+      for (i = 0; i < size; i++) {
 	scalPrecons[i]->precon(x->getDOFVector(i));
       }
     };
@@ -255,7 +263,11 @@ namespace AMDiS {
      * Frees needed memory.
      */
     virtual void  exit() {
-      for (int i = 0; i < scalPrecons.getSize(); i++) {
+      int i;
+      int size = scalPrecons.getSize();
+
+#pragma omp parallel for
+      for (i = 0; i < size; i++) {
 	scalPrecons[i]->exit();
       }
     };
diff --git a/AMDiS/src/SystemVector.h b/AMDiS/src/SystemVector.h
index 5269f51114b1e54d9bc152f765b7a85e20ed6b44..226f27a4da793e3ab347f0d52edfc6053e1f2d2b 100644
--- a/AMDiS/src/SystemVector.h
+++ b/AMDiS/src/SystemVector.h
@@ -469,12 +469,14 @@ namespace AMDiS {
 		 bool               add = false)
   {
     int size = x.getNumVectors();
+    int i;
 
     TEST_EXIT_DBG(size == result.getNumVectors())("incompatible sizes\n");
     TEST_EXIT_DBG(size == matrix.getNumRows())("incompatible sizes\n");
     TEST_EXIT_DBG(size == matrix.getNumCols())("incompatible sizes\n");
-    
-    for (int i = 0; i < size; i++) {
+
+#pragma omp parallel for schedule(static, 1)    
+    for (i = 0; i < size; i++) {
       if (!add) 
 	result.getDOFVector(i)->set(0.0);
 
@@ -499,8 +501,10 @@ namespace AMDiS {
           ("invalid size\n");
 
     int size = x.getNumVectors();
+    int i;
 
-    for (int i = 0; i < size; i++) {
+#pragma omp parallel for schedule(static, 1)
+    for (i = 0; i < size; i++) {
       axpy(a, *(x.getDOFVector(i)), *(y.getDOFVector(i)));
     }
   };