diff --git a/istl/paamg/amg.hh b/istl/paamg/amg.hh
index a8eab6068d8f13fb49b4db6b7f3b2b358108e4c7..34ac5667c933a3036d3d12be97fd648cf0d5b838 100644
--- a/istl/paamg/amg.hh
+++ b/istl/paamg/amg.hh
@@ -1,9 +1,10 @@
 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 // vi: set et ts=4 sw=2 sts=2:
-// $Id : $
+// $Id$
 #ifndef DUNE_AMG_AMG_HH
 #define DUNE_AMG_AMG_HH
 
+#include <memory>
 #include <dune/istl/paamg/smoother.hh>
 #include <dune/istl/paamg/transfer.hh>
 #include <dune/istl/paamg/hierarchy.hh>
@@ -23,7 +24,7 @@ namespace Dune
      * @author Markus Blatt
      * @brief The AMG preconditioner.
      */
-    template<class M, class X, class Y, class CS, class S, class A>
+    template<class M, class X, class Y, class CS, class S, class A=std::allocator<X> >
     class AMG : public Preconditioner<X,Y>
     {
     public:
@@ -65,14 +66,16 @@ namespace Dune
 
       void post(Domain& x);
 
+    private:
+      /** @brief Multigrid cycle on a level. */
       void mgc(typename Hierarchy<Smoother,A>::Iterator& smoother,
-               const typename MatrixHierarchy::Iterator& matrix,
+               typename MatrixHierarchy::ParallelMatrixHierarchy::ConstIterator& matrix,
+               typename MatrixHierarchy::AggregatesMapList::const_iterator& aggregates,
                typename Hierarchy<Domain,A>::Iterator& lhs,
                typename Hierarchy<Domain,A>::Iterator& update,
                typename Hierarchy<Range,A>::Iterator& rhs,
                typename Hierarchy<Range,A>::Iterator& defect);
 
-    private:
       /**  @brief The matrix we solve. */
       const MatrixHierarchy* matrices_;
       /** @brief The arguments to construct the smoother */
@@ -80,7 +83,7 @@ namespace Dune
       /** @brief The hierarchy of the smoothers. */
       Hierarchy<Smoother,A> smoothers_;
       /** @brief The solver of the coarsest level. */
-      const CoarseSolver* solver_;
+      CoarseSolver* solver_;
       /** @brief The right hand side of our problem. */
       Hierarchy<Range,A>* rhs_;
       /** @brief The current defect. */
@@ -89,28 +92,24 @@ namespace Dune
       Hierarchy<Domain,A>* lhs_;
       /** @brief The  vectors to store the update in. */
       Hierarchy<Domain,A>* update_;
+      /** @brief Gamma, 1 for V-cycle and 2 for W-cycle. */
       std::size_t gamma_;
+      /** @brief The number of pre and postsmoothing steps. */
       std::size_t steps_;
+      std::size_t level;
     };
 
     template<class M, class X, class Y, class CS, class S, class A>
     AMG<M,X,Y,CS,S,A>::AMG(const MatrixHierarchy& matrices, CoarseSolver& coarseSolver,
                            const SmootherArgs& smootherArgs,
                            std::size_t gamma, std::size_t smoothingSteps)
-      : matrices_(&matrices), solver_(coarseSolver), smootherArgs_(smootherArgs),
-        smoothers_(), solver_(0), rhs_(), defect_(), lhs_(), update_(), gamma_(gamma),
+      : matrices_(&matrices), smootherArgs_(smootherArgs),
+        smoothers_(), solver_(&coarseSolver), gamma_(gamma),
         steps_(smoothingSteps)
     {
-      assert(matrices_.built());
-      // Initialize smoother on the finest level if necessary
-      if(smoothers_.levels()==0) {
-        typename SmootherTraits<S>::Arguments args;
-        args.setMatrix(matrices_.finest()->matrix());
-        args.setArgs(smootherArgs_);
-        smoothers_.addCoarser(args);
-      }
+      assert(matrices_->isBuilt());
       // build the necessary smoother hierarchies
-      matrices_.coarsenSmoother(smoothers_, smootherArgs_);
+      matrices_->coarsenSmoother(smoothers_, smootherArgs_);
 
     }
 
