diff --git a/AMDiS/src/Mesh.cc b/AMDiS/src/Mesh.cc
index f140ca49fa53d2e0c329850e933ac15399709d29..5d3e7f499f2691b49158feb80e55dc0e0fed999c 100644
--- a/AMDiS/src/Mesh.cc
+++ b/AMDiS/src/Mesh.cc
@@ -333,9 +333,9 @@ namespace AMDiS {
 
       // Go through all neighbours of the macro element and remove this macro element
       // to be neighbour of some other macro element.
-      for (int i = 0; i <= dim; i++)
+      for (int i = 0; i < getGeo(NEIGH); i++)
 	if ((*macroIt)->getNeighbour(i))
-	  for (int j = 0; j <= dim; j++)
+	  for (int j = 0; j < getGeo(NEIGH); j++)
 	    if ((*macroIt)->getNeighbour(i)->getNeighbour(j) == *macroIt)
 	      (*macroIt)->getNeighbour(i)->setNeighbour(j, NULL);
 
@@ -352,13 +352,13 @@ namespace AMDiS {
 
       // We will delete at least some element DOFs in the next but will keep the
       // element object still in memory. Therefore the DOF pointer must be set to be
-      // invalide.
+      // invalid.
       (*macroIt)->getElement()->setDofValid(false);
     }     
 
 
-    // === Check now all the dofs, that have no owner anymore and therefore have ===
-    // === to be removed.                                                        ===
+    // === Check now all the DOFs that have no owner anymore and therefore have ===
+    // === to be removed.                                                       ===
 
     for (DofElMap::iterator dofsIt = dofsOwner.begin(); 
 	 dofsIt != dofsOwner.end(); ++dofsIt) {
diff --git a/AMDiS/src/io/DataCollector.cc b/AMDiS/src/io/DataCollector.cc
index 6c20185634e8dc775450ea5d4a54701dd674a99a..6125ec61af63a64018257b4a47dd38e6398d0bf2 100644
--- a/AMDiS/src/io/DataCollector.cc
+++ b/AMDiS/src/io/DataCollector.cc
@@ -217,11 +217,11 @@ namespace AMDiS {
     FUNCNAME("DataCollector::addElementData()");
 
     const DegreeOfFreedom **dof = elInfo->getElement()->getDof();
-    DegreeOfFreedom vertexDOF;
-    WorldVector<double> vertexCoords;
 
-    // MSG("ELEMENT: %d\n", elInfo->getElement()->getIndex());
-    // MSG("DOFs: %d %d %d\n", dof[0][0], dof[1][0], dof[2][0]);
+//     MSG("ELEMENT: %d %d\n", 
+// 	elInfo->getElement()->getIndex(),
+// 	elInfo->getMacroElement()->getIndex());    
+//     MSG("DOFs: %d %d %d %d\n", dof[0][0], dof[1][0], dof[2][0], dof[3][0]);
 
     // create ElementInfo
     ElementInfo elementInfo(dim);
@@ -244,28 +244,28 @@ namespace AMDiS {
     }
 
     // for all vertices
-    for (int i = 0; i < dim + 1; i++) {
+    for (int i = 0; i < mesh->getGeo(VERTEX); i++) {
       // get coords of this vertex
-      vertexCoords = elInfo->getCoord(i);
+      WorldVector<double> &vertexCoords = elInfo->getCoord(i);
       
       // get dof index of this vertex
-      vertexDOF = dof[i][nPreDofs];
+      DegreeOfFreedom vertexDof = dof[i][nPreDofs];
 
       // search for coords at this dof
       std::list<VertexInfo>::iterator it =
-	  find((*vertexInfos)[vertexDOF].begin(), (*vertexInfos)[vertexDOF].end(),
+	  find((*vertexInfos)[vertexDof].begin(), (*vertexInfos)[vertexDof].end(),
 	       vertexCoords);
       
       // coords not yet in list?
-      if (it == (*vertexInfos)[vertexDOF].end()) {
+      if (it == (*vertexInfos)[vertexDof].end()) {
 	// create new vertex info and increment number of vertices
 	VertexInfo newVertexInfo = {vertexCoords, nVertices};
 
 	// add new vertex info to list
-	(*vertexInfos)[vertexDOF].push_front(newVertexInfo);
+	(*vertexInfos)[vertexDof].push_front(newVertexInfo);
 
 	// set iterator to new vertex info
-	it = (*vertexInfos)[vertexDOF].begin();	
+	it = (*vertexInfos)[vertexDof].begin();	
 
 	nVertices++;
       }
diff --git a/AMDiS/src/io/VtkWriter.cc b/AMDiS/src/io/VtkWriter.cc
index 41db97c3cf895a51a82a5c16fac4f9180caa9cb1..1d0503610b588b7a22d0550fd8db1a02c027e4b3 100644
--- a/AMDiS/src/io/VtkWriter.cc
+++ b/AMDiS/src/io/VtkWriter.cc
@@ -56,16 +56,6 @@ namespace AMDiS {
     file.push(boost::iostreams::file_descriptor_sink(name, std::ios::trunc)); 
     writeFileToStream(file);
 
-#if 0
-
-    std::ofstream file;
-    file.open(name.c_str());
-    TEST_EXIT(file.is_open())("Cannot open file %s for writing\n", name.c_str());
-    writeFileToStream(file);    
-    file.close();
-
-#endif
-      
     return 0;
   }
 
@@ -159,7 +149,7 @@ namespace AMDiS {
     DataCollector dc(values->getFeSpace(), values);
     std::vector<DataCollector*> dcList(0);
     dcList.push_back(&dc);
-    writeFile(dcList,filename,writeParallel);
+    writeFile(dcList, filename, writeParallel);
   }
 
 
diff --git a/AMDiS/src/io/VtkWriter.hh b/AMDiS/src/io/VtkWriter.hh
index 473c028ef4d3753494ef26fb52f3bd4be5a90eb2..214e1e83d8a9aad0eec917267ae50f1c62cf942b 100644
--- a/AMDiS/src/io/VtkWriter.hh
+++ b/AMDiS/src/io/VtkWriter.hh
@@ -19,6 +19,8 @@ namespace AMDiS {
   template<typename T>
   void VtkWriter::writeFileToStream(T &file)
   {
+    FUNCNAME("VtkWriter::writeFileToStream()");
+
     int nVertices = (*dataCollector)[0]->getNumberVertices();
     int nElements = (*dataCollector)[0]->getNumberElements();
     int vertices = (*dataCollector)[0]->getMesh()->getGeo(VERTEX);
diff --git a/AMDiS/src/parallel/ElementObjectData.cc b/AMDiS/src/parallel/ElementObjectData.cc
index a97b17e5c38dc514850c2af2ce2c801ac7670f0f..708574506697a05d82d2a9775b382f3bf308049e 100644
--- a/AMDiS/src/parallel/ElementObjectData.cc
+++ b/AMDiS/src/parallel/ElementObjectData.cc
@@ -336,7 +336,7 @@ namespace AMDiS {
     FUNCNAME("ElementObjects::provideConnectedPeriodicBoundary()");
 
     std::pair<BoundaryType, BoundaryType> bConn = 
-      (b0 <= b1 ? std::make_pair(b0, b1) : std::make_pair(b1, b0));
+      (b0 <= b1 ? make_pair(b0, b1) : make_pair(b1, b0));
 
     if (bConnMap.count(bConn) == 0) {
       BoundaryType newPeriodicBoundaryType = getNewBoundaryType();
@@ -417,6 +417,65 @@ namespace AMDiS {
   }
 
 
+  void ElementObjects::createReverseModeData(map<int, Element*> &elIndexMap,
+					     map<int, int> &elIndexTypeMap)
+  {
+    FUNCNAME("ElementObjects::createReverseModeData()");
+
+    // In 2D, all reverse modes are always true!
+    if (mesh->getDim() == 2)
+      return;
+
+    for (map<DofEdge, vector<ElementObjectData> >::iterator edgeIt = edgeElements.begin();
+	 edgeIt != edgeElements.end(); ++edgeIt) {
+
+      vector<ElementObjectData>& els = edgeIt->second;
+
+      for (unsigned int i = 0; i < els.size(); i++) {
+	BoundaryObject obj0(elIndexMap[els[i].elIndex], 
+			    elIndexTypeMap[els[i].elIndex], 
+			    EDGE, els[i].ithObject);
+
+	for (unsigned int j = i + 1; j < els.size(); j++) {
+	  BoundaryObject obj1(elIndexMap[els[j].elIndex], 
+			      elIndexTypeMap[els[j].elIndex], 
+			      EDGE, els[j].ithObject);
+
+	  bool reverseMode = 
+	    BoundaryObject::computeReverseMode(obj0, obj1, feSpace, INTERIOR);
+
+	  edgeReverseMode[make_pair(els[i], els[j])] = reverseMode;
+	  edgeReverseMode[make_pair(els[j], els[i])] = reverseMode;
+	}
+      }
+    }
+
+    for (map<DofFace, vector<ElementObjectData> >::iterator faceIt = faceElements.begin();
+	 faceIt != faceElements.end(); ++faceIt) {
+
+      vector<ElementObjectData>& els = faceIt->second;
+
+      for (unsigned int i = 0; i < els.size(); i++) {
+	BoundaryObject obj0(elIndexMap[els[i].elIndex], 
+			    elIndexTypeMap[els[i].elIndex], 
+			    FACE, els[i].ithObject);
+
+	for (unsigned int j = i + 1; j < els.size(); j++) {
+	  BoundaryObject obj1(elIndexMap[els[j].elIndex], 
+			      elIndexTypeMap[els[j].elIndex], 
+			      FACE, els[j].ithObject);
+
+	  bool reverseMode = 
+	    BoundaryObject::computeReverseMode(obj0, obj1, feSpace, INTERIOR);
+
+	  faceReverseMode[make_pair(els[i], els[j])] = reverseMode;
+	  faceReverseMode[make_pair(els[j], els[i])] = reverseMode;
+	}
+      }
+    }
+  }
+
+
   void ElementObjects::serialize(ostream &out)
   {
     FUNCNAME("ElementObjects::serialize()");
@@ -505,6 +564,42 @@ namespace AMDiS {
     SerUtil::serialize(out, periodicVertices);
     SerUtil::serialize(out, periodicEdges);
     SerUtil::serialize(out, periodicFaces);
+
+
+    nSize = periodicDofAssoc.size();
+    SerUtil::serialize(out, nSize);
+    for (map<DegreeOfFreedom, std::set<BoundaryType> >::iterator it = periodicDofAssoc.begin();
+	 it != periodicDofAssoc.end(); ++it) {
+      SerUtil::serialize(out, it->first);
+      SerUtil::serialize(out, it->second);
+    }
+
+    nSize = periodicEdgeAssoc.size();
+    SerUtil::serialize(out, nSize);
+    for (map<DofEdge, std::set<DofEdge> >::iterator it = periodicEdgeAssoc.begin();
+	 it != periodicEdgeAssoc.end(); ++it) {
+      SerUtil::serialize(out, it->first);
+      SerUtil::serialize(out, it->second);
+    }
+
+
+    nSize = edgeReverseMode.size();
+    SerUtil::serialize(out, nSize);
+    for (map<pair<ElementObjectData, ElementObjectData>, bool>::iterator it = edgeReverseMode.begin();
+	 it != edgeReverseMode.end(); ++it) {
+      it->first.first.serialize(out);
+      it->first.second.serialize(out);
+      SerUtil::serialize(out, it->second);
+    }
+
+    nSize = faceReverseMode.size();
+    SerUtil::serialize(out, nSize);
+    for (map<pair<ElementObjectData, ElementObjectData>, bool>::iterator it = faceReverseMode.begin();
+	 it != faceReverseMode.end(); ++it) {
+      it->first.first.serialize(out);
+      it->first.second.serialize(out);
+      SerUtil::serialize(out, it->second);
+    }
   }
 
 
@@ -613,7 +708,55 @@ namespace AMDiS {
 
     SerUtil::deserialize(in, periodicVertices);
     SerUtil::deserialize(in, periodicEdges);
-    SerUtil::deserialize(in, periodicFaces);  
+    SerUtil::deserialize(in, periodicFaces);
+
+    
+
+    SerUtil::deserialize(in, nSize);
+    periodicDofAssoc.clear();
+    for (int i = 0; i < nSize; i++) {
+      DegreeOfFreedom dof;
+      std::set<DegreeOfFreedom> dofs;
+      SerUtil::deserialize(in, dof);
+      SerUtil::deserialize(in, dofs);
+      periodicDofAssoc[dof] = dofs;
+    }
+
+    SerUtil::deserialize(in, nSize);
+    periodicEdgeAssoc.clear();
+    for (int i = 0; i < nSize; i++) {
+      DofEdge edge;
+      std::set<DofEdge> edges;
+      SerUtil::deserialize(in, edge);
+      SerUtil::deserialize(in, edges);
+      periodicEdgeAssoc[edge] = edges;
+    }
+
+
+
+    SerUtil::deserialize(in, nSize);
+    edgeReverseMode.clear();
+    for (int i = 0; i < nSize; i++) {
+      ElementObjectData obj0, obj1;
+      bool reverseMode;
+      obj0.deserialize(in);
+      obj1.deserialize(in);
+      SerUtil::deserialize(in, reverseMode);
+
+      edgeReverseMode[make_pair(obj0, obj1)] = reverseMode;
+    }
+
+    SerUtil::deserialize(in, nSize);
+    faceReverseMode.clear();
+    for (int i = 0; i < nSize; i++) {
+      ElementObjectData obj0, obj1;
+      bool reverseMode;
+      obj0.deserialize(in);
+      obj1.deserialize(in);
+      SerUtil::deserialize(in, reverseMode);
+
+      faceReverseMode[make_pair(obj0, obj1)] = reverseMode;
+    }
   }
 
 
diff --git a/AMDiS/src/parallel/ElementObjectData.h b/AMDiS/src/parallel/ElementObjectData.h
index d859595dd28f509af18b7b8691682cdccff770ef..2bf63bd2c48e82a724955b7a62d70a3b76dba43c 100644
--- a/AMDiS/src/parallel/ElementObjectData.h
+++ b/AMDiS/src/parallel/ElementObjectData.h
@@ -148,6 +148,9 @@ namespace AMDiS {
      */
     void createRankData(map<int, int>& macroElementRankMap);
 
+    void createReverseModeData(map<int, Element*> &elIndexMap,
+			       map<int, int> &elIndexTypeMap);
+
 
     /** \brief
      * Iterates over all elements for one geometrical index, i.e., over all vertices,
@@ -320,6 +323,32 @@ namespace AMDiS {
       return faceElements[face];
     }
 
+
+    /// Returns a vector with all macro elements that have a given vertex DOF in common.
+    vector<ElementObjectData>& getElementsVertex(int elIndex, int ithVertex)
+    {
+      ElementObjectData elObj(elIndex, ithVertex);
+      DegreeOfFreedom vertex = vertexLocalMap[elObj];
+      return vertexElements[vertex];
+    }
+    
+    /// Returns a vector with all macro elements that have a given edge in common.
+    vector<ElementObjectData>& getElementsEdge(int elIndex, int ithEdge)
+    {
+      ElementObjectData elObj(elIndex, ithEdge);
+      DofEdge edge = edgeLocalMap[elObj];
+      return edgeElements[edge];
+    }
+
+    /// Returns a vector with all macro elements that have a given face in common.
+    vector<ElementObjectData>& getElementsFace(int elIndex, int ithFace)
+    {
+      ElementObjectData elObj(elIndex, ithFace);
+      DofFace face = faceLocalMap[elObj];
+      return faceElements[face];
+    }
+
+
     
     /// Returns a map that maps to each rank all macro elements in this rank that
     /// have a given vertex DOF in common.
@@ -381,6 +410,22 @@ namespace AMDiS {
       return periodicFaces;
     }
 
+    bool getEdgeReverseMode(ElementObjectData &obj0, ElementObjectData &obj1)
+    {
+      TEST_EXIT_DBG(edgeReverseMode.count(make_pair(obj0, obj1)))
+	("Should not happen!\n");
+
+      return edgeReverseMode[make_pair(obj0, obj1)];
+    }
+
+    bool getFaceReverseMode(ElementObjectData &obj0, ElementObjectData &obj1)
+    {
+      TEST_EXIT_DBG(faceReverseMode.count(make_pair(obj0, obj1)))
+	("Should not happen!\n");
+
+      return faceReverseMode[make_pair(obj0, obj1)];
+    }
+
     /// Write the element database to disk.
     void serialize(ostream &out);
     
@@ -505,7 +550,7 @@ namespace AMDiS {
     /// iterators, i.e., if no iteration is running.
     GeoIndex iterGeoPos;
 
-    std::map<std::pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
+    map<pair<BoundaryType, BoundaryType>, BoundaryType> bConnMap;
 
     // The following three data structures store periodic DOFs, edges and faces.
     PerBoundMap<DegreeOfFreedom>::type periodicVertices;
@@ -513,10 +558,14 @@ namespace AMDiS {
     PerBoundMap<DofFace>::type periodicFaces;
 
     // Stores to each vertex all its periodic associations.
-    std::map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
+    map<DegreeOfFreedom, std::set<BoundaryType> > periodicDofAssoc;
 
     // Stores to each edge all its periodic associations.
-    std::map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
+    map<DofEdge, std::set<DofEdge> > periodicEdgeAssoc;
+
+    map<pair<ElementObjectData, ElementObjectData>, bool> edgeReverseMode;
+
+    map<pair<ElementObjectData, ElementObjectData>, bool> faceReverseMode;
   };
 
 }
diff --git a/AMDiS/src/parallel/InteriorBoundary.cc b/AMDiS/src/parallel/InteriorBoundary.cc
index 4c8e92469f7f88d62f5e3e3ffba86642d6f47ef2..9b4366245b3c8f0dcc02b0b83966bdb1b01bfa9f 100644
--- a/AMDiS/src/parallel/InteriorBoundary.cc
+++ b/AMDiS/src/parallel/InteriorBoundary.cc
@@ -18,35 +18,38 @@
 
 namespace AMDiS {
 
-  void BoundaryObject::setReverseMode(BoundaryObject &otherBound, 
-				      FiniteElemSpace *feSpace,
-				      BoundaryType boundary)
+
+  bool BoundaryObject::computeReverseMode(BoundaryObject &obj0, 
+					  BoundaryObject &obj1,
+					  FiniteElemSpace *feSpace,
+					  BoundaryType boundary)
   {
-    FUNCNAME("BoundaryObject::setReverseMode()");
+    FUNCNAME("BoundaryObject::computeReverseMode()");
 
-    bool otherMode = false;
+    bool reverseMode = false;
 
     switch (feSpace->getMesh()->getDim()) {
     case 2:
-      otherMode = true;
+      reverseMode = true;
       break;
 
     case 3:
-      TEST_EXIT_DBG(otherBound.elType == 0)
-	("Only 3D macro elements with level 0 are supported. This element has level %d!\n", otherBound.elType);
+      TEST_EXIT_DBG(obj1.elType == 0)
+	("Only 3D macro elements with level 0 are supported. This element has level %d!\n", 
+	 obj1.elType);
 
 
-      if (subObj == EDGE) {	
-	int el0_v0 = el->getVertexOfEdge(ithObj, 0);
-	int el0_v1 = el->getVertexOfEdge(ithObj, 1);
-	int el1_v0 = el->getVertexOfEdge(otherBound.ithObj, 0);
-	int el1_v1 = el->getVertexOfEdge(otherBound.ithObj, 1);
+      if (obj0.subObj == EDGE) {	
+	int el0_v0 = obj0.el->getVertexOfEdge(obj0.ithObj, 0);
+	int el0_v1 = obj0.el->getVertexOfEdge(obj0.ithObj, 1);
+	int el1_v0 = obj0.el->getVertexOfEdge(obj1.ithObj, 0);
+	int el1_v1 = obj0.el->getVertexOfEdge(obj1.ithObj, 1);
 
 	const BasisFunction *basFcts = feSpace->getBasisFcts();
 	int nBasFcts = basFcts->getNumber();
 	std::vector<DegreeOfFreedom> localDofs0(nBasFcts), localDofs1(nBasFcts);
-	basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0);
-	basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1);
+	basFcts->getLocalIndices(obj0.el, feSpace->getAdmin(), localDofs0);
+	basFcts->getLocalIndices(obj1.el, feSpace->getAdmin(), localDofs1);
 
 	Mesh *mesh = feSpace->getMesh();
 
@@ -59,30 +62,25 @@ namespace AMDiS {
 	    ("This should not happen!\n");
 
 	  if (localDofs0[el0_v0] != localDofs1[el1_v0])
-	    otherMode = true; 	
+	    reverseMode = true; 	
 	} else {
 	  if (mesh->associated(localDofs0[el0_v0], localDofs1[el1_v0]) == false)
-	    otherMode = true;
-
-	  if ((elIndex == 28 && otherBound.elIndex == 41) ||
-	      (elIndex == 41 && otherBound.elIndex == 28)) {
-	    MSG("HERE TEST B (%d %d): %d\n", el0_v0, el1_v0, otherMode);
-	  }
+	    reverseMode = true;
 	}
       }
 
-      if (subObj == FACE && ithObj != 1) {
+      if (obj0.subObj == FACE && obj0.ithObj != 1) {
 	const BasisFunction *basFcts = feSpace->getBasisFcts();
 	int nBasFcts = basFcts->getNumber();
 	std::vector<DegreeOfFreedom> localDofs0(nBasFcts), localDofs1(nBasFcts);
-	basFcts->getLocalIndices(el, feSpace->getAdmin(), localDofs0);
-	basFcts->getLocalIndices(otherBound.el, feSpace->getAdmin(), localDofs1);
+	basFcts->getLocalIndices(obj0.el, feSpace->getAdmin(), localDofs0);
+	basFcts->getLocalIndices(obj1.el, feSpace->getAdmin(), localDofs1);
 	
-	if (ithObj == 2 || ithObj == 3)
-	  otherMode = (localDofs0[0] != localDofs1[0]);
+	if (obj0.ithObj == 2 || obj0.ithObj == 3)
+	  reverseMode = (localDofs0[0] != localDofs1[0]);
 	  
-	if (ithObj == 0)
-	  otherMode = (localDofs0[1] != localDofs1[1]);
+	if (obj0.ithObj == 0)
+	  reverseMode = (localDofs0[1] != localDofs1[1]);
       }
       break;
 
@@ -90,14 +88,23 @@ namespace AMDiS {
       ERROR_EXIT("This should not happen!\n");
     }
 
-    otherBound.reverseMode = otherMode;
+    return reverseMode;
+  }
+
+
+  void BoundaryObject::setReverseMode(BoundaryObject &otherBound, 
+				      FiniteElemSpace *feSpace,
+				      BoundaryType boundary)
+  {
+    FUNCNAME("BoundaryObject::setReverseMode()");
+
+    otherBound.reverseMode = computeReverseMode(*this, otherBound, feSpace, boundary);
   }
 
 
   bool BoundaryObject::operator==(const BoundaryObject& other) const
   {
     return (other.elIndex == elIndex && 
-	    //	    other.elType == elType &&
 	    other.subObj == subObj && 
 	    other.ithObj == ithObj);
   }
@@ -106,7 +113,6 @@ namespace AMDiS {
   bool BoundaryObject::operator!=(const BoundaryObject& other) const
   {
     return (other.elIndex != elIndex || 
-	    //    other.elType != elType ||
 	    other.subObj != subObj || 
 	    other.ithObj != ithObj);
   }
diff --git a/AMDiS/src/parallel/InteriorBoundary.h b/AMDiS/src/parallel/InteriorBoundary.h
index 81280de026a99c88033b6498747b0f20fa2f06fc..b68bff77c1722bb157827059fc7587a15aafbf78 100644
--- a/AMDiS/src/parallel/InteriorBoundary.h
+++ b/AMDiS/src/parallel/InteriorBoundary.h
@@ -54,6 +54,11 @@ namespace AMDiS {
 	excludedSubstructures(0)
     {}
 
+    static bool computeReverseMode(BoundaryObject &obj0,
+				   BoundaryObject &obj1,
+				   FiniteElemSpace *feSpace,
+				   BoundaryType boundary);
+
     void setReverseMode(BoundaryObject &otherBound, 
 			FiniteElemSpace *feSpace,
 			BoundaryType boundary);
diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc
index f1d9fe6166bcb3181986100ca622c6c1db8ff555..9c64ffde0e9df42fffa8dfaf838a82b42c17b860 100644
--- a/AMDiS/src/parallel/MeshDistributor.cc
+++ b/AMDiS/src/parallel/MeshDistributor.cc
@@ -92,6 +92,8 @@ namespace AMDiS {
     tmp = 0;
     GET_PARAMETER(0, name + "->log main rank", "%d", &tmp);
     Msg::outputMainRank = (tmp > 0);
+
+    partitioner = new ParMetisPartitioner(&mpiComm);
   }
 
 
@@ -120,18 +122,12 @@ namespace AMDiS {
       macroElIndexMap.clear();
       macroElIndexTypeMap.clear();
 
-      map<int, bool>& elementInRank = partitioner->getElementInRank();
       for (vector<MacroElement*>::iterator it = allMacroElements.begin();
 	   it != allMacroElements.end(); ++it) {
-	elementInRank[(*it)->getIndex()] = false;
 	macroElIndexMap[(*it)->getIndex()] = (*it)->getElement();
 	macroElIndexTypeMap[(*it)->getIndex()] = (*it)->getElType();
       }
 
-      for (deque<MacroElement*>::iterator it = mesh->getMacroElements().begin();
-	   it != mesh->getMacroElements().end(); ++it)
-	elementInRank[(*it)->getIndex()] = true;      
-
       return;
     }
 
@@ -146,7 +142,7 @@ namespace AMDiS {
     createMacroElementInfo();
 
     // create an initial partitioning of the mesh
-    partitioner->createPartitionData();
+    partitioner->createInitialPartitioning();
 
     // set the element weights, which are 1 at the very first begin
     setInitialElementWeights();
@@ -316,7 +312,7 @@ namespace AMDiS {
 	ERROR_EXIT("This should not happen for dim = %d!\n", mesh->getDim());
       }
 
-      partitioner = new ParMetisPartitioner(mesh, &mpiComm);
+      partitioner->setMesh(mesh);
     }
 
     // Create parallel serialization file writer, if needed.
@@ -699,9 +695,7 @@ namespace AMDiS {
 
     updateLocalGlobalNumbering();
 
-
     // === Update periodic mapping, if there are periodic boundaries. ===
-
     createPeriodicMap();
 
     INFO(info, 8)("Parallel mesh adaption needed %.5f seconds\n", 
@@ -981,6 +975,8 @@ namespace AMDiS {
 
     for (std::set<MacroElement*>::iterator it = newMacroEl.begin();
 	 it != newMacroEl.end(); ++it) {
+      MSG("NEW MACRO EL: %d\n", (*it)->getIndex());
+
       MacroElement *mel = *it;
 
       // First, reset all neighbour relations. The correct neighbours will be set later.
@@ -1100,6 +1096,8 @@ namespace AMDiS {
 	  ("Could not find macro element %d\n", *elIt);
 
 	deleteMacroElements.insert(elIndexMap[*elIt]);
+
+	MSG("REMOVE MACRO EL: %d\n", *elIt);
       }
     }
 
@@ -1114,12 +1112,93 @@ namespace AMDiS {
     MeshManipulation meshManipulation(feSpace);
     meshManipulation.deleteDoubleDofs(newMacroEl, elObjects);
 
-    mesh->dofCompress();
+#if 0
+    {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL);
+    while (elInfo) {
+      MSG("HAVE MACRO EL %d\n", elInfo->getMacroElement()->getIndex());
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    }
+
+    {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
+    while (elInfo) {
+      MSG("A-CHECK DOFs ON %d: %d %d %d %d\n", 
+	  elInfo->getElement()->getIndex(),
+	  elInfo->getElement()->getDof(0, 0),
+	  elInfo->getElement()->getDof(1, 0),
+	  elInfo->getElement()->getDof(2, 0),
+	  elInfo->getElement()->getDof(3, 0));
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    }
+#endif
 
+    mesh->dofCompress();
     partitioner->fillCoarsePartitionVec(&partitionVec);
+
+#if 0
+    {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
+    while (elInfo) {
+      MSG("B-CHECK DOFs ON %d: %d %d %d %d\n", 
+	  elInfo->getElement()->getIndex(),
+	  elInfo->getElement()->getDof(0, 0),
+	  elInfo->getElement()->getDof(1, 0),
+	  elInfo->getElement()->getDof(2, 0),
+	  elInfo->getElement()->getDof(3, 0));
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    }
+#endif
+
     updateInteriorBoundaryInfo();
+
+#if 0
+    {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
+    while (elInfo) {
+      MSG("C-CHECK DOFs ON %d: %d %d %d %d\n", 
+	  elInfo->getElement()->getIndex(),
+	  elInfo->getElement()->getDof(0, 0),
+	  elInfo->getElement()->getDof(1, 0),
+	  elInfo->getElement()->getDof(2, 0),
+	  elInfo->getElement()->getDof(3, 0));
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    }
+#endif
+
     updateLocalGlobalNumbering();
 
+#if 0
+    {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL);
+    while (elInfo) {
+      MSG("D-CHECK DOFs ON %d: %d %d %d %d\n", 
+	  elInfo->getElement()->getIndex(),
+	  elInfo->getElement()->getDof(0, 0),
+	  elInfo->getElement()->getDof(1, 0),
+	  elInfo->getElement()->getDof(2, 0),
+	  elInfo->getElement()->getDof(3, 0));
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    }
+#endif
+
+
+
 #if (DEBUG != 0)
     MSG("AMDiS runs in debug mode, so make some test ...\n");
 
@@ -1183,6 +1262,9 @@ namespace AMDiS {
       elInfo = stack.traverseNext(elInfo);
     }
 
+
+    elObjects.createReverseModeData(macroElIndexMap, macroElIndexTypeMap);
+
     // === Create periodic data, if there are periodic boundary conditions. ===
     elObjects.createPeriodicData();
 
@@ -1196,7 +1278,6 @@ namespace AMDiS {
   {
     FUNCNAME("MeshDistributor::createBoundaryData()");
 
-
     // === Clear all relevant data structures. ===
 
     myIntBoundary.clear();
@@ -1250,7 +1331,11 @@ namespace AMDiS {
 	      
 	      AtomicBoundary& b = myIntBoundary.getNewAtomic(it2->first);
 	      b = bound;
-	      b.rankObj.setReverseMode(b.neighObj, feSpace, bound.type);
+	      //	      b.rankObj.setReverseMode(b.neighObj, feSpace, bound.type);
+	      if (geoIndex == EDGE)
+		b.neighObj.reverseMode = elObjects.getEdgeReverseMode(rankBoundEl, it2->second);
+	      if (geoIndex == FACE)
+		b.neighObj.reverseMode = elObjects.getFaceReverseMode(rankBoundEl, it2->second);
 	    }
 	    
 	  } else {
@@ -1269,13 +1354,19 @@ namespace AMDiS {
 	    
 	    AtomicBoundary& b = otherIntBoundary.getNewAtomic(owner);
 	    b = bound;	 
-	    b.neighObj.setReverseMode(b.rankObj, feSpace, bound.type);
+
+	    //	    b.neighObj.setReverseMode(b.rankObj, feSpace, bound.type);
+	    
+	    if (geoIndex == EDGE)
+	      b.rankObj.reverseMode = elObjects.getEdgeReverseMode(rankBoundEl, ownerBoundEl);
+	    if (geoIndex == FACE)
+	      b.rankObj.reverseMode = elObjects.getFaceReverseMode(rankBoundEl, ownerBoundEl);
 	  }
 	}
       }
     }
     
-    
+  
     // === Create periodic boundary data structure. ===
 
     for (PerBoundMap<DegreeOfFreedom>::iterator it = elObjects.getPeriodicVertices().begin();
@@ -1902,6 +1993,8 @@ namespace AMDiS {
 
     checkMeshChange();
 
+    partitioner->serialize(out);
+
     SerUtil::serialize(out, elemWeights);
     SerUtil::serialize(out, partitionVec);
     SerUtil::serialize(out, oldPartitionVec);
@@ -1941,6 +2034,8 @@ namespace AMDiS {
   {
     FUNCNAME("MeshDistributor::deserialize()");
 
+    partitioner->deserialize(in);
+
     SerUtil::deserialize(in, elemWeights);
     SerUtil::deserialize(in, partitionVec);
     SerUtil::deserialize(in, oldPartitionVec);
diff --git a/AMDiS/src/parallel/MeshManipulation.cc b/AMDiS/src/parallel/MeshManipulation.cc
index e72c4cd96d0b4eaf986dde5f7ed5679ce1bb0139..e17f001194de3a3b01f6d01e5ea24d34f66b4934 100644
--- a/AMDiS/src/parallel/MeshManipulation.cc
+++ b/AMDiS/src/parallel/MeshManipulation.cc
@@ -47,22 +47,19 @@ namespace AMDiS {
   {
     FUNCNAME("MeshManipulation::deleteDoubleDofs()");
 
-    TEST_EXIT(mesh->getDim() == 2)("Not yet supported for dim != 2!\n");
-
-
     // Create data structure that maps macro element indices to the 
     // corresponding pointers.
-    std::map<int, MacroElement*> macroIndexMap;
+    map<int, MacroElement*> macroIndexMap;
     for (std::set<MacroElement*>::iterator it = newMacroEl.begin();
 	 it != newMacroEl.end(); ++it)
       macroIndexMap[(*it)->getIndex()] = *it;
 
     std::set<int> macrosProcessed;
-    std::map<const DegreeOfFreedom*, const DegreeOfFreedom*> mapDelDofs;
+    map<const DegreeOfFreedom*, const DegreeOfFreedom*> mapDelDofs;
 
     
     // === Traverse mesh and put all "old" macro element to macrosProcessed  ===
-    // === that stores all macro elements which are really conected to the   ===
+    // === that stores all macro elements which are really connected to the  ===
     // === overall mesh structure.                                           ===
 
     TraverseStack stack;
@@ -86,12 +83,13 @@ namespace AMDiS {
     for (std::set<MacroElement*>::iterator it = newMacroEl.begin(); 
 	 it != newMacroEl.end(); ++it) {
 
+      // === Traverse all vertices of the new element. ===
+
       for (int i = 0; i < mesh->getGeo(VERTEX); i++) {
-	ElementObjectData elObj((*it)->getIndex(), i);
-	DegreeOfFreedom vertex = objects.getVertexLocalMap(elObj);
-	std::vector<ElementObjectData> &vertexEl = objects.getElements(vertex);
+	vector<ElementObjectData> &vertexEl = 
+	  objects.getElementsVertex((*it)->getIndex(), i);
 
-	for (std::vector<ElementObjectData>::iterator elIt = vertexEl.begin();
+	for (vector<ElementObjectData>::iterator elIt = vertexEl.begin();
 	     elIt != vertexEl.end(); ++elIt) {
 	  if (elIt->elIndex == (*it)->getIndex())
 	    continue;
@@ -115,33 +113,32 @@ namespace AMDiS {
 
       for (int i = 0; i < mesh->getGeo(EDGE); i++) {
 	ElementObjectData elObj((*it)->getIndex(), i);
-	DofEdge edge = objects.getEdgeLocalMap(elObj);
-	std::vector<ElementObjectData> &edgeEl = objects.getElements(edge);
 
-	for (std::vector<ElementObjectData>::iterator elIt = edgeEl.begin();
+	vector<ElementObjectData> &edgeEl = 
+	  objects.getElementsEdge((*it)->getIndex(), i);
+
+	for (vector<ElementObjectData>::iterator elIt = edgeEl.begin();
 	     elIt != edgeEl.end(); ++elIt) {
 	  if (elIt->elIndex == (*it)->getIndex())
 	    continue;
 
 	  if (macrosProcessed.count(elIt->elIndex) == 1) {
-	    TEST_EXIT_DBG(macroIndexMap.count(elIt->elIndex) == 1)
-	      ("Should not happen!\n");
-
-	    TEST_EXIT(mesh->getDim() == 2)("In 3D set correct reverse mode!\n");
-
-	    TEST_EXIT(feSpace->getBasisFcts()->getDegree() == 1)
-	      ("Not yet implemented!\n");
+	    TEST_EXIT_DBG(macroIndexMap.count(elIt->elIndex))("Should not happen!\n");
 
 	    Element *el0 = (*it)->getElement();	    
 	    Element *el1 = macroIndexMap[elIt->elIndex]->getElement();
 
-	    BoundaryObject b0(el0, 0, EDGE, i, true);
+	    bool reverseMode = objects.getEdgeReverseMode(elObj, *elIt);
+
+	    BoundaryObject b0(el0, 0, EDGE, i, reverseMode);
 	    BoundaryObject b1(el1, 0, EDGE, elIt->ithObject, false);
 
 	    DofContainer dofs0, dofs1;
 	    
 	    el0->getVertexDofs(feSpace, b0, dofs0);
+	    el0->getNonVertexDofs(feSpace, b0, dofs0);
 	    el1->getVertexDofs(feSpace, b1, dofs1);
+	    el1->getNonVertexDofs(feSpace, b1, dofs1);
 
 #if (DEBUG != 0)
 	    debug::testDofsByCoords(feSpace, dofs0, dofs1);
@@ -155,8 +152,47 @@ namespace AMDiS {
 	}
       }
 
-      TEST_EXIT(mesh->getDim() == 2)("Add face traverse here!\n");
 
+      for (int i = 0; i < mesh->getGeo(FACE); i++) {
+	ElementObjectData elObj((*it)->getIndex(), i);
+
+	vector<ElementObjectData> &faceEl = 
+	  objects.getElementsFace((*it)->getIndex(), i);
+
+	for (vector<ElementObjectData>::iterator elIt = faceEl.begin();
+	     elIt != faceEl.end(); ++elIt) {
+	  if (elIt->elIndex == (*it)->getIndex())
+	    continue;
+
+	  if (macrosProcessed.count(elIt->elIndex) == 1) {
+	    TEST_EXIT_DBG(macroIndexMap.count(elIt->elIndex))("Should not happen!\n");
+
+	    Element *el0 = (*it)->getElement();	    
+	    Element *el1 = macroIndexMap[elIt->elIndex]->getElement();
+
+	    bool reverseMode = objects.getFaceReverseMode(elObj, *elIt);
+
+	    BoundaryObject b0(el0, 0, FACE, i, reverseMode);
+	    BoundaryObject b1(el1, 0, FACE, elIt->ithObject, false);
+
+	    DofContainer dofs0, dofs1;
+	    
+	    el0->getVertexDofs(feSpace, b0, dofs0);
+	    el0->getNonVertexDofs(feSpace, b0, dofs0);
+	    el1->getVertexDofs(feSpace, b1, dofs1);
+	    el1->getNonVertexDofs(feSpace, b1, dofs1);
+
+#if (DEBUG != 0)
+	    debug::testDofsByCoords(feSpace, dofs0, dofs1);
+#endif
+
+ 	    for (unsigned int i = 0; i < dofs0.size(); i++)
+ 	      mapDelDofs[dofs0[i]] = dofs1[i];
+
+	    break;
+	  }
+	}
+      }
 
       macrosProcessed.insert((*it)->getIndex());
     }
@@ -167,9 +203,9 @@ namespace AMDiS {
     bool changed = false;
     do {
       changed = false;
-      for (std::map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator it = mapDelDofs.begin();
+      for (map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator it = mapDelDofs.begin();
 	   it != mapDelDofs.end(); ++it) {
-	std::map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator findIt = mapDelDofs.find(it->second);
+	map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator findIt = mapDelDofs.find(it->second);
 	if (findIt != mapDelDofs.end()) {
 	  TEST_EXIT_DBG(it->first != findIt->second)
 	    ("Cycle %d -> %d and %d -> %d! Should not happen!\n",
@@ -195,7 +231,7 @@ namespace AMDiS {
 
     // === And delete all double DOFs. ===
 
-    for (std::map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator it = mapDelDofs.begin();
+    for (map<const DegreeOfFreedom*, const DegreeOfFreedom*>::iterator it = mapDelDofs.begin();
 	 it != mapDelDofs.end(); ++it)
       mesh->freeDof(const_cast<DegreeOfFreedom*>(it->first), VERTEX);
   }
diff --git a/AMDiS/src/parallel/ParMetisPartitioner.cc b/AMDiS/src/parallel/ParMetisPartitioner.cc
index 0c0181e672b461c1a04e1653ae6f05aae522fd63..f8d4dfd36389fe87520b9be0ad8ca86c03a9e8dd 100644
--- a/AMDiS/src/parallel/ParMetisPartitioner.cc
+++ b/AMDiS/src/parallel/ParMetisPartitioner.cc
@@ -13,6 +13,7 @@
 #include <queue>
 #include "parallel/ParMetisPartitioner.h"
 #include "parallel/MpiHelper.h"
+#include "Serializer.h"
 #include "Mesh.h"
 #include "Traverse.h"
 #include "ElInfo.h"
@@ -221,9 +222,9 @@ namespace AMDiS {
   }
 
 
-  void ParMetisPartitioner::createPartitionData() 
+  void ParMetisPartitioner::createInitialPartitioning() 
   {
-    FUNCNAME("ParMetrisPartitioner::createPartitionData()");
+    FUNCNAME("ParMetrisPartitioner::createInitialPartitioning()");
 
     int mpiRank = mpiComm->Get_rank();
     int mpiSize = mpiComm->Get_size();
@@ -660,4 +661,15 @@ namespace AMDiS {
     return true;
   }
 
+  
+  void ParMetisPartitioner::serialize(std::ostream &out)
+  {
+    SerUtil::serialize(out, elementInRank);
+  }
+
+
+  void ParMetisPartitioner::deserialize(std::istream &in)
+  {
+    SerUtil::deserialize(in, elementInRank);
+  }
 }
diff --git a/AMDiS/src/parallel/ParMetisPartitioner.h b/AMDiS/src/parallel/ParMetisPartitioner.h
index 11c713d4307a2eed9f158c4280299f72395a8547..a96974fd2090710667fdc17487923af86c7806bd 100644
--- a/AMDiS/src/parallel/ParMetisPartitioner.h
+++ b/AMDiS/src/parallel/ParMetisPartitioner.h
@@ -172,15 +172,20 @@ namespace AMDiS {
   class ParMetisPartitioner
   {
   public:
-    ParMetisPartitioner(Mesh *m, MPI::Intracomm *comm)
-      : mesh(m),
-        mpiComm(comm),
+    ParMetisPartitioner(MPI::Intracomm *comm)
+      : mpiComm(comm),
+	mesh(NULL),
         parMetisMesh(NULL),
         mapLocalGlobal(NULL)
     {}
 
     ~ParMetisPartitioner();
 
+    void setMesh(Mesh *m)
+    {
+      mesh = m;
+    }
+
     bool partition(std::map<int, double> &elemWeights,
 		   PartitionMode mode = INITIAL,
 		   float itr = 1000000.0);
@@ -192,7 +197,7 @@ namespace AMDiS {
     void fillCoarsePartitionVec(std::map<int, int> *partitionVec);
 
     /// Creates an initial paritioning of the AMDiS mesh.
-    void createPartitionData();
+    void createInitialPartitioning();
 
     void useLocalGlobalDofMap(std::map<DegreeOfFreedom, DegreeOfFreedom> *m)
     {
@@ -214,20 +219,27 @@ namespace AMDiS {
       return sendElements;
     }
 
+    /// Write partitioner state to disk.
+    void serialize(std::ostream &out);
+
+    /// Read partitioner state from disk.
+    void deserialize(std::istream &in);
+
   protected:
     // Returns true, if the mesh partitioning could be distributed. If this is not the
     // case, i.e., because there are empty partitions, the function returns false.
     bool distributePartitioning(int *part);
 
   protected:
-    Mesh *mesh;
-
     MPI::Intracomm *mpiComm;
 
+    Mesh *mesh;
+
     ParMetisMesh *parMetisMesh;
 
     std::map<DegreeOfFreedom, DegreeOfFreedom> *mapLocalGlobal;
 
+    /// Maps to each macro element index if it is in rank's partition or not.
     std::map<int, bool> elementInRank;
 
     std::map<int, std::vector<int> > recvElements, sendElements;