diff --git a/misc/examples/sizes.cc b/misc/examples/sizes.cc
index 04b32ddb370f1c91db69e98dbccde6922ec8a1f5..cec4fe604c3ff0069775aecbd33a4dddc0120dc8 100644
--- a/misc/examples/sizes.cc
+++ b/misc/examples/sizes.cc
@@ -12,7 +12,7 @@
 
 using namespace std;
 
-#define PARALLEL
+// #define PARALLEL
 
 #define COUNT_FLOPS
 
@@ -83,7 +83,7 @@ void checkRefinements( GitterType& grid )
 
 // refine grid globally, i.e. mark all elements and then call adapt 
 template <class GitterType>
-void globalRefine(GitterType& grid, bool global) 
+void globalRefine(GitterType& grid, bool global,int step) 
 {
    {
      if (global)
@@ -109,10 +109,16 @@ void globalRefine(GitterType& grid, bool global)
         }
        // adapt grid 
        grid.adapt ();
+       grid.printsize () ;
      }
      else
      {
+       double t = double(step)/10.;
        double center[3] = {0.2,0.2,0.2};
+       double dir[3]    = {1.0,0.0,0.0};
+       center[0] += dir[0]*t;
+       center[1] += dir[1]*t;
+       center[2] += dir[2]*t;
        double rad=0.6;
        grid.refineBall(center,rad,10);
      }
@@ -171,16 +177,19 @@ int main (int argc, char ** argv, const char ** envp)
 {
   MPI_Init(&argc,&argv);
 
-  int mxl = 0; 
+  int mxl = 0, glb = 0; 
   const char* filename = 0 ;
   if (argc < 2) 
   {
     filename = "../macrogrids/reference.tetra";
     mxl = 1;
-    cout << "usage: "<< argv[0] << " <macro grid> <opt: level> \n";
+    glb = 1;
+    cout << "usage: "<< argv[0] << " <macro grid> <opt: level global> \n";
   }
   else 
+  {
     filename = argv[ 1 ];
+  }
 
   {
     int rank = 0;
@@ -196,6 +205,13 @@ int main (int argc, char ** argv, const char ** envp)
     }
     else 
       mxl = atoi(argv[2]);
+    if (argc < 4)
+    {
+      if( rank == 0 ) 
+        cout << "Default global refinement = "<< glb << " choosen! \n";
+    }
+    else 
+      glb = atoi(argv[3]);
 
     std::string macroname( filename );
 
@@ -218,84 +234,31 @@ int main (int argc, char ** argv, const char ** envp)
       //cout << "P[ " << rank << " ] : Grid generated! \n";
       grid.printsize(); 
       cout << "---------------------------------------------\n";
-    /*
+    
       grid.printMemUsage();
-      for (int i = 0; i < 6; ++i)
-        globalRefine(grid, true);
-     */
- 
-      //int bla; 
-      // cin >> bla;
-      for( int i = 0; i <= mxl; ++i )
+      for (int i = 0; i < glb; ++i)
+        globalRefine(grid, true,-1);
+      for (int i = 0; i < glb; ++i)
+        globalRefine(grid, false,0);
+      for( int i = 0; i < mxl; ++i )
       {
         std::ostringstream ss;
         ss << "out-" << ZeroPadNumber(i) << ".vtu";
         grid.tovtk(  ss.str().c_str() );
-        if( i < mxl )
-          globalRefine(grid, false);
+        globalRefine(grid, false,i);
       }
-     
-#if 0
-      checkRefinements( grid );
-
-      std::ofstream file( "file.out" );
-      grid.duneBackup( file );
-      file.close();
-
-      /*
       {
-        ObjectStream os ;
-        grid.duneBackup( os );
-
-        char* buffer = ObjectStream ::allocateBuffer( os.size() );
-        os.read( buffer, os.size() );
-        
-        std::ofstream obj( "obj.out" );
-        const size_t size = os.size();
-        obj.write( (const char *) &size, sizeof( size_t ) ); 
-        obj.write( buffer, size );
-        ObjectStream :: freeBuffer( buffer );
+        std::ostringstream ss;
+        ss << "out-" << ZeroPadNumber(mxl) << ".vtu";
+        grid.tovtk(  ss.str().c_str() );
       }
-
-      globalRefine(grid, mxl);
-
-      {
-        size_t size = 0;
-
-        std::ifstream obj( "obj.out" );
-        obj.read( (char *) &size, sizeof( size_t ) ); 
-        char * buffer = ObjectStream ::allocateBuffer( size );
-        obj.read( buffer, size );
-        //ObjectStream :: freeBuffer( buffer );
-
-        ObjectStream is;
-        is.clear();
-        is.write( buffer, size );
-
-        {
-          ObjectStream copy( is );
-          std::ofstream obj( "check.out" );
-          const size_t size = copy.size();
-          obj.write( buffer, size );
-          //ObjectStream :: freeBuffer( buffer );
-        }
-        }*/
-
+      globalCoarsening(grid,3*glb);
       {
-        std::ifstream file( "file.out" );
-#ifdef PARALLEL
-        MpAccessMPI a (MPI_COMM_WORLD);
-        GitterDunePll grid2( file, a);
-#else 
-        GitterDuneImpl grid2( file );
-#endif
-        grid2.printsize();
+        std::ostringstream ss;
+        ss << "out-" << ZeroPadNumber(mxl+1) << ".vtu";
+        grid.tovtk(  ss.str().c_str() );
       }
-      //levelwalk(grid, mxl);
-      // globalCoarsening(grid, mxl);
-      //grid.printMemUsage();
-      //cin.get();
-#endif
+      return 1;
     }
   }
 
