diff --git a/grid/yaspgrid.hh b/grid/yaspgrid.hh
index b219e65846812bd132f12b737f792a15038fdb1f..d9f1256f424777d45c433d96adbb44c40f426ee1 100644
--- a/grid/yaspgrid.hh
+++ b/grid/yaspgrid.hh
@@ -10,6 +10,7 @@
 #include "../common/stack.hh" // the stack class
 #include "../common/capabilities.hh" // the capabilities
 #include "../common/helpertemplates.hh"
+#include "../common/bigunsignedint.hh"
 
 /*! \file yaspgrid.hh
    Yasppergrid stands for yet another structured parallel grid.
@@ -41,8 +42,17 @@ namespace Dune {
    */
   typedef double yaspgrid_ctype;
 
+
   static const yaspgrid_ctype yasptolerance=1E-13; // tolerance in coordinate computations
 
+  /*! type used for the persistent indices
+   */
+
+  // globally define the persistent index type
+  typedef bigunsignedint<64> yaspgrid_persistentindextype;
+
+
+
   //************************************************************************
   // forward declaration of templates
 
@@ -604,6 +614,9 @@ namespace Dune {
     typedef typename GridImp::template codim<0>::IntersectionIterator IntersectionIterator;
     typedef typename GridImp::template codim<0>::HierarchicIterator HierarchicIterator;
 
+    //! define the type used for persisitent indices
+    typedef yaspgrid_persistentindextype PersistentIndexType;
+
     //! define type used for coordinates in grid module
     typedef typename YGrid<dim,ctype>::iTupel iTupel;
 
@@ -634,18 +647,18 @@ namespace Dune {
     //! geometry of this entity
     const Geometry& geometry () const { return _geometry; }
 
-    /*! Intra-element access to entities of codimension cc > codim. Return number of entities
-          with codimension cc.
+    /*! Return number of subentities with codimension cc.
      */
     template<int cc> int count () const
     {
-      if (cc==1) return 2*dim;
       if (cc==dim) return 1<<dim;
+      if (cc==1) return 2*dim;
+      if (cc==dim-1) return dim*(1<<(dim-1));
+      if (cc==0) return 1;
       DUNE_THROW(GridError, "codim not (yet) implemented");
     }
 
-    /*! Intra-element access to entities of codimension cc > codim. Return number of entities
-          with codimension cc.
+    /*! Intra-element access to subentities of codimension cc > codim.
      */
     template<int cc>
     typename codim<cc>::EntityPointer entity (int i) const
@@ -724,9 +737,9 @@ namespace Dune {
 
     bool isLeaf() const
     {
-      std::cout << _g.level() << " ... " << _g.mg()->maxlevel() << std::endl;
-      if (_g.level() == _g.mg()->maxlevel())
-        std::cout << "is Leaf\n";
+      //    std::cout << _g.level() << " ... " << _g.mg()->maxlevel() << std::endl;
+      //   if (_g.level() == _g.mg()->maxlevel())
+      //      std::cout << "is Leaf\n";
       return (_g.level() == _g.mg()->maxlevel());
     }
 
@@ -758,6 +771,244 @@ namespace Dune {
     }
 
   private:
+    friend class GridImp::IndexType; // needs access to the private index methods
+
+    //! globally unique, persistent index
+    PersistentIndexType persistentIndex () const
+    {
+      // get coordinate and size of global grid
+      const iTupel& size =  _g.cell_global().size();
+      int coord[dim];
+
+      // correction for periodic boundaries
+      for (int i=0; i<dim; i++)
+      {
+        coord[i] = _it.coord(i);
+        if (coord[i]<0) coord[i] += size[i];
+        if (coord[i]>=size[i]) coord[i] -= size[i];
+      }
+
+      // make one number from coordinate
+      PersistentIndexType number1(coord[dim-1]);
+      for (int i=dim-2; i>=0; i--)
+        number1 = (number1*size[i])+coord[i];
+
+      // encode codim and level
+      PersistentIndexType number2((_g.level()<<4));
+
+      return number1|(number2<<52);
+    }
+
+    //! consecutive, codim-wise, level-wise index
+    int compressedIndex () const
+    {
+      _it.superindex();
+    }
+
+    //! subentity persistent index
+    template<int cc>
+    PersistentIndexType subPersistentIndex (int i) const
+    {
+      // get position of cell, note that global origin is zero
+      // adjust for periodic boundaries
+      int coord[dim];
+      for (int k=0; k<dim; k++)
+      {
+        coord[k] = _it.coord(k);
+        if (coord[k]<0) coord[k] += _g.cell_global().size(k);
+        if (coord[k]>=_g.cell_global().size(k)) coord[k] -= _g.cell_global().size(k);
+      }
+
+      if (cc==dim)
+      {
+        // transform to vertex coordinates
+        for (int k=0; k<dim; k++)
+          if (i&(1<<k)) (coord[k])++;
+
+        // make one number from coordinate
+        PersistentIndexType number1(coord[dim-1]);
+        for (int k=dim-2; k>=0; k--)
+          number1 = (number1*(_g.cell_global().size(k)+1))+coord[k];
+
+        // encode codim and level
+        PersistentIndexType number2((_g.level()<<4)+cc);
+
+        return number1|(number2<<52);
+      }
+
+      if (cc==1)   // faces, i.e. for dim=2 codim=1 is treated as a face
+      {
+        // Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
+
+        // ivar is the direction that varies
+        int ivar=i/2;
+
+        // compute position from cell position
+        if (i%2) coord[ivar] += 1;
+
+        // do lexicographic numbering
+        PersistentIndexType index(coord[dim-1]);
+        for (int k=dim-2; k>=0; --k)
+          if (k==ivar)
+            index = (index*(_g.cell_global().size(k)+1))+coord[k];             // one more
+          else
+            index = (index*(_g.cell_global().size(k)))+coord[k];
+
+        // add size of all subsets for smaller directions
+        for (int j=0; j<ivar; j++)
+        {
+          PersistentIndexType n(_g.cell_global().size(j)+1);
+          for (int l=0; l<dim; l++)
+            if (l!=j) n = n*_g.cell_global().size(l);
+          index = index+n;
+        }
+
+        // encode codim and level
+        PersistentIndexType modifier((_g.level()<<4)+cc);
+
+        return index|(modifier<<52);
+      }
+
+      if (cc==dim-1)   // edges, exist only for dim>2
+      {
+        // Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
+
+        // number of entities per direction
+        int m=1<<(dim-1);
+
+        // ifix is the direction that is fixed
+        int ifix=(dim-1)-(i/m);
+
+        // compute position from cell position
+        int bit=1;
+        for (int k=0; k<dim; k++)
+        {
+          if (k==ifix) continue;
+          if ((i%m)&bit) coord[k] += 1;
+          bit *= 2;
+        }
+
+        // do lexicographic numbering
+        PersistentIndexType index(coord[dim-1]);
+        for (int k=dim-2; k>=0; --k)
+          if (k!=ifix)
+            index = (index*(_g.cell_global().size(k)+1))+coord[k];             // one more
+          else
+            index = (index*(_g.cell_global().size(k)))+coord[k];
+
+        // add size of all subsets for smaller directions
+        for (int j=dim-1; j>ifix; j--)
+        {
+          PersistentIndexType n(_g.cell_overlap().size(j));
+          for (int l=0; l<dim; l++)
+            if (l!=j) n = n*(_g.cell_global().size(l)+1);
+          index = index+n;
+        }
+
+        // encode codim and level
+        PersistentIndexType modifier((_g.level()<<4)+cc);
+
+        return index|(modifier<<52);
+      }
+
+      DUNE_THROW(GridError, "codim not (yet) implemented");
+    }
+
+    //! subentity compressed index
+    template<int cc>
+    int subCompressedIndex (int i) const
+    {
+      // get cell position relative to origin of local cell grid
+      iTupel coord;
+      for (int k=0; k<dim; ++k)
+        coord[k] = _it.coord(k)-_g.cell_overlap().origin(k);
+
+      if (cc==dim)   // vertices
+      {
+        // transform cell coordinate to corner coordinate
+        for (int k=0; k<dim; k++)
+          if (i&(1<<k)) (coord[k])++;
+
+        // do lexicographic numbering
+        int index = coord[dim-1];
+        for (int k=dim-2; k>=0; --k)
+          index = (index*(_g.cell_overlap().size(k)+1))+coord[k];
+        return index;
+      }
+
+      if (cc==1)   // faces, i.e. for dim=2 codim=1 is treated as a face
+      {
+        // Idea: direction ivar varies, all others are fixed, i.e. 2 possibilities per direction
+
+        // ivar is the direction that varies
+        int ivar=i/2;
+
+        // compute position from cell position
+        if (i%2) coord[ivar] += 1;
+
+        // do lexicographic numbering
+        int index = coord[dim-1];
+        for (int k=dim-2; k>=0; --k)
+          if (k==ivar)
+            index = (index*(_g.cell_overlap().size(k)+1))+coord[k];             // one more
+          else
+            index = (index*(_g.cell_overlap().size(k)))+coord[k];
+
+        // add size of all subsets for smaller directions
+        for (int j=0; j<ivar; j++)
+        {
+          int n=_g.cell_overlap().size(j)+1;
+          for (int l=0; l<dim; l++)
+            if (l!=j) n *= _g.cell_overlap().size(l);
+          index += n;
+        }
+
+        return index;
+      }
+
+      if (cc==dim-1)   // edges, exist only for dim>2
+      {
+        // Idea: direction i is fixed, all others are vary, i.e. 2^(dim-1) possibilities per direction
+
+        // number of entities per direction
+        int m=1<<(dim-1);
+
+        // ifix is the direction that is fixed
+        int ifix=(dim-1)-(i/m);
+
+        // compute position from cell position
+        int bit=1;
+        for (int k=0; k<dim; k++)
+        {
+          if (k==ifix) continue;
+          if ((i%m)&bit) coord[k] += 1;
+          bit *= 2;
+        }
+
+        // do lexicographic numbering
+        int index = coord[dim-1];
+        for (int k=dim-2; k>=0; --k)
+          if (k!=ifix)
+            index = (index*(_g.cell_overlap().size(k)+1))+coord[k];             // one more
+          else
+            index = (index*(_g.cell_overlap().size(k)))+coord[k];
+
+        // add size of all subsets for smaller directions
+        for (int j=dim-1; j>ifix; j--)
+        {
+          int n=_g.cell_overlap().size(j);
+          for (int l=0; l<dim; l++)
+            if (l!=j) n *= _g.cell_overlap().size(l)+1;
+          index += n;
+        }
+
+        return index;
+      }
+
+      DUNE_THROW(GridError, "codim not (yet) implemented");
+    }
+
+
     const TSI& _it;         // position in the grid level
     const YGLI& _g;         // access to grid level
     SpecialGeometry _geometry; // the element geometry
@@ -785,6 +1036,9 @@ namespace Dune {
     };
     typedef typename GridImp::template codim<0>::EntityPointer EntityPointer;
 
+    //! define the type used for persisitent indices
+    typedef yaspgrid_persistentindextype PersistentIndexType;
+
     //! define type used for coordinates in grid module
     typedef typename YGrid<dim,ctype>::iTupel iTupel;
 
@@ -799,10 +1053,9 @@ namespace Dune {
     //! index is unique and consecutive per level
     int index () const {return _it.superindex();}
 
-    //! globalIndex is unique and consecutive per global level
-    int globalIndex () const {
-      return _g.cell_global().index(_it.coord());
-    }
+    //! globally unique, persistent index
+    int globalIndex () const { return _g.cell_global().index(_it.coord()); }
+
 
     //! geometry of this entity
     const Geometry& geometry () const { return _geometry; }
@@ -877,6 +1130,37 @@ namespace Dune {
     }
 
   private:
+    friend class GridImp::IndexType; // needs access to the private index methods
+
+    //! globally unique, persistent index
+    PersistentIndexType persistentIndex () const
+    {
+      // get coordinate and size of global grid
+      const iTupel& size =  _g.vertex_global().size();
+      int coord[dim];
+
+      // correction for periodic boundaries
+      for (int i=0; i<dim; i++)
+      {
+        coord[i] = _it.coord(i);
+        if (coord[i]<0) coord[i] += size[i];
+        if (coord[i]>=size[i]) coord[i] -= size[i];
+      }
+
+      // make one number from coordinate
+      PersistentIndexType number1(coord[dim-1]);
+      for (int i=dim-2; i>=0; i--)
+        number1 = (number1*size[i])+coord[i];
+
+      // encode codim and level
+      PersistentIndexType number2((_g.level()<<4)+dim);
+
+      return number1|(number2<<52);
+    }
+
+    //! consecutive, codim-wise, level-wise index
+    int compressedIndex () const { return _it.superindex();}
+
     const TSI& _it;              // position in the grid level
     const YGLI& _g;              // access to grid level
     SpecialGeometry _geometry;    // the element geometry
@@ -1389,19 +1673,73 @@ namespace Dune {
   template <class GridImp>
   class YaspLeafIterator : public YaspLevelIterator<0,All_Partition,GridImp>
   {
+    //! know your own dimension
+    enum { dim=GridImp::dimension };
     typedef typename GridImp::ctype ctype;
   public:
-    typedef typename MultiYGrid<0,ctype>::YGridLevelIterator YGLI;
-    typedef typename SubYGrid<0,ctype>::TransformingSubIterator TSI;
+    typedef typename MultiYGrid<dim,ctype>::YGridLevelIterator YGLI;
+    typedef typename SubYGrid<dim,ctype>::TransformingSubIterator TSI;
     YaspLeafIterator(const YGLI & g, const TSI & it) :
       YaspLevelIterator<0,All_Partition,GridImp>(g,it)
     {}
     YaspLeafIterator(const YaspLeafIterator& i) :
-      YaspLevelIterator<0,All_Partition,GridImp>(i.g,i.it)
+      YaspLevelIterator<0,All_Partition,GridImp>(i)
     {}
   };
 
 
+
+  //========================================================================
+  /*!
+     YaspIndex provides mappers with index information for an entity
+
+     Numbering of the entities on one level which can also be used as leaf index
+   */
+  //========================================================================
+
+  // Index class for level indices, we implement it with methods in the entity
+  template<class GridImp>
+  class YaspIndex
+  {
+  public:
+    //! define the type used for persisitent indices
+    typedef yaspgrid_persistentindextype PersistentIndexType;
+
+    //! globally unique, persistent index
+    template<int cd>
+    PersistentIndexType persistent (const typename GridImp::Traits::template codim<cd>::Entity& e) const
+    {
+      return grid.template getRealEntity<cd>(e).persistentIndex();
+    }
+
+    //! consecutive, codim-wise and geometrytype-wise index
+    template<int cd>
+    int compressed (const typename GridImp::Traits::template codim<cd>::Entity& e) const
+    {
+      return grid.template getRealEntity<cd>(e).compressedIndex();
+    }
+
+    //! subentity persistent index
+    template<int cc>
+    PersistentIndexType subpersistent (const typename GridImp::Traits::template codim<0>::Entity& e, int i) const
+    {
+      return grid.template getRealEntity<0>(e).template subPersistentIndex<cc>(i);
+    }
+
+    //! subentity compressed index
+    template<int cc>
+    int subcompressed (const typename GridImp::Traits::template codim<0>::Entity& e, int i) const
+    {
+      return grid.template getRealEntity<0>(e).template subCompressedIndex<cc>(i);
+    }
+
+    YaspIndex (const GridImp& g) : grid(g) {}
+
+  private:
+    const GridImp& grid;
+  };
+
+
   //************************************************************************
   /*!
      A Grid is a container of grid entities. Given a dimension dim these entities have a
@@ -1425,11 +1763,17 @@ namespace Dune {
     typedef GridTraits<dim,dimworld,Dune::YaspGrid<dim,dimworld>,
         YaspGeometry,YaspEntity,YaspBoundaryEntity,
         YaspEntityPointer,YaspLevelIterator,
-        YaspIntersectionIterator,YaspHierarchicIterator> Traits;
+        YaspIntersectionIterator,YaspHierarchicIterator,
+        YaspLeafIterator> Traits;
+
+    typedef YaspIndex<YaspGrid<dim,dimworld> > IndexType;
 
     //! define type used for coordinates in grid module
     typedef yaspgrid_ctype ctype;
 
+    //! define the type used for persisitent indices
+    typedef yaspgrid_persistentindextype PersistentIndexType;
+
     //! maximum number of levels allowed
     enum { MAXL=64 };
 
@@ -1451,8 +1795,10 @@ namespace Dune {
     YaspGrid (MPI_Comm comm, Dune::FieldVector<ctype, dim> L,
               Dune::FieldVector<int, dim> s,
               Dune::FieldVector<bool, dim> periodic, int overlap) :
-      MultiYGrid<dim,ctype>(comm,L,s,periodic,overlap)
-    {}
+      MultiYGrid<dim,ctype>(comm,L,s,periodic,overlap),yi(*this)
+    {
+      setsizes();
+    }
 
     /*! Return maximum level defined in this grid. Levels are numbered
           0 ... maxlevel with 0 the coarsest level.
@@ -1465,6 +1811,14 @@ namespace Dune {
       bool b=false;
       if (refCount>0) b=true;
       MultiYGrid<dim,ctype>::refine(b);
+      setsizes();
+    }
+
+    //! refine the grid refCount times. What about overlap?
+    void refine (bool b)
+    {
+      MultiYGrid<dim,ctype>::refine(b);
+      setsizes();
     }
 
     //! one past the end on this level
@@ -1473,6 +1827,7 @@ namespace Dune {
     {
       IsTrue< ( cd == dim || cd == 0 ) >::yes();
       YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      if (level<0 || level>maxlevel()) DUNE_THROW(RangeError, "level out of range");
       if (cd==0)   // the elements
       {
         if (pitype<=InteriorBorder_Partition)
@@ -1500,6 +1855,7 @@ namespace Dune {
     {
       IsTrue< ( cd == dim || cd == 0 ) >::yes();
       YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      if (level<0 || level>maxlevel()) DUNE_THROW(RangeError, "level out of range");
       if (cd==0)   // the elements
       {
         if (pitype<=InteriorBorder_Partition)
@@ -1527,6 +1883,7 @@ namespace Dune {
     {
       IsTrue< ( cd == dim || cd == 0 ) >::yes();
       YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      if (level<0 || level>maxlevel()) DUNE_THROW(RangeError, "level out of range");
       if (cd==0)   // the elements
       {
         return YaspLevelIterator<cd,All_Partition,GridImp>(g,g.cell_overlap().tsubbegin());
@@ -1544,6 +1901,7 @@ namespace Dune {
     {
       IsTrue< ( cd == dim || cd == 0 ) >::yes();
       YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      if (level<0 || level>maxlevel()) DUNE_THROW(RangeError, "level out of range");
       if (cd==0)   // the elements
       {
         return YaspLevelIterator<cd,All_Partition,GridImp>(g,g.cell_overlap().tsubend());
@@ -1555,6 +1913,22 @@ namespace Dune {
       DUNE_THROW(GridError, "YaspLevelIterator with this codim or partition type not implemented");
     }
 
+    //! return LeafIterator which points to the first entity in maxLevel
+    typename Traits::LeafIterator leafbegin(int maxLevel) const
+    {
+      int level = std::min(maxLevel,maxlevel());
+      YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      return YaspLeafIterator<const GridImp>(g,g.cell_overlap().tsubbegin());
+    };
+
+    //! return LeafIterator which points behind the last entity in maxLevel
+    typename Traits::LeafIterator leafend(int maxLevel) const
+    {
+      int level = std::min(maxLevel,maxlevel());
+      YGLI g = MultiYGrid<dim,ctype>::begin(level);
+      return YaspLeafIterator<const GridImp>(g,g.cell_overlap().tsubend());
+    }
+
     //! return size (= distance in graph) of overlap region
     int overlapSize (int level, int codim) const
     {
@@ -1568,20 +1942,48 @@ namespace Dune {
       return 0;
     }
 
-    //! number of grid entities per level and codim
+    //! number of entities per level and codim in this process
     int size (int level, int codim) const
     {
-      YaspGrid<dim, dimworld>* p = const_cast<YaspGrid<dim, dimworld>*>(this);
-      YGLI g = p->begin(level);
-      if (codim==0)
-      {
-        return g.cell_overlap().totalsize();
-      }
-      if (codim==dim)
+      return sizes[level][codim];
+    }
+
+    //! number of leaf entities per codim in this process
+    int size (int codim) const
+    {
+      return sizes[maxlevel()][codim];
+    }
+
+    //! number of entities per level, codim and geometry type in this process
+    int size (int level, int codim, GeometryType type) const
+    {
+      if (type==hypercube) return sizes[level][codim];
+      switch (dim-codim)
       {
-        return g.vertex_overlapfront().totalsize();
+      case 0 :
+        if (type==vertex) return sizes[level][codim];
+        break;
+
+      case 1 :
+        if (type==line) return sizes[level][codim];
+        break;
+
+      case 2 :
+        if (type==quadrilateral) return sizes[level][codim];
+        if (type==iso_quadrilateral) return sizes[level][codim];
+        break;
+
+      case 3 :
+        if (type==hexahedron) return sizes[level][codim];
+        break;
       }
-      DUNE_THROW(GridError, "Yasp does not implement this codim (yet)");
+      return 0;
+    }
+
+    //! number of leaf entities per codim and geometry type in this process
+    int size (int codim, GeometryType type) const
+    {
+      return size(maxlevel(),codim,type);
     }
 
     /*! The communication interface
@@ -1714,19 +2116,95 @@ namespace Dune {
 
     // implement leaf communication. Problem: supply vector of vectors
 
+    // the index methods
+    const IndexType& leafindex () const
+    {
+      return yi;
+    }
+
+    const IndexType& levelindex () const
+    {
+      return yi;
+    }
+
+    const IndexType& savedleafindex () const
+    {
+      return yi;
+    }
+
+    const IndexType& savedlevelindex () const
+    {
+      return yi;
+    }
+
   private:
+    IndexType yi;
+
+    // Index classes need access to the real entity
+    friend class Dune::YaspIndex<Dune::YaspGrid<dim,dimworld> >;
+
     template<int codim>
     YaspEntity<codim,dim,const YaspGrid<dim,dimworld> >&
-    getRealEntity(typename Traits::template codim<codim>::Entity& e );
+    getRealEntity(typename Traits::template codim<codim>::Entity& e )
+    {
+      return e.realEntity;
+    }
 
     template<int codim>
     const YaspEntity<codim,dim,const YaspGrid<dim,dimworld> >&
-    getRealEntity(const typename Traits::template codim<codim>::Entity& e ) const ;
+    getRealEntity(const typename Traits::template codim<codim>::Entity& e ) const
+    {
+      return e.realEntity;
+    }
 
     template<int codim_, int dim_, class GridImp_, template<int,int,class> class EntityImp_>
     friend class Entity;
 
-    //  YMG _mg;
+    void setsizes ()
+    {
+      for (YGLI g=MultiYGrid<dim,ctype>::begin(); g!=MultiYGrid<dim,ctype>::end(); ++g)
+      {
+        // codim 0 (elements)
+        sizes[g.level()][0] = 1;
+        for (int i=0; i<dim; ++i)
+          sizes[g.level()][0] *= g.cell_overlap().size(i);
+
+        // codim 1 (faces)
+        if (dim>1)
+        {
+          sizes[g.level()][1] = 0;
+          for (int i=0; i<dim; ++i)
+          {
+            int s=g.cell_overlap().size(i)+1;
+            for (int j=0; j<dim; ++j)
+              if (j!=i)
+                s *= g.cell_overlap().size(j);
+            sizes[g.level()][1] += s;
+          }
+        }
+
+        // codim dim-1 (edges)
+        if (dim>2)
+        {
+          sizes[g.level()][dim-1] = 0;
+          for (int i=0; i<dim; ++i)
+          {
+            int s=g.cell_overlap().size(i);
+            for (int j=0; j<dim; ++j)
+              if (j!=i)
+                s *= g.cell_overlap().size(j)+1;
+            sizes[g.level()][dim-1] += s;
+          }
+        }
+
+        // codim dim (vertices)
+        sizes[g.level()][dim] = 1;
+        for (int i=0; i<dim; ++i)
+          sizes[g.level()][dim] *= g.vertex_overlapfront().size(i);
+      }
+    }
+
+    int sizes[MAXL][dim+1]; // total number of entities per level and codim
   };
 
   /** @} end documentation group */