@@ -118,17 +117,17 @@ namespace Dune
     void AMG<M,X,Y,CS,S,A>::pre(X& x, Y& b)
     {
       Y* copy = new Y(b);
-      rhs_ = new Hierarchy<Range,A>(copy);
+      rhs_ = new Hierarchy<Range,A>(*copy);
       copy = new Y(b);
-      defect_ = new Hierarchy<Range,A>(copy);
+      defect_ = new Hierarchy<Range,A>(*copy);
       copy = new X(x);
-      lhs_ = new Hierarchy<Domain,A>(copy);
+      lhs_ = new Hierarchy<Domain,A>(*copy);
       copy = new X(x);
-      update_ = new Hierarchy<Domain,A>(copy);
-      matrices_.coarsenVector(*rhs_);
-      matrices_.coarsenVector(*defect_);
-      matrices_.coarsenVector(*lhs_);
-      matrices_.coarsenVector(*update_);
+      update_ = new Hierarchy<Domain,A>(*copy);
+      matrices_->coarsenVector(*rhs_);
+      matrices_->coarsenVector(*defect_);
+      matrices_->coarsenVector(*lhs_);
+      matrices_->coarsenVector(*update_);
 
       // Preprocess all smoothers
       typedef typename Hierarchy<Smoother,A>::Iterator Iterator;
@@ -136,13 +135,13 @@ namespace Dune
       typedef typename Hierarchy<Domain,A>::Iterator DIterator;
       Iterator coarsest = smoothers_.coarsest();
       Iterator smoother = smoothers_.finest();
-      RIterator rhs = rhs_.finest();
-      DIterator lhs = lhs_.finest();
+      RIterator rhs = rhs_->finest();
+      DIterator lhs = lhs_->finest();
 
-      smoother.pre(*lhs,*rhs);
+      smoother->pre(*lhs,*rhs);
 
       for(++smoother, ++lhs, ++rhs; smoother != coarsest; ++smoother, ++lhs, ++rhs)
-        smoother.pre(*lhs,*rhs);
+        smoother->pre(*lhs,*rhs);
     }
 
     template<class M, class X, class Y, class CS, class S, class A>
@@ -151,32 +150,36 @@ namespace Dune
       *(lhs_->finest())=v;
       *(rhs_->finest())=d;
 
-      //Create the iterator over the levels
+      typename Hierarchy<Smoother,A>::Iterator smoother = smoothers_.finest();
+      typename MatrixHierarchy::ParallelMatrixHierarchy::ConstIterator matrix = matrices_->matrices().finest();
+      typename MatrixHierarchy::AggregatesMapList::const_iterator aggregates = matrices_->aggregatesMaps().begin();
+      typename Hierarchy<Domain,A>::Iterator lhs = lhs_->finest();
+      typename Hierarchy<Domain,A>::Iterator update = update_->finest();
+      typename Hierarchy<Range,A>::Iterator rhs = rhs_->finest();
+      typename Hierarchy<Range,A>::Iterator defect = defect_->finest();
 