diff --git a/src/duneinterface/gitter_dune_pll_impl.cc b/src/duneinterface/gitter_dune_pll_impl.cc
index 05876facfdebfceffaabde48ec35b785a5fe8ca8..cc6daaae635fd530c1b33486e790a25e99803c6b 100644
--- a/src/duneinterface/gitter_dune_pll_impl.cc
+++ b/src/duneinterface/gitter_dune_pll_impl.cc
@@ -1395,8 +1395,6 @@ void GitterDunePll :: duneRestore(const char *fileName)
 }
 void GitterDunePll :: tovtk( const std::string &fn ) 
 {
-  const bool showbnd = false;
-  const bool showface = true;
   const int myrank = mpAccess ().myrank () ;
   const int nProc = mpAccess ().psize () ;
 
@@ -1405,6 +1403,8 @@ void GitterDunePll :: tovtk( const std::string &fn )
 
   // openfile
   std::ofstream vtuFile;
+  Gitter :: tovtk( ss.str() );
+#if 0
   vtuFile.open( ss.str().c_str() );
     
   // header info
@@ -1642,6 +1642,7 @@ void GitterDunePll :: tovtk( const std::string &fn )
   vtuFile << "</VTKFile>" << std::endl;
 
   vtuFile.close();
+#endif
 
   if( myrank == 0 )
   {
diff --git a/src/serial/gitter_geo.cc b/src/serial/gitter_geo.cc
index 5cf293f7f3958ca6aea895d65dd0e943a879186d..7127383ab27ebb6146707a1009c31c5394d3044b 100644
--- a/src/serial/gitter_geo.cc
+++ b/src/serial/gitter_geo.cc
@@ -549,9 +549,9 @@ int Gitter :: Geometric :: Tetra :: tagForBallRefinement (const alucoord_t (&cen
     }
   }
 #endif
-  return hit ?  (request (myrule_t :: bisect), 1) : (request (myrule_t :: nosplit), 0);
-  //  (level () < limit ? (request (myrule_t :: iso8), 1) 
-  //       : (request (myrule_t :: nosplit), 0)) : (request (myrule_t :: crs), 1) ;
+  if (!hit) return (request (myrule_t :: crs), 1) ;
+  if (level()>limit) return (request (myrule_t :: nosplit), 0);
+  return (request (myrule_t :: bisect), 1);
 }
 
 // ######                                                           #####
diff --git a/src/serial/gitter_sti.cc b/src/serial/gitter_sti.cc
index 732416b7a9938c0fe9d89cf8ee31f27bb2e9bb92..94124c2cc9771b4f8e43bb47a7dd7586ec468d21 100644
--- a/src/serial/gitter_sti.cc
+++ b/src/serial/gitter_sti.cc
@@ -312,13 +312,22 @@ bool Gitter :: markNonConform()
 {
   bool x = true ;
   leaf_element__macro_element__iterator i (container ()) ;
-  // std::cout << "check non conform refinement" << std::endl;
   for( i.first(); ! i.done() ; i.next()) { x &= i.item ().markNonConform () ; }
   return x;
 }
+void Gitter :: markEdgeCoarsening () 
+{
+  edgeCoarseningFlags_.assign( indexManagerStorage().get(2).getMaxIndex(), true );
+  leaf_element__macro_element__iterator i (container ()) ;
+  for( i.first(); ! i.done() ; i.next() ) 
+  {
+    i.item().markEdgeCoarsening();
+  }
+}
 
 void Gitter :: coarse() 
 {
+  markEdgeCoarsening();
   assert (debugOption (20) ? (cout << "**INFO Gitter :: coarse ()" << endl, 1) : 1) ;
   {
     AccessIterator < helement_STI > :: Handle i (container ()) ;
@@ -327,10 +336,18 @@ void Gitter :: coarse()
       i.item ().coarse () ; 
     }
   }
+  std::ostringstream ss;
+  int filenr = adaptstep*100+nr;
+  ss << "crs-" << ZeroPadNumber(filenr) << ".vtu";
+  tovtk(  ss.str() );
+  ++nr;
 }
 
 void Gitter :: tovtk( const std::string &fn ) 
 {
+  const bool showbnd = false;
+  const bool showface = true;
+
   // openfile
   std::ofstream vtuFile;
   vtuFile.open( fn.c_str() );
@@ -346,30 +363,54 @@ void Gitter :: tovtk( const std::string &fn )
   VertexList vertexList;
 
   int nCells = 0;
-
-  typedef Gitter :: Geometric :: tetra_GEO tetra_GEO ;
+  int nBnd = 0;
+  int nFaces = 0;
+#if 1
   typedef LeafIterator < Gitter::helement_STI > Iterator;
-  // typedef LevelIterator < Gitter::helement_STI > Iterator;
   Iterator w (*this) ;
-
+  typedef LeafIterator < Gitter::hbndseg_STI > BndIterator;
+  BndIterator wbnd (*this) ;
+  typedef LeafIterator < Gitter::hface_STI > FaceIterator;
+  FaceIterator wface (*this) ;
+#else
+  typedef LevelIterator < Gitter::helement_STI > Iterator;
+  Iterator w (*this,0) ;
+  typedef LevelIterator < Gitter::hbndseg_STI > BndIterator;
+  BndIterator wbnd (*this,0) ;
+  typedef LevelIterator < Gitter::hface_STI > FaceIterator;
+  FaceIterator wface (*this,0) ;
+#endif
+  typedef Geometric :: tetra_GEO tetra ;
+  typedef Geometric :: hbndseg3_GEO bndseg ;
+  typedef Geometric :: hface3_GEO face;
   // loop to find vertexList and count cells
   {
     for (w->first () ; ! w->done () ; w->next ())
     {
-      tetra_GEO* item = ((tetra_GEO *) &w->item ());
-      for (int i=0;i<4;++i)
-      {
-        Vertex v(3);
-        for (int k=0;k<3;++k) 
-          v[k] = item->myvertex(i)->Point()[k];
-        vertexList[ item->myvertex(i)->getIndex() ] = make_pair(-1,v);
-      }
-      ++nCells;
+	    tetra* item = ((tetra *) &w->item ());
+	    for (int i=0;i<4;++i)
+	    {
+	      Vertex v(3);
+	      for (int k=0;k<3;++k) 
+	        v[k] = item->myvertex(i)->Point()[k];
+	      vertexList[ item->myvertex(i)->getIndex() ] = make_pair(-1,v);
+	    }
+	    ++nCells;
+    }
+    if (showbnd)
+    {
+      for (wbnd->first () ; ! wbnd->done () ; wbnd->next ())
+        ++nBnd;
+    }
+    if (showface)
+    {
+      for (wface->first () ; ! wface->done () ; wface->next ())
+        ++nFaces;
     }
   }
 
   vtuFile << "    <Piece NumberOfPoints=\"" << vertexList.size() << "\" "
-          << "NumberOfCells=\"" << nCells << "\">" << std::endl;
+	        << "NumberOfCells=\"" << nCells+nBnd+nFaces << "\">" << std::endl;
 
   // cell data
   {
@@ -379,9 +420,69 @@ void Gitter :: tovtk( const std::string &fn )
 
     for (w->first () ; ! w->done () ; w->next ())
     {
-      vtuFile << w->item ().getIndex() << " ";
+	    tetra* item = ((tetra *) &w->item ());
+	    // vtuFile << item->getIndex() << " ";
+      bool ok = true;
+      for (int k=0;k<4;++k)
+        ok &= item->myneighbour( k ).first->isRealObject();
+      if (!ok)
+      {
+        std::cout << "Problem: " << item << std::endl;
+        for (int k=0;k<4;++k)
+          if (!item->myneighbour( k ).first->isRealObject())
+          {
+            std::cout << item->myhface3(k) << std::endl;
+            if ( item->myhface3(k)->nb.front().first->isRealObject() )
+            {
+              std::cout << item->myhface3(k)->nb.front().first << std::endl;
+              std::cout << ((bndseg *) item->myhface3(k)->nb.front().first)->myhface3(0) << std::endl;
+            }
+            if ( item->myhface3(k)->nb.rear().first->isRealObject() )
+            {
+              std::cout << item->myhface3(k)->nb.rear().first << std::endl;
+              std::cout << ((bndseg *) item->myhface3(k)->nb.rear().first)->myhface3(0) << std::endl;
+            }
+            std::cout << std::endl;
+          }
+        std::cout << std::endl;
+      }
+
+      vtuFile << ((ok)?1:-1) << " ";
     }
 
+    vtuFile << std::endl;
+    if (showbnd)
+      for (wbnd->first () ; ! wbnd->done () ; wbnd->next ())
+      {
+	      bndseg* item = ((bndseg *) &wbnd->item ());
+        bool ok = true;
+        ok &= item->myhface3(0)->nb.front().first->isRealObject();
+        ok &= item->myhface3(0)->nb.rear().first->isRealObject();
+        if (!ok)
+        {
+          if ( item->myhface3(0)->nb.front().first->isRealObject() )
+            assert( item->myhface3(0)->nb.front().first == item );
+          if ( item->myhface3(0)->nb.rear().first->isRealObject() )
+            assert( item->myhface3(0)->nb.rear().first == item );
+          std::cout << "Problem: " << item << std::endl;
+          std::cout << item->myhface3(0) << std::endl;
+          std::cout << item->myhface3(0)->nb.front().first << std::endl;
+          std::cout << item->myhface3(0)->nb.rear().first << std::endl;
+          std::cout << std::endl;
+        }
+        vtuFile << ((ok)?1:-1)*item->myhface3(0)->ref << " ";
+      }
+    if (showface)
+      for (wface->first () ; ! wface->done () ; wface->next ())
+      {
+	      face* item = ((face *) &wface->item ());
+        bool ok = true;
+        ok &= item->nb.front().first->isRealObject();
+        ok &= item->nb.rear().first->isRealObject();
+        assert(item->ref>0);
+        vtuFile << ((ok)?1:-1)*item->ref << " ";
+      }
+
     vtuFile << std::endl;
     vtuFile << "        </DataArray>" << std::endl;
     vtuFile << "      </CellData>" << std::endl;
@@ -413,12 +514,30 @@ void Gitter :: tovtk( const std::string &fn )
 
     for (w->first () ; ! w->done () ; w->next ())
     {
-      tetra_GEO* item = ((tetra_GEO *) &w->item ());
-      for (int i=0;i<4;++i)
+	    tetra* item = ((tetra *) &w->item ());
+	    for (int i=0;i<4;++i)
+	    {
+	      vtuFile << " " << vertexList[item->myvertex(i)->getIndex()].first;
+	    }
+    }
+    if (showbnd)
+      for (wbnd->first () ; ! wbnd->done () ; wbnd->next ())
       {
-        vtuFile << " " << vertexList[item->myvertex(i)->getIndex()].first;
+	      bndseg* item = ((bndseg *) &wbnd->item ());
+	      for (int i=0;i<3;++i)
+	      {
+	        vtuFile << " " << vertexList[item->myvertex(0,i)->getIndex()].first;
+	      }
+      }
+    if (showface)
+      for (wface->first () ; ! wface->done () ; wface->next ())
+      {
+	      face* item = ((face *) &wface->item ());
+	      for (int i=0;i<3;++i)
+	      {
+	        vtuFile << " " << vertexList[item->myvertex(i)->getIndex()].first;
+	      }
       }
-    }
     vtuFile << std::endl;
     vtuFile << "        </DataArray>" << std::endl;
 
@@ -428,7 +547,15 @@ void Gitter :: tovtk( const std::string &fn )
 
     for( int i = 0; i < nCells; ++i )
     {
-      vtuFile << " " << (i+1)*4;
+	    vtuFile << " " << (i+1)*4;
+    }
+    for( int i = 0; i < nBnd; ++i )
+    {
+	    vtuFile << " " << nCells*4 + (i+1)*3;
+    }
+    for( int i = 0; i < nFaces; ++i )
+    {
+	    vtuFile << " " << nCells*4 + nBnd*3 + (i+1)*3;
     }
     vtuFile << std::endl;
 
@@ -440,13 +567,20 @@ void Gitter :: tovtk( const std::string &fn )
 
     for( int i = 0; i < nCells; ++i )
     {
-      vtuFile << " " << 10; // 10 for tetrahedra
+	    vtuFile << " " << 10; // 10 for tetrahedra
+    }
+    for( int i = 0; i < nBnd; ++i )
+    {
+	    vtuFile << " " << 5; // 5 for triangle
+    }
+    for( int i = 0; i < nFaces; ++i )
+    {
+	    vtuFile << " " << 5; // 5 for trianglea
     }
     vtuFile << std::endl;
 
     vtuFile << "        </DataArray>" << std::endl;
   }
