diff --git a/AMDiS/src/parallel/DofComm.cc b/AMDiS/src/parallel/DofComm.cc
index 7fa60de75ef8817663c46a9b08ffb0e4a62e5902..aa973a91a4f6d94e35a8ee16e9f4063930a2d99d 100644
--- a/AMDiS/src/parallel/DofComm.cc
+++ b/AMDiS/src/parallel/DofComm.cc
@@ -46,7 +46,7 @@ namespace AMDiS {
   {
     FUNCNAME("DofComm::Iterator::setNextFeMap()");
 
-    if (dataIter != dofComm.data[0].end()) {
+    if (dataIter != dofComm.data[traverseLevel].end()) {
       TEST_EXIT_DBG(dataIter->second.size())("Should not happen!\n");
 
       feMapIter = dataIter->second.begin();
diff --git a/AMDiS/src/parallel/DofComm.h b/AMDiS/src/parallel/DofComm.h
index d428ccad6de8d702b9ac140db88388fc0edc4990..dd33200176e5a1df2d81ffe0232eb6e2e82958c3 100644
--- a/AMDiS/src/parallel/DofComm.h
+++ b/AMDiS/src/parallel/DofComm.h
@@ -78,19 +78,26 @@ namespace AMDiS {
 	       const FiniteElemSpace *fe = NULL)
 	: dofComm(dc),
 	  dofCounter(-1),
-	  traverseFeSpace(fe)
+	  traverseFeSpace(fe),
+	  traverseLevel(0)
       {
-	FUNCNAME("DofComm::Iterator::Iterator()");
-
-	dataIter = dofComm.data[0].begin();
+	goFirst();
+      }
 
-	while (setNextFeMap() == false)
-	  ++dataIter;
+      Iterator(DofComm &dc,
+	       int level,
+	       const FiniteElemSpace *fe = NULL)
+	: dofComm(dc),
+	  dofCounter(-1),
+	  traverseFeSpace(fe),
+	  traverseLevel(level)
+      {
+	goFirst();
       }
 
       inline bool end()
       {
-	return (dataIter == dofComm.data[0].end());
+	return (dataIter == dofComm.data[traverseLevel].end());
       }
       
       inline void nextRank()
@@ -181,6 +188,14 @@ namespace AMDiS {
       }
 
     protected:
+      void goFirst()
+      {
+	dataIter = dofComm.data[traverseLevel].begin();
+
+	while (setNextFeMap() == false)
+	  ++dataIter;
+      }
+
       bool setNextFeMap();
 
     protected:
@@ -195,6 +210,8 @@ namespace AMDiS {
       int dofCounter;
 
       const FiniteElemSpace *traverseFeSpace;
+
+      int traverseLevel;
     };
 
 
diff --git a/AMDiS/src/parallel/InteriorBoundary.h b/AMDiS/src/parallel/InteriorBoundary.h
index ff081f56ec68ba935276d177d4ba302642d0667c..dc04842f821d0a27477f5a057b2c73c819a06064 100644
--- a/AMDiS/src/parallel/InteriorBoundary.h
+++ b/AMDiS/src/parallel/InteriorBoundary.h
@@ -216,14 +216,18 @@ namespace AMDiS {
 	  TEST_EXIT_DBG(levelData)("No mesh level data object defined!\n");
 	  TEST_EXIT_DBG(level == 1)("Only 2-level method supported!\n");
 
-	  int rankInLevel = levelData->mapRank(mapIt->first, level - 1, level);
-	  MSG("rankInLevel %d\n", rankInLevel);
-	}
-
- 	while (mapIt->second.size() == 0) {
- 	  ++mapIt;
-	  if (mapIt == bound.boundary.end())
-	    return;
+	  while (levelData->rankInSubdomain(mapIt->first, level) ||
+		 mapIt->second.size() == 0) {
+	    ++mapIt;
+	    if (mapIt == bound.boundary.end())
+	      return;	  
+	  }
+	} else {
+	  while (mapIt->second.size() == 0) {
+	    ++mapIt;
+	    if (mapIt == bound.boundary.end())
+	      return;
+	  }
 	}
       }
 
diff --git a/AMDiS/src/parallel/MeshDistributor.cc b/AMDiS/src/parallel/MeshDistributor.cc
index f90dcfb78dfb1c8a9b43e56d39da5d4d08429c81..f88f386008a0e6632ca9bc596929ac539983a90f 100644
--- a/AMDiS/src/parallel/MeshDistributor.cc
+++ b/AMDiS/src/parallel/MeshDistributor.cc
@@ -665,14 +665,15 @@ namespace AMDiS {
 
 
   void MeshDistributor::getAllBoundaryDofs(const FiniteElemSpace *feSpace,
+					   int level,
 					   DofContainer& dofs)
   {
     FUNCNAME("MeshDistributor::getAllBoundaryDofs()");
 
     DofContainerSet dofSet;
-    for (DofComm::Iterator it(sendDofs, feSpace); !it.end(); it.nextRank())
+    for (DofComm::Iterator it(sendDofs, level, feSpace); !it.end(); it.nextRank())
       dofSet.insert(it.getDofs().begin(), it.getDofs().end());
-    for (DofComm::Iterator it(recvDofs, feSpace); !it.end(); it.nextRank())
+    for (DofComm::Iterator it(recvDofs, level, feSpace); !it.end(); it.nextRank())
       dofSet.insert(it.getDofs().begin(), it.getDofs().end());
 
     dofs.clear();
@@ -1036,23 +1037,6 @@ namespace AMDiS {
   }
 
 
-  void MeshDistributor::createBoundaryDofs(const FiniteElemSpace *feSpace,
-					   std::set<DegreeOfFreedom> &boundaryDofs)
-  {
-    FUNCNAME("MeshDistributor::createBoundaryDofs()");
-
-    boundaryDofs.clear();
-
-    for (DofComm::Iterator it(sendDofs, feSpace); !it.end(); it.nextRank())
-      for (; !it.endDofIter(); it.nextDof())
-	boundaryDofs.insert(it.getDofIndex());
-
-    for (DofComm::Iterator it(recvDofs, feSpace); !it.end(); it.nextRank())
-      for (; !it.endDofIter(); it.nextDof())
-	boundaryDofs.insert(it.getDofIndex());
-  }
-
-
   void MeshDistributor::serialize(ostream &out, DofContainer &data)
   {    
     int vecSize = data.size();
diff --git a/AMDiS/src/parallel/MeshDistributor.h b/AMDiS/src/parallel/MeshDistributor.h
index 721915a49c67e7af26fb67720bff4eaa54f486f0..29be59ba6d154a4cdf3a52a108974e4a4ccc1a90 100644
--- a/AMDiS/src/parallel/MeshDistributor.h
+++ b/AMDiS/src/parallel/MeshDistributor.h
@@ -373,11 +373,6 @@ namespace AMDiS {
       return initialized;
     }
 
-    /// Creates a set of all DOFs that are on interior boundaries of rank's
-    /// domain. Thus, it creates the union of \ref sendDofs and \ref recvDofs.
-    void createBoundaryDofs(const FiniteElemSpace *feSpace,
-			    std::set<DegreeOfFreedom> &boundaryDofs);
-
     // Writes all data of this object to an output stream.
     void serialize(ostream &out);
 
@@ -436,7 +431,8 @@ namespace AMDiS {
       createBoundaryDofFlag = flag;
     }
 
-    BoundaryDofInfo& getBoundaryDofInfo(const FiniteElemSpace *feSpace, int level = 0)
+    BoundaryDofInfo& getBoundaryDofInfo(const FiniteElemSpace *feSpace, 
+					int level = 0)
     {
       FUNCNAME("MeshDistributor::getBoundaryDofInfo()");
 
@@ -447,7 +443,8 @@ namespace AMDiS {
       return boundaryDofInfo[level][feSpace];
     }
 
-    void getAllBoundaryDofs(const FiniteElemSpace *feSpace,
+    void getAllBoundaryDofs(const FiniteElemSpace *feSpace, 
+			    int level,
 			    DofContainer& dofs);
 
     const ElementObjectDatabase& getElementObjectDb() 
diff --git a/AMDiS/src/parallel/MeshLevelData.h b/AMDiS/src/parallel/MeshLevelData.h
index d697e5b58ae777d5b1119e30a733526b2e7d32aa..9151705db4b4e87a47fb3f1e978c16ee5198c056 100644
--- a/AMDiS/src/parallel/MeshLevelData.h
+++ b/AMDiS/src/parallel/MeshLevelData.h
@@ -98,6 +98,13 @@ namespace AMDiS {
       return toRank;			
     }
 
+    bool rankInSubdomain(int rank, int level)
+    {
+      TEST_EXIT_DBG(level < nLevel)("Should not happen!\n");
+
+      return static_cast<bool>(levelRanks[level].count(rank));
+    }
+
   protected:
     int nLevel;
 
diff --git a/AMDiS/src/parallel/ParallelDebug.h b/AMDiS/src/parallel/ParallelDebug.h
index 467277871e43006f900268ed9dcc509f5f586594..28d10f48834834492f71714a7c422f47cbbb8dbe 100644
--- a/AMDiS/src/parallel/ParallelDebug.h
+++ b/AMDiS/src/parallel/ParallelDebug.h
@@ -63,8 +63,8 @@ namespace AMDiS {
 
     /** \brief
      * This function is used for debugging only. It traverses all interior boundaries
-     * and compares the DOF indices on them with the dof indices of the boundarys
-     * neighbours. The function fails, when dof indices on an interior boundary do
+     * and compares the DOF indices on them with the DOF indices of the boundarys
+     * neighbours. The function fails, when DOF indices on an interior boundary do
      * not fit together.
      *
      * \param[in]  pdb           Parallel problem definition used for debugging.
diff --git a/AMDiS/src/parallel/PetscSolverFeti.cc b/AMDiS/src/parallel/PetscSolverFeti.cc
index 4d2058fbf1558c50cd750657697173bced9d10cc..6918f7c5dc64ace0c7d0e791dd660875ca5eb1cf 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.cc
+++ b/AMDiS/src/parallel/PetscSolverFeti.cc
@@ -10,6 +10,7 @@
 // See also license.opensource.txt in the distribution.
 
 
+#include "AMDiS.h"
 #include "parallel/PetscSolverFeti.h"
 #include "parallel/PetscSolverFetiStructs.h"
 #include "parallel/StdMpi.h"
@@ -315,7 +316,6 @@ namespace AMDiS {
     DofIndexSet primals;
     DofContainerSet& vertices = 
       meshDistributor->getBoundaryDofInfo(feSpace, meshLevel).geoDofs[VERTEX];
-    TEST_EXIT_DBG(vertices.size())("No primal vertices on this rank!\n");
     for (DofContainerSet::iterator it = vertices.begin(); 
 	 it != vertices.end(); ++it)
       primals.insert(**it);
@@ -339,7 +339,7 @@ namespace AMDiS {
     // === Create global index of the dual nodes on each rank. ===
 
     DofContainer allBoundaryDofs;
-    meshDistributor->getAllBoundaryDofs(feSpace, allBoundaryDofs);
+    meshDistributor->getAllBoundaryDofs(feSpace, meshLevel, allBoundaryDofs);
 
     for (DofContainer::iterator it = allBoundaryDofs.begin();
 	 it != allBoundaryDofs.end(); ++it)
@@ -357,7 +357,7 @@ namespace AMDiS {
 
     boundaryDofRanks[feSpace].clear();
 
-    for (DofComm::Iterator it(meshDistributor->getSendDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getSendDofs(), meshLevel, feSpace); 
 	 !it.end(); it.nextRank())
       for (; !it.endDofIter(); it.nextDof()) {
 	if (!isPrimal(feSpace, it.getDofIndex())) {
@@ -372,20 +372,23 @@ namespace AMDiS {
 
     StdMpi<vector<std::set<int> > > stdMpi(meshDistributor->getMpiComm());
 
-    for (DofComm::Iterator it(meshDistributor->getSendDofs(), feSpace);
+    for (DofComm::Iterator it(meshDistributor->getSendDofs(), meshLevel, feSpace);
 	 !it.end(); it.nextRank())
       for (; !it.endDofIter(); it.nextDof())
-	if (!isPrimal(feSpace, it.getDofIndex()))
+	if (!isPrimal(feSpace, it.getDofIndex())) {
+	  MSG("SEND TO RANK %d\n", it.getRank());
 	  stdMpi.getSendData(it.getRank()).push_back(boundaryDofRanks[feSpace][it.getDofIndex()]);
+	}
 
     stdMpi.updateSendDataSize();
 
-    for (DofComm::Iterator it(meshDistributor->getRecvDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getRecvDofs(), meshLevel, feSpace); 
 	 !it.end(); it.nextRank()) {
       bool recvFromRank = false;
       for (; !it.endDofIter(); it.nextDof()) {
 	if (!isPrimal(feSpace, it.getDofIndex())) {
 	  recvFromRank = true;
+	  MSG("RECV FROM RANK %d\n", it.getRank());
 	  break;
 	}
       }
@@ -396,7 +399,7 @@ namespace AMDiS {
 
     stdMpi.startCommunication();
 
-    for (DofComm::Iterator it(meshDistributor->getRecvDofs(), feSpace); 
+    for (DofComm::Iterator it(meshDistributor->getRecvDofs(), meshLevel, feSpace); 
 	 !it.end(); it.nextRank()) {
       int i = 0;
       for (; !it.endDofIter(); it.nextDof())
@@ -405,7 +408,6 @@ namespace AMDiS {
 	    stdMpi.getRecvData(it.getRank())[i++];
     }
 
-
     // === Reserve for each dual node, on the rank that owns this node, the ===
     // === appropriate number of Lagrange constraints.                      ===
 
diff --git a/AMDiS/src/parallel/PetscSolverFeti.h b/AMDiS/src/parallel/PetscSolverFeti.h
index 912e94ef7646f145a6226ea21dff260455cde7e8..38de4e8e1414ac22663efe0b327578c13a1ebef6 100644
--- a/AMDiS/src/parallel/PetscSolverFeti.h
+++ b/AMDiS/src/parallel/PetscSolverFeti.h
@@ -190,7 +190,7 @@ namespace AMDiS {
     /// in this map. Is used for the Dirichlet preconditioner only.
     ParallelDofMapping interiorDofMap;
 
-    /// Stores to each dual boundary DOF in each finite elment space the set of
+    /// Stores to each dual boundary DOF in each FE space the set of
     /// ranks in which the DOF is contained in.
     map<const FiniteElemSpace*, DofIndexToPartitions> boundaryDofRanks;