-      // Coarsest level
-      typename Hierarchy<Domain>::Iterator coarsest =
-        mgc(smoothers_.finest, matrices_.finest(), lhs_.finest(),
-            update_.finest(), rhs_.finest(), defect_.finest());
+      level=0;
+      mgc(smoother, matrix, aggregates, lhs, update, rhs, defect);
     }
 
     template<class M, class X, class Y, class CS, class S, class A>
     void AMG<M,X,Y,CS,S,A>::mgc(typename Hierarchy<Smoother,A>::Iterator& smoother,
-                                const typename MatrixHierarchy::Iterator& matrix,
+                                typename MatrixHierarchy::ParallelMatrixHierarchy::ConstIterator& matrix,
+                                typename MatrixHierarchy::AggregatesMapList::const_iterator& aggregates,
                                 typename Hierarchy<Domain,A>::Iterator& lhs,
                                 typename Hierarchy<Domain,A>::Iterator& update,
                                 typename Hierarchy<Range,A>::Iterator& rhs,
-                                typename Hierarchy<Range,A>::Iterator& defect)
-    {
-      if(matrix == matrices_.coarsest()) {
+                                typename Hierarchy<Range,A>::Iterator& defect){
+      if(matrix == matrices_->matrices().coarsest()) {
         // Solve directly
         InverseOperatorResult res;
-        solver_.apply(*lhs, rhs, res);
+        solver_->apply(*lhs, *rhs, res);
       }else{
         // presmoothing
-        for(int i=0; i < steps_; ++i) {
+        for(std::size_t i=0; i < steps_; ++i) {
           // calculate defect
           *defect = *rhs;
-          matrix().matrix().mmv(*lhs, *defect);
+          matrix->matrix().mmv(*lhs, *defect);
 
           // smooth
           smoother->apply(*update, *rhs);
@@ -187,43 +190,46 @@ namespace Dune
 
         // calculate defect
         *defect = *rhs;
-        matrix().matrix().mmv(*lhs, *defect);
+        matrix->matrix().mmv(*lhs, *defect);
 
         //restrict defect to coarse level right hand side.
         ++rhs;
 
-        Transfer<typename MatrixHierarchy::AggregatesMap::Vertex,Range>::restrict (matrix->aggregates(),
-                                                                                   rhs,
-                                                                                   defect);
+        Transfer<typename MatrixHierarchy::AggregatesMap::AggregateDescriptor,Range>
+        ::restrict (*(*aggregates), *rhs, *defect);
+
         // prepare coarse system
-        ++lhs=0;
+        ++lhs;
         ++update;
         ++defect;
         ++smoother;
         ++matrix;
+        ++aggregates;
+        ++level;
+        *lhs=0;
 
         // next level
-        mgc(smoother, matrix, lhs, update, rhs, defect);
-
+        mgc(smoother, matrix, aggregates, lhs, update, rhs, defect);
 
+        --level;
         //prolongate (coarse x is the new update)
         --matrix;
+        --aggregates;
         --update;
-        Transfer<typename MatrixHierarchy::AggregatesMap::Vertex,Range>::prolongate(matrix->aggregates(),
-                                                                                    update,
-                                                                                    lhs,
-                                                                                    0.8);
+        Transfer<typename MatrixHierarchy::AggregatesMap::AggregateDescriptor,Range>
+        ::prolongate(*(*aggregates), *update, *lhs, 0.8);
+
         --lhs;
         --rhs;
         --defect;
         --smoother;
 
         // postsmoothing
-        for(int i=0; i < steps_; ++i) {
+        for(std::size_t i=0; i < steps_; ++i) {
 
           // calculate defect
           *defect = *rhs;
-          matrix().matrix().mmv(*lhs, *defect);
+          matrix->matrix().mmv(*lhs, *defect);
 
           // smooth
           smoother->apply(*update, *defect);
@@ -243,20 +249,20 @@ namespace Dune
       typedef typename Hierarchy<Domain,A>::Iterator DIterator;
       Iterator coarsest = smoothers_.coarsest();
       Iterator smoother = smoothers_.finest();
-      DIterator lhs = lhs_.finest();
+      DIterator lhs = lhs_->finest();
 
-      smoother.post(*lhs);
+      smoother->post(*lhs);
 
       for(++smoother; smoother != coarsest; ++smoother, ++lhs)
-        smoother.post(*lhs);
+        smoother->post(*lhs);
 
-      delete &(*update_.finest());
+      delete &(*update_->finest());
       delete update_;
-      delete &(*lhs_.finest());
+      delete &(*lhs_->finest());
       delete lhs_;
-      delete &(*defect_.finest());
+      delete &(*defect_->finest());
       delete defect_;
-      delete &(*rhs_.finest());
+      delete &(*rhs_->finest());
       delete rhs_;
     }
   } // end namespace Amg
diff --git a/istl/paamg/hierarchy.hh b/istl/paamg/hierarchy.hh
index 9b2a9560c3fae0c167e0c95b37be4cbca9ee67a1..7a9f8382b77b79d9bd5b7c83c71be92f61c27632 100644
--- a/istl/paamg/hierarchy.hh
+++ b/istl/paamg/hierarchy.hh
@@ -297,7 +297,11 @@ namespace Dune
       typedef A Allocator;
       /** @brief The type of the aggregates map we use. */
       typedef AggregatesMap<typename MatrixGraph<M>::VertexDescriptor> AggregatesMap;
+      /** @brief The type of the parallel matrix hierarchy. */
+      typedef Hierarchy<ParallelMatrix,Allocator> ParallelMatrixHierarchy;
 
+      /** @brief The type of the aggregates maps list. */
+      typedef std::list<AggregatesMap*,Allocator> AggregatesMapList;
       /**
        * @brief Constructor
        * @param fineMatrix The matrix to coarsen.
@@ -324,8 +328,8 @@ namespace Dune
       template<class V, class TA>
       void coarsenVector(Hierarchy<BlockVector<V,TA> >& hierarchy) const;
 
-      template<class S>
-      void coarsenSmoother(Hierarchy<S>& smoothers,
+      template<class S, class TA>
+      void coarsenSmoother(Hierarchy<S,TA>& smoothers,
                            const typename SmootherTraits<S>::Arguments& args) const;
 
       /**
@@ -340,15 +344,16 @@ namespace Dune
        */
       bool isBuilt() const;
 
+      const ParallelMatrixHierarchy& matrices() const;
+
+      const AggregatesMapList& aggregatesMaps() const;
+
     private:
       typedef typename ConstructionTraits<ParallelMatrix>::Arguments MatrixArgs;
-      /** @brief The type of the aggregates maps list. */
-      typedef std::list<AggregatesMap*,Allocator> AggregatesMapList;
       /** @brief The list of aggregates maps. */
-      AggregatesMapList aggregatesMaps;
-      typedef Hierarchy<ParallelMatrix,Allocator> MMatrixHierarchy;
+      AggregatesMapList aggregatesMaps_;
       /** @brief The hierarchy of parallel matrices. */
-      MMatrixHierarchy matrices_;
+      ParallelMatrixHierarchy matrices_;
       typedef Hierarchy<Interface,Allocator> InterfaceHierarchy;
       /** @brief The hierarchy of interfaces. */
       InterfaceHierarchy interfaces_;
@@ -361,7 +366,7 @@ namespace Dune
 
       template<class T>
       bool coarsenTargetReached(const T& crit,
-                                const typename MMatrixHierarchy::Iterator& matrix);
+                                const typename ParallelMatrixHierarchy::Iterator& matrix);
     };
 
     template<class T>
@@ -428,7 +433,7 @@ namespace Dune
     template<typename T>
     inline bool
     MatrixHierarchy<M,IS,O,A>::coarsenTargetReached(const T& crit,
-                                                    const typename MMatrixHierarchy::Iterator& matrix)
+                                                    const typename ParallelMatrixHierarchy::Iterator& matrix)
     {
       int nodes = matrix->matrix().N();
       int totalNodes;
@@ -444,7 +449,7 @@ namespace Dune
     {
       GalerkinProduct productBuilder;
       int procs;
-      typedef typename MMatrixHierarchy::Iterator MatIterator;
+      typedef typename ParallelMatrixHierarchy::Iterator MatIterator;
       typedef typename InterfaceHierarchy::Iterator InterfaceIterator;
       typedef typename CommunicatorHierarchy::Iterator CommIterator;
 
@@ -479,7 +484,7 @@ namespace Dune
         PropertiesGraph pg(sg, IdentityMap(), sg.getEdgeIndexMap());
         AggregatesMap* aggregatesMap=new AggregatesMap(pg.maxVertex());
 
-        aggregatesMaps.push_back(aggregatesMap);
+        aggregatesMaps_.push_back(aggregatesMap);
 
         int noAggregates = aggregatesMap->buildAggregates(mlevel->matrix(), pg, criterion);
 
@@ -536,16 +541,31 @@ namespace Dune
         matrices_.addCoarser(MatrixArgs(*coarseMatrix, *coarseIndices, *coarseRemote));
       }
       built_=true;
+      AggregatesMap* aggregatesMap=new AggregatesMap(0);
+      aggregatesMaps_.push_back(aggregatesMap);
+    }
 
+    template<class M, class IS, class R, class I>
+    const typename MatrixHierarchy<M,IS,R,I>::ParallelMatrixHierarchy&
+    MatrixHierarchy<M,IS,R,I>::matrices() const
+    {
+      return matrices_;
     }
 
+
+    template<class M, class IS, class R, class I>
+    const typename MatrixHierarchy<M,IS,R,I>::AggregatesMapList&
+    MatrixHierarchy<M,IS,R,I>::aggregatesMaps() const
+    {
+      return aggregatesMaps_;
+    }
     template<class M, class IS, class R, class I>
     MatrixHierarchy<M,IS,R,I>::~MatrixHierarchy()
     {
       typedef typename AggregatesMapList::reverse_iterator AggregatesMapIterator;
-      typedef typename MMatrixHierarchy::Iterator Iterator;
+      typedef typename ParallelMatrixHierarchy::Iterator Iterator;
 
-      AggregatesMapIterator amap = aggregatesMaps.rbegin();
+      AggregatesMapIterator amap = aggregatesMaps_.rbegin();
 
       for(Iterator level=matrices_.coarsest(), finest=matrices_.finest(); level != finest;  --level, ++amap) {
         delete *amap;
@@ -567,7 +587,7 @@ namespace Dune
     void MatrixHierarchy<M,IS,R,I>::coarsenVector(Hierarchy<BlockVector<V,TA> >& hierarchy) const
     {
       assert(hierarchy.levels()==1);
-      typedef typename MMatrixHierarchy::ConstIterator Iterator;
+      typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;
       Iterator coarsest = matrices_.coarsest();
       int level=0;
       std::cout<<"Level "<<level<<" has "<<matrices_.finest()->matrix().N()<<" unknows!"<<std::endl;
@@ -581,16 +601,18 @@ namespace Dune
     }
 
     template<class M, class IS, class R, class I>
-    template<class S>
-    void MatrixHierarchy<M,IS,R,I>::coarsenSmoother(Hierarchy<S>& smoothers,
+    template<class S, class TA>
+    void MatrixHierarchy<M,IS,R,I>::coarsenSmoother(Hierarchy<S,TA>& smoothers,
                                                     const typename SmootherTraits<S>::Arguments& sargs) const
     {
-      assert(smoothers.levels()==1);
-      typedef typename MMatrixHierarchy::ConstIterator Iterator;
+      assert(smoothers.levels()==0);
+      typedef typename ParallelMatrixHierarchy::ConstIterator Iterator;
       typename ConstructionTraits<S>::Arguments cargs;
       cargs.setArgs(sargs);
       Iterator coarsest = matrices_.coarsest();
+      int level=0;
       for(Iterator matrix = matrices_.finest(); matrix != coarsest; ++matrix) {
+        std::cout<<"level "<<level++<<" "<<&matrix->matrix();
         cargs.setMatrix(matrix->matrix());
         smoothers.addCoarser(cargs);
       }
@@ -600,9 +622,9 @@ namespace Dune
     void MatrixHierarchy<M,IS,R,I>::recalculateGalerkin()
     {
       typedef typename AggregatesMapList::iterator AggregatesMapIterator;
-      typedef typename MMatrixHierarchy::Iterator Iterator;
+      typedef typename ParallelMatrixHierarchy::Iterator Iterator;
 
-      AggregatesMapIterator amap = aggregatesMaps.begin();
+      AggregatesMapIterator amap = aggregatesMaps_.begin();
       GalerkinProduct productBuilder;
 
       for(Iterator level = matrices_.finest(), coarsest=matrices_.coarsest(); level!=coarsest; ++amap) {
diff --git a/istl/paamg/smoother.hh b/istl/paamg/smoother.hh
index 06d96c39de54efce9e97fcb6e9a8e473e5d93e92..39a0e3aad7ad5126e86e52b53d4781d4c2018def 100644
--- a/istl/paamg/smoother.hh
+++ b/istl/paamg/smoother.hh
@@ -3,6 +3,7 @@
 #ifndef DUNE_AMGSMOOTHER_HH
 #define DUNE_AMGSMOOTHER_HH
 
+#include <iostream>
 #include <dune/istl/paamg/construction.hh>
 #include <dune/istl/preconditioners.hh>
 namespace Dune
@@ -24,13 +25,13 @@ namespace Dune
     /**
      * @brief The default class for the smoother arguments.
      */
-    template<class M>
+    template<class T>
     struct DefaultSmootherArgs
     {
       /**
        * @brief The type of matrix the smoother is for.
        */
-      typedef M Matrix;
+      typedef typename T::matrix_type Matrix;
 
       /**
        * @brief The numbe of iterations to perform.
@@ -40,7 +41,7 @@ namespace Dune
       /**
        * @brief The relaxation factor to use.
        */
-      typename M::field_type relaxationFactor;
+      typename Matrix::field_type relaxationFactor;
 
       /**
        * @brief Default constructor.
@@ -76,7 +77,9 @@ namespace Dune
     public:
       void setMatrix(const Matrix& matrix)
       {
+        std::cout<<"Setting matrix "<<&matrix<<" size="<<matrix.N()<<std::endl;
         matrix_=&matrix;
+        std::cout<<"Matrix "<<matrix_<<" size="<<matrix_->N()<<std::endl;
       }
 
       void setArgs(const DefaultSmootherArgs<T>& args)
diff --git a/istl/paamg/test/Makefile.am b/istl/paamg/test/Makefile.am
index ebd38715ec90f615eb6fecfc03a41f6aaee7865f..23e190a3d5143ca7b270e98a21200de25346dfa6 100644
--- a/istl/paamg/test/Makefile.am
+++ b/istl/paamg/test/Makefile.am
@@ -3,7 +3,7 @@
 #if MPI
   MPITESTS = graphtest
   TESTPROGS = galerkintest hierarchytest amgtest
-  TESTRUNS = run-galerkin run-hierarchy
+  TESTRUNS = run-galerkin run-hierarchy run-amg
 #endif
 
 NORMALTESTS = $(MPITESTS)
diff --git a/istl/paamg/test/amgtest.cc b/istl/paamg/test/amgtest.cc
index 825f82b7e4422d1b3b2452a955d3b7281513e457..d99ada7c5e198c90c2ea614199d7f0870b17f3bd 100644
--- a/istl/paamg/test/amgtest.cc
+++ b/istl/paamg/test/amgtest.cc
@@ -1,7 +1,74 @@
 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 // vi: set et ts=4 sw=2 sts=2:
 #include "config.h"
+#include "anisotropic.hh"
 #include <dune/istl/paamg/amg.hh>
+#include <dune/istl/indexset.hh>
 
-int main()
-{}
+int main(int argc, char** argv)
+{
+  MPI_Init(&argc, &argv);
+
+  const int BS=1, N=8;
+
+  int procs, rank;
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &procs);
+
+  IndexSet indices;
+  typedef Dune::FieldMatrix<double,BS,BS> MatrixBlock;
+  typedef Dune::BCRSMatrix<MatrixBlock> BCRSMat;
+  typedef Dune::FieldVector<double,BS> VectorBlock;
+  typedef Dune::BlockVector<VectorBlock> Vector;
+
+  int n;
+
+  BCRSMat mat = setupAnisotropic2d<N,BS>(indices, &n);
+  Vector b(indices.size()), x(indices.size());
+
+  b=1;
+  x=100;
+
+  RemoteIndices remoteIndices(indices,indices,MPI_COMM_WORLD);
+  remoteIndices.rebuild<false>();
+
+  typedef Dune::Interface<IndexSet> Interface;
+
+  Interface interface;
+
+  typedef Dune::EnumItem<GridFlag,overlap> OverlapFlags;
+  typedef Dune::Amg::MatrixHierarchy<BCRSMat,IndexSet,OverlapFlags> MHierarchy;
+  typedef Dune::Amg::Hierarchy<Vector> VHierarchy;
+
+  interface.build(remoteIndices, Dune::NegateSet<OverlapFlags>(), OverlapFlags());
+
+  MHierarchy hierarchy(mat, indices, remoteIndices, interface);
+  VHierarchy vh(b);
+
+  typedef Dune::Amg::CoarsenCriterion<Dune::Amg::SymmetricCriterion<BCRSMat,Dune::Amg::FirstDiagonal> >
+  Criterion;
+
+  Criterion criterion(10,4);
+
+  hierarchy.build(criterion);
+  hierarchy.coarsenVector(vh);
+
+  typedef Dune::SeqSSOR<BCRSMat,Vector,Vector> Smoother;
+  typedef Dune::Amg::SmootherTraits<Smoother>::Arguments SmootherArgs;
+  SmootherArgs smootherArgs;
+
+  Dune::MatrixAdapter<BCRSMat,Vector,Vector> op(hierarchy.matrices().coarsest()->matrix());
+  Dune::SeqSSOR<BCRSMat,Vector,Vector> ssor(hierarchy.matrices().coarsest()->matrix(),1,1.0);
+  typedef Dune::LoopSolver<Vector> Solver;
+  Solver solver(op,ssor,1E-6,8000,2);
+  Dune::SeqScalarProduct<Vector> sp;
+  typedef Dune::Amg::AMG<MHierarchy,Vector,Vector,Solver,Smoother> AMG;
+
+  AMG amg(hierarchy, solver, smootherArgs, 1, 1);
+
+  amg.pre(x, b);
+  amg.apply(x,b);
+  amg.post(x);
+
+  MPI_Finalize();
+}
diff --git a/istl/paamg/test/run-amg b/istl/paamg/test/run-amg
new file mode 100755
index 0000000000000000000000000000000000000000..8ef12937f0b05796b2cab62c59324e9f68bb7ce9
--- /dev/null
+++ b/istl/paamg/test/run-amg
@@ -0,0 +1,17 @@
+#!/bin/sh
+# $Id$
+
+# run lamboot if possible
+if which lamboot; then
+  lamboot 2>&1 > /dev/null
+fi
+
+# start test and abort on fail
+set -e
+mpirun -np 1 amgtest
+set +e
+
+# possibly stop LAM again
+if which lamhalt; then
+  lamhalt 2>&1 > /dev/null
+fi
diff --git a/istl/paamg/transfer.hh b/istl/paamg/transfer.hh
index b14d2e8985b7768c7e8872a94f8dcee50494b0d7..df07786b89538d4ef75cbca8b8a5db4bf84c5e80 100644
--- a/istl/paamg/transfer.hh
+++ b/istl/paamg/transfer.hh
@@ -28,20 +28,20 @@ namespace Dune
       typedef V1 Vertex;
       typedef V2 Vector;
 
-      void prolongate(const AggregatesMap<Vertex>& aggregates, const Vector & coarse, Vector fine,
-                      typename Vector::field_type damp) const;
-      void restrict (const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector fine) const;
+      static void prolongate(const AggregatesMap<Vertex>& aggregates, const Vector & coarse, Vector fine,
+                             typename Vector::field_type damp);
+      static void restrict (const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector fine);
     };
 
     template<class V1, class V2>
     void Transfer<V1,V2>::prolongate(const AggregatesMap<Vertex>& aggregates, const Vector& coarse,
-                                     Vector fine, typename Vector::field_type damp) const
+                                     Vector fine, typename Vector::field_type damp)
     {
       DUNE_THROW(NotImplemented, "There is no secialization available for this type of vector!");
     }
     template<class V1, class V2>
     void Transfer<V1,V2>::restrict (const AggregatesMap<Vertex>& aggregates, Vector& coarse,
-                                    const Vector fine) const
+                                    const Vector fine)
     {
       DUNE_THROW(NotImplemented, "There is no secialization available for this type of vector!");
     }
@@ -52,36 +52,36 @@ namespace Dune
     public:
       typedef V Vertex;
       typedef BlockVector<B> Vector;
-      void prolongate(const AggregatesMap<Vertex>& aggregates, const Vector & coarse, Vector fine,
-                      typename Vector::field_type damp) const;
+      static void prolongate(const AggregatesMap<Vertex>& aggregates, const Vector & coarse, Vector fine,
+                             typename Vector::field_type damp);
 
-      void restrict (const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector fine) const;
+      static void restrict (const AggregatesMap<Vertex>& aggregates, Vector& coarse, const Vector fine);
     };
 
     template<class V, class B>
-    void Transfer<V,BlockVector<B> >::prolongate(const AggregatesMap<Vertex>& aggregates,
-                                                 const Vector& coarse, Vector fine,
-                                                 typename Vector::field_type damp) const
+    inline void Transfer<V,BlockVector<B> >::prolongate(const AggregatesMap<Vertex>& aggregates,
+                                                        const Vector& coarse, Vector fine,
+                                                        typename Vector::field_type damp)
     {
       typedef typename Vector::iterator Iterator;
 
       Iterator end = fine.end();
 
       for(Iterator block=fine.begin(); block != end; ++block) {
-        block = coarse[aggregates[block.index()]];
-        block *= damp;
+        *block = coarse[aggregates[block.index()]];
+        *block *= damp;
       }
     }
 
     template<class V, class B>
-    void Transfer<V,BlockVector<B> >::restrict (const AggregatesMap<Vertex>& aggregates,
-                                                Vector& coarse,
-                                                const Vector fine) const
+    inline void Transfer<V,BlockVector<B> >::restrict (const AggregatesMap<Vertex>& aggregates,
+                                                       Vector& coarse,
+                                                       const Vector fine)
     {
       // Set coarse vector to zero
       coarse=0;
 
-      typedef typename Vector::iterator Iterator;
+      typedef typename Vector::const_iterator Iterator;
       Iterator end = fine.end();
       for(Iterator block=fine.begin(); block != end; ++block)
         coarse[aggregates[block.index()]] += *block;