-
   vtuFile << "      </Cells>" << std::endl;
   vtuFile << "    </Piece>" << std::endl;
   vtuFile << "  </UnstructuredGrid>" << std::endl;
@@ -467,11 +601,9 @@ bool Gitter :: adapt ()
   do {
     refined &= refine ();
     // check for conformity
-    // if noconform break;
-    std::cout << "check non conform refinement" << std::endl;
     x = markNonConform();
   }
-  while (!x);  // need something here on required conformity
+  while (!x); 
 
   if (!refined) {
     cerr << "**WARNUNG (IGNORIERT) Verfeinerung nicht vollst\"andig (warum auch immer)\n" ;
@@ -480,6 +612,7 @@ bool Gitter :: adapt ()
   }
   int lap = clock () ;
   coarse () ;
+  assert ( markNonConform() );
   int end = clock () ;
   if (debugOption (1)) {
     float u1 = (float)(lap - start)/(float)(CLOCKS_PER_SEC) ;
diff --git a/src/serial/gitter_sti.h b/src/serial/gitter_sti.h
index 96a5056526dbe0efe75e9efe6502091bbeaddaab..2e33217854e998a5f007bbf1c17855efcc7630f7 100644
--- a/src/serial/gitter_sti.h
+++ b/src/serial/gitter_sti.h
@@ -573,6 +573,8 @@ public :
 
     virtual void backupIndex  (ObjectStream& os ) const { backupIndexErr(); }
     virtual void restoreIndex (ObjectStream& is, RestoreInfo& ) { restoreIndexErr(); }
+
+    virtual bool canCoarsen( std::vector<bool> &edgeCoarseningFlags ) const;
   } ;
     
   class hface : public FacePllXDefault, 
@@ -687,6 +689,7 @@ public :
     virtual int segmentIndex (const int) const { return -1; }
         
     virtual bool markNonConform () = 0;
+    virtual void markEdgeCoarsening () = 0;
     // mark element for using iso8 rule 
     virtual int tagForGlobalRefinement () = 0 ;
     // mark element for coarsening 
@@ -1564,6 +1567,7 @@ public :
       virtual myrule_t getrule () const = 0 ;
       virtual void request (myrule_t) = 0 ;
       virtual bool markNonConform () { return true; }
+      virtual void markEdgeCoarsening () { }
       int tagForGlobalRefinement () ;
       int tagForGlobalCoarsening () ;
       int resetRefinementRequest () ;
@@ -1655,6 +1659,7 @@ public :
       virtual myrule_t requestrule () const = 0;
       virtual void request (myrule_t) = 0 ;
       virtual bool markNonConform () { return true; }
+      virtual void markEdgeCoarsening () { }
       int tagForGlobalRefinement () ;
       int tagForGlobalCoarsening () ;
       int resetRefinementRequest () ;
@@ -1728,6 +1733,7 @@ public :
       virtual myrule_t getrule () const = 0 ;
       virtual void request (myrule_t) = 0 ;
       virtual bool markNonConform () { return true; }
+      virtual void markEdgeCoarsening () { }
       int tagForGlobalRefinement () ;
       int tagForGlobalCoarsening () ;
       int resetRefinementRequest () ;
@@ -1778,6 +1784,7 @@ public :
       virtual bool isperiodic() const { return false; }
 
       virtual bool markNonConform () { return true; }
+      virtual void markEdgeCoarsening () { }
       virtual int nChild () const;
       // just returns level 
       virtual int nbLevel() const { return level(); }
@@ -1827,6 +1834,7 @@ public :
       inline hface4_GEO * subface4 (int,int) const ;
       
       virtual bool markNonConform () { return true; }
+      virtual void markEdgeCoarsening () { }
       virtual bool isboundary() const { return true; }
       virtual bool isperiodic() const { return false; }
       virtual int nChild () const;
@@ -2026,6 +2034,7 @@ protected :
   // methods for refining and coarsening
   virtual bool refine () ;
   virtual bool markNonConform () ;
+  virtual void markEdgeCoarsening () ;
   virtual void coarse () ;
 
   virtual Makrogitter & container () = 0 ;
@@ -2096,6 +2105,10 @@ protected:
   friend class LevelIterator < hbndseg_STI > ;
   friend class LevelIterator < hedge_STI > ;
   friend class LevelIterator < hface_STI > ;
+
+  public:
+  // flags to say if an edge can be coarsened during conform bisection 
+  mutable std::vector<bool> edgeCoarseningFlags_;
 } ; 
 // --endGitter
 
@@ -2820,6 +2833,18 @@ inline const Gitter :: Geometric :: hedge1 :: myvertex_t * Gitter :: Geometric :
   return i == 1 ? v1 : v0 ;
 }
 
+
+
+inline bool Gitter :: hedge :: canCoarsen( std::vector<bool> &edgeCoarseningFlags ) const
+{
+  int idx = this->getIndex();
+  if ( !edgeCoarseningFlags[ idx ] ) return false;
+  if ( this->down() ) return this->down()->canCoarsen( edgeCoarseningFlags );
+  if ( this->next() ) return this->next()->canCoarsen( edgeCoarseningFlags );
+  return true;
+}
+
+             
 // #     #                                  #####  ######
 // #     #  ######    ##     ####   ###### #     # #     #  #    #  #       ######
 // #     #  #        #  #   #    #  #            # #     #  #    #  #       #
@@ -3031,8 +3056,8 @@ Gitter :: Geometric :: hface3 :: face3Neighbour :: setPrevRear ( )
 
 inline void Gitter :: Geometric :: hface3 :: face3Neighbour :: operator = (const face3Neighbour & n)
 {
-  frontList_ = n.frontList_;
-  rearList_ = n.rearList_;
+  frontList_.clear();
+  rearList_.clear();
   _faceFront = n._faceFront;
   _faceRear = n._faceRear;
   _numFront = n._numFront;
@@ -3043,6 +3068,7 @@ inline void Gitter :: Geometric :: hface3 :: face3Neighbour :: operator = (const
 inline int Gitter :: Geometric :: hface3 :: face3Neighbour :: complete (const face3Neighbour & n)
 {
   int ret = 0;
+  // assert(0);
 
   if( front() == null )
   {
@@ -3109,7 +3135,6 @@ inline void Gitter :: Geometric :: hface3 :: attachElement (const pair < myconne
     ref ++ ;
   if (t>=0 && nb.frontList_.size()==0)
     ref ++ ;
-
   if( t < 0 )
     nb.setRear( p );
   else
diff --git a/src/serial/gitter_tetra_top.cc b/src/serial/gitter_tetra_top.cc
index 34a97cd5e28bd4c5e43a696b9d0f772c2a046961..40475c5757da3e88b1d0bf66b4d41fc3dff2e633 100644
--- a/src/serial/gitter_tetra_top.cc
+++ b/src/serial/gitter_tetra_top.cc
@@ -422,7 +422,6 @@ template < class A > bool Hface3Top < A > :: coarse ()
   // vollst"andigt, die eventuell durch Elementvergr"oberung
   // durcheinander gekommen war. Die Vergr"oberung geht dann
   // auf das n"achste Level "uber.
-  
     if (f->ref) {
       if (f->ref == 1) f->nb.complete (this->nb) ;
       f->coarse () ;
@@ -2103,6 +2102,7 @@ template < class A >  bool TetraTop < A > :: coarse ()
 {
   if (this->leaf ()) 
   {
+    if (!up()) return false;
     assert (_req == myrule_t :: nosplit || _req == myrule_t :: crs) ;
     myrule_t w = _req ;
     _req = myrule_t :: nosplit ;
@@ -2132,12 +2132,34 @@ template < class A >  bool TetraTop < A > :: coarse ()
     // not faces that are not leaf 
     if (x) 
     {
+      // test marking on refinement edge 
+      assert( this->nEdges() == 6 );
+      // int e = getrule()-2;  // did not work....
+      for (int e=0;e<6;++e)
+      {
+        myhedge1_t *edge = this->myhedge1(e);
+        if ( edge->down() )
+        {
+          int idx = edge->getIndex();
+          if ( !this->myGrid()->edgeCoarseningFlags_[ idx ] ) 
+            return false;
+          // we need to make sure that none of the children of this
+          // refinement edge should not be removed
+          // (we could not go up on edges during marking so we go down here)
+          if (! edge->down()->canCoarsen( this->myGrid()->edgeCoarseningFlags_ ) ) 
+          {
+            return false;
+          }
+        }
+      }
+
       this->preCoarsening () ;
       this->attachleafs();
 
       delete _inner ; 
       _inner = 0 ;
 
+#if 0
       // for bisection refinement we have to again 
       // set the face neighbours, since they have been overwritten   
       // by the refined element  
@@ -2158,6 +2180,7 @@ template < class A >  bool TetraTop < A > :: coarse ()
           }
         }
       }
+#endif
 
       // reset refinement rule 
       _rule = myrule_t :: nosplit ;
diff --git a/src/serial/gitter_tetra_top.h b/src/serial/gitter_tetra_top.h
index 3496dd23c581d12c6780641ba651aced1c3a77b3..e423a744ed011fa225c5087f2451ac7d659486b6 100644
--- a/src/serial/gitter_tetra_top.h
+++ b/src/serial/gitter_tetra_top.h
@@ -403,7 +403,6 @@ template < class A > class TetraTop : public A
       assert( this->nEdges() == 6 );
       for (int e=0; e < 6; ++e)
       {
-        // std::cout << this->myhedge1(e) << std::endl;
         if( this->myhedge1(e)->down() )
         {
           this->request ( myrule_t :: bisect );
@@ -412,6 +411,24 @@ template < class A > class TetraTop : public A
       }
       return true;
     }
+    virtual void markEdgeCoarsening () 
+    { 
+      assert( this->nEdges() == 6 );
+      if (!this->up()) return;
+      for (int e=0; e<6; ++e)
+      {
+        myhedge1_t *edge = this->up()->myhedge1(e);
+        // if (e == (int)(this->up()->getrule())-2) // does not seem to // work...
+        if (_req == myrule_t :: crs && edge->down()) // the father of a leaf element can only have one non leaf edge
+        { // we leave thing as they are
+        }
+        else
+        {  
+          int idx = edge->getIndex();
+          this->myGrid()->edgeCoarseningFlags_[ idx ] = false;
+        }
+      }
+    }
 
     void refineImmediate (myrule_t) ;
     inline void append (innertetra_t * h) ;