diff --git a/AMDiS/bin/Makefile.am b/AMDiS/bin/Makefile.am
index b29383cbc9548041a242945d925edd4da70c3628..86011cb752efa4e64344b372999cf8a69bb60d63 100644
--- a/AMDiS/bin/Makefile.am
+++ b/AMDiS/bin/Makefile.am
@@ -29,7 +29,8 @@ endif
 
 if USE_PARALLEL_DOMAIN_AMDIS
   PARALLEL_AMDIS_SOURCES += \
-  $(PARALLEL_DIR)/ParallelDomainProblem.h $(PARALLEL_DIR)/ParallelDomainProblem.cc
+  $(PARALLEL_DIR)/ParallelDomainBase.h $(PARALLEL_DIR)/ParallelDomainBase.cc \
+  $(PARALLEL_DIR)/ParallelDomainScal.h $(PARALLEL_DIR)/ParallelDomainScal.cc
   libamdis_la_CXXFLAGS += -DHAVE_PARALLEL_DOMAIN_AMDIS=1
   AMDIS_INCLUDES += -I/u/witkowski/local/petsc-3.0.0-p4/include -I/u/witkowski/local/petsc-3.0.0-p4/linux-gnu-c-debug/include
 endif
diff --git a/AMDiS/bin/Makefile.in b/AMDiS/bin/Makefile.in
index 32db5b10da3f50798f849fced4876267724a70fb..02f6cbd1b597e8e3c87b02d12785a4152344c0d0 100644
--- a/AMDiS/bin/Makefile.in
+++ b/AMDiS/bin/Makefile.in
@@ -38,7 +38,8 @@ build_triplet = @build@
 host_triplet = @host@
 @USE_PARALLEL_AMDIS_TRUE@am__append_1 = -DHAVE_PARALLEL_AMDIS=1
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__append_2 = \
-@USE_PARALLEL_DOMAIN_AMDIS_TRUE@  $(PARALLEL_DIR)/ParallelDomainProblem.h $(PARALLEL_DIR)/ParallelDomainProblem.cc
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@  $(PARALLEL_DIR)/ParallelDomainBase.h $(PARALLEL_DIR)/ParallelDomainBase.cc \
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@  $(PARALLEL_DIR)/ParallelDomainScal.h $(PARALLEL_DIR)/ParallelDomainScal.cc
 
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__append_3 = -DHAVE_PARALLEL_DOMAIN_AMDIS=1
 @USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__append_4 = -I/u/witkowski/local/petsc-3.0.0-p4/include -I/u/witkowski/local/petsc-3.0.0-p4/linux-gnu-c-debug/include
@@ -71,9 +72,10 @@ am__installdirs = "$(DESTDIR)$(libdir)"
 libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libamdis_la_LIBADD =
-am__libamdis_la_SOURCES_DIST =  \
-	$(PARALLEL_DIR)/ParallelDomainProblem.h \
-	$(PARALLEL_DIR)/ParallelDomainProblem.cc \
+am__libamdis_la_SOURCES_DIST = $(PARALLEL_DIR)/ParallelDomainBase.h \
+	$(PARALLEL_DIR)/ParallelDomainBase.cc \
+	$(PARALLEL_DIR)/ParallelDomainScal.h \
+	$(PARALLEL_DIR)/ParallelDomainScal.cc \
 	$(PARALLEL_DIR)/ConditionalEstimator.h \
 	$(PARALLEL_DIR)/ConditionalEstimator.cc \
 	$(PARALLEL_DIR)/ConditionalMarker.h \
@@ -224,7 +226,8 @@ am__libamdis_la_SOURCES_DIST =  \
 	$(SOURCE_DIR)/parareal/ProblemBase.h \
 	$(SOURCE_DIR)/parareal/AdaptParaReal.h \
 	$(SOURCE_DIR)/parareal/AdaptParaReal.cc
-@USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__objects_1 = libamdis_la-ParallelDomainProblem.lo
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@am__objects_1 = libamdis_la-ParallelDomainBase.lo \
+@USE_PARALLEL_DOMAIN_AMDIS_TRUE@	libamdis_la-ParallelDomainScal.lo
 @USE_PARALLEL_AMDIS_FALSE@am__objects_2 = $(am__objects_1)
 @USE_PARALLEL_AMDIS_TRUE@am__objects_2 =  \
 @USE_PARALLEL_AMDIS_TRUE@	libamdis_la-ConditionalEstimator.lo \
@@ -754,7 +757,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-NonLinUpdater.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Operator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParMetisPartitioner.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDomainProblem.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDomainBase.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelDomainScal.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-ParallelProblem.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parameters.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libamdis_la-Parametric.Plo@am__quote@
@@ -825,12 +829,19 @@ distclean-compile:
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
 
-libamdis_la-ParallelDomainProblem.lo: $(PARALLEL_DIR)/ParallelDomainProblem.cc
-@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelDomainProblem.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParallelDomainProblem.Tpo" -c -o libamdis_la-ParallelDomainProblem.lo `test -f '$(PARALLEL_DIR)/ParallelDomainProblem.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainProblem.cc; \
-@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-ParallelDomainProblem.Tpo" "$(DEPDIR)/libamdis_la-ParallelDomainProblem.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParallelDomainProblem.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$(PARALLEL_DIR)/ParallelDomainProblem.cc' object='libamdis_la-ParallelDomainProblem.lo' libtool=yes @AMDEPBACKSLASH@
+libamdis_la-ParallelDomainBase.lo: $(PARALLEL_DIR)/ParallelDomainBase.cc
+@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelDomainBase.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParallelDomainBase.Tpo" -c -o libamdis_la-ParallelDomainBase.lo `test -f '$(PARALLEL_DIR)/ParallelDomainBase.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainBase.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-ParallelDomainBase.Tpo" "$(DEPDIR)/libamdis_la-ParallelDomainBase.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParallelDomainBase.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$(PARALLEL_DIR)/ParallelDomainBase.cc' object='libamdis_la-ParallelDomainBase.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelDomainProblem.lo `test -f '$(PARALLEL_DIR)/ParallelDomainProblem.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainProblem.cc
+@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelDomainBase.lo `test -f '$(PARALLEL_DIR)/ParallelDomainBase.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainBase.cc
+
+libamdis_la-ParallelDomainScal.lo: $(PARALLEL_DIR)/ParallelDomainScal.cc
+@am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ParallelDomainScal.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ParallelDomainScal.Tpo" -c -o libamdis_la-ParallelDomainScal.lo `test -f '$(PARALLEL_DIR)/ParallelDomainScal.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainScal.cc; \
+@am__fastdepCXX_TRUE@	then mv -f "$(DEPDIR)/libamdis_la-ParallelDomainScal.Tpo" "$(DEPDIR)/libamdis_la-ParallelDomainScal.Plo"; else rm -f "$(DEPDIR)/libamdis_la-ParallelDomainScal.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$(PARALLEL_DIR)/ParallelDomainScal.cc' object='libamdis_la-ParallelDomainScal.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -c -o libamdis_la-ParallelDomainScal.lo `test -f '$(PARALLEL_DIR)/ParallelDomainScal.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ParallelDomainScal.cc
 
 libamdis_la-ConditionalEstimator.lo: $(PARALLEL_DIR)/ConditionalEstimator.cc
 @am__fastdepCXX_TRUE@	if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libamdis_la_CXXFLAGS) $(CXXFLAGS) -MT libamdis_la-ConditionalEstimator.lo -MD -MP -MF "$(DEPDIR)/libamdis_la-ConditionalEstimator.Tpo" -c -o libamdis_la-ConditionalEstimator.lo `test -f '$(PARALLEL_DIR)/ConditionalEstimator.cc' || echo '$(srcdir)/'`$(PARALLEL_DIR)/ConditionalEstimator.cc; \
diff --git a/AMDiS/src/ParallelDomainProblem.cc b/AMDiS/src/ParallelDomainBase.cc
similarity index 84%
rename from AMDiS/src/ParallelDomainProblem.cc
rename to AMDiS/src/ParallelDomainBase.cc
index cdc6259268d6354799c55f830da938a387d13dd1..5ca34813b80896c52185694f447db132a7a4a906 100644
--- a/AMDiS/src/ParallelDomainProblem.cc
+++ b/AMDiS/src/ParallelDomainBase.cc
@@ -1,9 +1,6 @@
-#include <boost/lambda/lambda.hpp>
 #include <algorithm>
 
-#include "ParallelDomainProblem.h"
-#include "ProblemScal.h"
-#include "ProblemInstat.h"
+#include "ParallelDomainBase.h"
 #include "ParMetisPartitioner.h"
 #include "Mesh.h"
 #include "Traverse.h"
@@ -19,8 +16,6 @@
 #include "petscksp.h"
 
 namespace AMDiS {
-  
-  using namespace boost::lambda;
 
   PetscErrorCode myKSPMonitor(KSP ksp, PetscInt iter, PetscReal rnorm, void *)
   {
@@ -30,6 +25,11 @@ namespace AMDiS {
     return 0;
   }
 
+  inline bool cmpDofsByValue(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2)
+  {
+    return (*dof1 < *dof2);
+  }
+
   ParallelDomainBase::ParallelDomainBase(const std::string& name,
 					 ProblemIterationInterface *iIF,
 					 ProblemTimeInterface *tIF,
@@ -88,11 +88,11 @@ namespace AMDiS {
     // Number of all DOFs in the macro mesh.
     int nOverallDOFs = 0;
 
-    createLocalGlobalNumbering(rankDOFs, boundaryDOFs, nRankDOFs, nOverallDOFs);
+    createLocalGlobalNumbering(rankDOFs, nRankDOFs, nOverallDOFs);
 
     // === Create interior boundary information ===
 
-    createInteriorBoundaryInfo(rankDOFs, boundaryDOFs);
+    createInteriorBoundaryInfo(rankDOFs);
 
     // === Remove all macro elements that are not part of the rank partition. ===
 
@@ -369,8 +369,7 @@ namespace AMDiS {
   }
 
 
-  void ParallelDomainBase::createInteriorBoundaryInfo(DofContainer& rankDOFs,
-						      DofToRank& boundaryDOFs)
+  void ParallelDomainBase::createInteriorBoundaryInfo(DofContainer& rankDOFs)
   {
     FUNCNAME("ParallelDomainBase::createInteriorBoundaryInfo()");
 
@@ -532,7 +531,6 @@ namespace AMDiS {
 
 
   void ParallelDomainBase::createLocalGlobalNumbering(DofContainer& rankDOFs,
-						      DofToRank& boundaryDOFs,
 						      int& nRankDOFs, 
 						      int& nOverallDOFs)
   {
@@ -543,8 +541,9 @@ namespace AMDiS {
     // Stores to each DOF pointer the set of ranks the DOF is part of.
     std::map<const DegreeOfFreedom*, std::set<int> > partitionDOFs;
     DofContainer rankAllDofs;
+    DofToRank boundaryDofs;
 
-    createDOFMemberInfo(partitionDOFs, rankDOFs, rankAllDofs, boundaryDOFs);
+    createDOFMemberInfo(partitionDOFs, rankDOFs, rankAllDofs, boundaryDofs);
 
     nRankDOFs = rankDOFs.size();
     nOverallDOFs = partitionDOFs.size();
@@ -604,7 +603,7 @@ namespace AMDiS {
     // another rank.
     std::map<int, int> recvNewDofs;
 
-    for (DofToRank::iterator it = boundaryDOFs.begin(); it != boundaryDOFs.end(); ++it) {
+    for (DofToRank::iterator it = boundaryDofs.begin(); it != boundaryDofs.end(); ++it) {
 
       if (it->second == mpiRank) {
 	// If the boundary dof is a rank dof, it must be send to other ranks.
@@ -685,21 +684,17 @@ namespace AMDiS {
       delete [] sendBuffers[j];
 
 
-    // === Change dof indices for rank partition. ===
-
-    mapLocalGlobalDOFs.clear();
-
     // === Change dof indices at boundary from other ranks. ===
 
     // Within this small data structure we track which dof index was already changed.
     // This is used to avoid the following situation: Assume, there are two dof indices
-    // a and b in boundaryDOFs. Then we have to change index a to b and b to c. When
+    // a and b in boundaryDofs. Then we have to change index a to b and b to c. When
     // the second rule applies, we have to avoid that not the first b, resulted from
     // changing a to b, is set to c, but the second one. Therefore, after the first
     // rule was applied, the dof pointer is set to false in this data structure and 
     // is not allowed to be changed anymore.
     std::map<const DegreeOfFreedom*, bool> dofChanged;
-    for (DofToRank::iterator dofIt = boundaryDOFs.begin(); dofIt != boundaryDOFs.end();
+    for (DofToRank::iterator dofIt = boundaryDofs.begin(); dofIt != boundaryDofs.end();
 	 ++dofIt)
       dofChanged[dofIt->first] = false;
 
@@ -717,8 +712,8 @@ namespace AMDiS {
 
 	// Iterate over all boundary dofs to find the dof, which index we have to change.
 
-	for (DofToRank::iterator dofIt = boundaryDOFs.begin(); 
-	     dofIt != boundaryDOFs.end(); ++dofIt) {
+	for (DofToRank::iterator dofIt = boundaryDofs.begin(); 
+	     dofIt != boundaryDofs.end(); ++dofIt) {
 
 	  if (*(dofIt->first) == oldDof && !dofChanged[dofIt->first]) {
 	    dofChanged[dofIt->first] = true;
@@ -738,22 +733,10 @@ namespace AMDiS {
       delete [] recvBuffers[i];
     }
 
-    
-    // === Create now the local to global index, and vice verse, mappings.     ===
+    // === Create now the local to global index and local to dof index mappings.  ===
 
-    for (DofIndexMap::iterator dofIt = rankDofsNewLocalIndex.begin();
-	 dofIt != rankDofsNewLocalIndex.end(); ++dofIt) {
-      DegreeOfFreedom localDof = dofIt->second;
-      DegreeOfFreedom globalDof = rankDofsNewGlobalIndex[dofIt->first];
-
-      *const_cast<DegreeOfFreedom*>(dofIt->first) = localDof;
-      mapLocalGlobalDOFs[localDof] = globalDof;
-    }
-
-    mapLocalToDofIndex.clear();
-    for (DofIndexMap::iterator dofIt = rankOwnedDofsNewLocalIndex.begin();
-	 dofIt != rankOwnedDofsNewLocalIndex.end(); ++dofIt)
-      mapLocalToDofIndex[dofIt->second] = *(dofIt->first);
+    createLocalMappings(rankDofsNewLocalIndex, rankOwnedDofsNewLocalIndex,
+			rankDofsNewGlobalIndex);
   }
 
 
@@ -789,9 +772,8 @@ namespace AMDiS {
     // === Traverse on interior boundaries and move all not ranked owned DOFs from ===
     // === rankDOFs to boundaryDOFs.                                               ===
 
-    DofToRank newBoundaryDOFs;
-    RankToDofContainer sendNewDofs;
-    RankToDofContainer recvNewDofs;
+    sendDofs.clear();
+    recvDofs.clear();
 
     for (RankToBoundMap::iterator it =  myIntBoundary.boundary.begin();
 	 it != myIntBoundary.boundary.end(); ++it) {
@@ -799,51 +781,38 @@ namespace AMDiS {
       for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin();
 	   boundIt != it->second.end(); ++boundIt) {
 
-	const DegreeOfFreedom *dof1, *dof2;
+	DofContainer dofs;
+	DofContainer &dofsToSend = sendDofs[it->first];
 
 	switch (boundIt->rankObject.ithObjAtBoundary) {
 	case 0:
-	  dof1 = boundIt->rankObject.el->getDOF(1);
-	  dof2 = boundIt->rankObject.el->getDOF(2);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(1));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(2));
 	  break;
 	case 1:
-	  dof1 = boundIt->rankObject.el->getDOF(0);
-	  dof2 = boundIt->rankObject.el->getDOF(2);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(0));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(2));
 	  break;
 	case 2:
-	  dof1 = boundIt->rankObject.el->getDOF(0);
-	  dof2 = boundIt->rankObject.el->getDOF(1);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(0));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(1));
 	  break;
 	default:
 	  ERROR_EXIT("Should never happen!\n");
 	}
 
-	TEST_EXIT_DBG(boundaryDOFs.find(dof1) != boundaryDOFs.end())
-	  ("Should never happen!\n");
-	TEST_EXIT_DBG(boundaryDOFs.find(dof2) != boundaryDOFs.end())
-	  ("Should never happen!\n");
-
-	newBoundaryDOFs[dof1] = boundaryDOFs[dof1];
-	newBoundaryDOFs[dof2] = boundaryDOFs[dof2];
-
-	DofContainer &dofsToSend = sendNewDofs[it->first];
-
-  	if (find(dofsToSend.begin(), dofsToSend.end(), dof1) == dofsToSend.end())
- 	  dofsToSend.push_back(dof1);
-  	if (find(dofsToSend.begin(), dofsToSend.end(), dof2) == dofsToSend.end())
- 	  dofsToSend.push_back(dof2);
-
-	DofContainer boundDOFs;
-	addAllVertexDOFs(boundIt->rankObject.el, 
-			 boundIt->rankObject.ithObjAtBoundary,
-			 boundDOFs);	
-  	addAllEdgeDOFs(boundIt->rankObject.el, 
-  		       boundIt->rankObject.ithObjAtBoundary,
-  		       boundDOFs);
+	for (DofContainer::iterator dofIt = dofs.begin(); dofIt != dofs.end(); ++dofIt) {
+	  if (find(dofsToSend.begin(), dofsToSend.end(), *dofIt) == dofsToSend.end())
+	    dofsToSend.push_back(*dofIt);
+	}
 
-	for (int i = 0; i < static_cast<int>(boundDOFs.size()); i++) {
-	  newBoundaryDOFs[boundDOFs[i]] = mpiRank;
-	  dofsToSend.push_back(boundDOFs[i]);
+	dofs.clear();
+	addAllVertexDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary,
+			 dofs);	
+  	addAllEdgeDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary,
+  		       dofs);
+	for (int i = 0; i < static_cast<int>(dofs.size()); i++) {
+	  dofsToSend.push_back(dofs[i]);
 	}
 	
       }
@@ -855,64 +824,49 @@ namespace AMDiS {
       for (std::vector<AtomicBoundary>::iterator boundIt = it->second.begin();
 	   boundIt != it->second.end(); ++boundIt) {
 
-	const DegreeOfFreedom *dof1, *dof2;
+	DofContainer dofs;
+	DofContainer &dofsToRecv = recvDofs[it->first];
 
 	switch (boundIt->rankObject.ithObjAtBoundary) {
 	case 0:
-	  dof1 = boundIt->rankObject.el->getDOF(1);
-	  dof2 = boundIt->rankObject.el->getDOF(2);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(1));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(2));
 	  break;
 	case 1:
-	  dof1 = boundIt->rankObject.el->getDOF(0);
-	  dof2 = boundIt->rankObject.el->getDOF(2);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(0));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(2));
 	  break;
 	case 2:
-	  dof1 = boundIt->rankObject.el->getDOF(1);
-	  dof2 = boundIt->rankObject.el->getDOF(0);
+	  dofs.push_back(boundIt->rankObject.el->getDOF(1));
+	  dofs.push_back(boundIt->rankObject.el->getDOF(0));
 	  break;
 	default:
 	  ERROR_EXIT("Should never happen!\n");
 	}
 
-	TEST_EXIT_DBG(boundaryDOFs.find(dof1) != boundaryDOFs.end())
-	  ("Should never happen!\n");
-	TEST_EXIT_DBG(boundaryDOFs.find(dof2) != boundaryDOFs.end())
-	  ("Should never happen!\n");
-
-	DofContainer::iterator eraseIt = find(rankDOFs.begin(), rankDOFs.end(), dof1);
-	if (eraseIt != rankDOFs.end())
-	  rankDOFs.erase(eraseIt);
-	eraseIt = find(rankDOFs.begin(), rankDOFs.end(), dof2);
-	if (eraseIt != rankDOFs.end())
-	  rankDOFs.erase(eraseIt);
-
-	newBoundaryDOFs[dof1] = boundaryDOFs[dof1];
-	newBoundaryDOFs[dof2] = boundaryDOFs[dof2];
-
-	DofContainer &dofsToRecv = recvNewDofs[it->first];
-  	if (find(dofsToRecv.begin(), dofsToRecv.end(), dof1) == dofsToRecv.end())
- 	  dofsToRecv.push_back(dof1);
-  	if (find(dofsToRecv.begin(), dofsToRecv.end(), dof2) == dofsToRecv.end())
- 	  dofsToRecv.push_back(dof2);
-
-	DofContainer boundDOFs;	
-	addAllEdgeDOFs(boundIt->rankObject.el, 
- 		       boundIt->rankObject.ithObjAtBoundary,
- 		       boundDOFs);
-	addAllVertexDOFs(boundIt->rankObject.el, 
-			 boundIt->rankObject.ithObjAtBoundary,
-			 boundDOFs);
-
-	for (int i = static_cast<int>(boundDOFs.size()) - 1; i >= 0; i--) {
-	  TEST_EXIT_DBG(find(rankDOFs.begin(), rankDOFs.end(), boundDOFs[i]) != rankDOFs.end())
+	for (DofContainer::iterator dofIt = dofs.begin(); dofIt != dofs.end(); ++dofIt) {
+	  DofContainer::iterator eraseIt = find(rankDOFs.begin(), rankDOFs.end(), *dofIt);
+	  if (eraseIt != rankDOFs.end())
+	    rankDOFs.erase(eraseIt);
+	  if (find(dofsToRecv.begin(), dofsToRecv.end(), *dofIt) == dofsToRecv.end())
+	    dofsToRecv.push_back(*dofIt);
+	}
+
+	dofs.clear();
+	addAllEdgeDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary, 
+		       dofs);
+	addAllVertexDOFs(boundIt->rankObject.el, boundIt->rankObject.ithObjAtBoundary,
+			 dofs);
+
+	for (int i = static_cast<int>(dofs.size()) - 1; i >= 0; i--) {
+	  TEST_EXIT_DBG(find(rankDOFs.begin(), rankDOFs.end(), dofs[i]) != rankDOFs.end())
 	    ("Should never happen!\n");
 
-	  eraseIt = find(rankDOFs.begin(), rankDOFs.end(), boundDOFs[i]);
+	  DofContainer::iterator eraseIt = find(rankDOFs.begin(), rankDOFs.end(), dofs[i]);
 	  if (eraseIt != rankDOFs.end())
 	    rankDOFs.erase(eraseIt);
 
-	  newBoundaryDOFs[boundDOFs[i]] = it->first;
-	  dofsToRecv.push_back(boundDOFs[i]);
+	  dofsToRecv.push_back(dofs[i]);
 	}
       }
     }
@@ -961,15 +915,15 @@ namespace AMDiS {
 
     // === Send new DOF indices. ===
 
-    std::vector<int*> sendBuffers(sendNewDofs.size());
-    std::vector<int*> recvBuffers(recvNewDofs.size());
+    std::vector<int*> sendBuffers(sendDofs.size());
+    std::vector<int*> recvBuffers(recvDofs.size());
 
-    MPI::Request request[sendNewDofs.size() + recvNewDofs.size()];
+    MPI::Request request[sendDofs.size() + recvDofs.size()];
     int requestCounter = 0;
 
     i = 0;
-    for (RankToDofContainer::iterator sendIt = sendNewDofs.begin();
-	 sendIt != sendNewDofs.end(); ++sendIt, i++) {
+    for (RankToDofContainer::iterator sendIt = sendDofs.begin();
+	 sendIt != sendDofs.end(); ++sendIt, i++) {
       int nSendDofs = sendIt->second.size();
       sendBuffers[i] = new int[nSendDofs];
       int c = 0;
@@ -982,8 +936,8 @@ namespace AMDiS {
     }
 
     i = 0;
-    for (RankToDofContainer::iterator recvIt = recvNewDofs.begin();
-	 recvIt != recvNewDofs.end(); ++recvIt, i++) {
+    for (RankToDofContainer::iterator recvIt = recvDofs.begin();
+	 recvIt != recvDofs.end(); ++recvIt, i++) {
       int nRecvDofs = recvIt->second.size();
       recvBuffers[i] = new int[nRecvDofs];
 	
@@ -997,8 +951,8 @@ namespace AMDiS {
       delete [] sendBuffers[j];
 
     i = 0;
-    for (RankToDofContainer::iterator recvIt = recvNewDofs.begin();
-	 recvIt != recvNewDofs.end(); ++recvIt) {      
+    for (RankToDofContainer::iterator recvIt = recvDofs.begin();
+	 recvIt != recvDofs.end(); ++recvIt) {      
       int j = 0;
       for (DofContainer::iterator dofIt = recvIt->second.begin();
 	   dofIt != recvIt->second.end(); ++dofIt) {
@@ -1012,14 +966,16 @@ namespace AMDiS {
     }
 
 
-    // === Update list of dofs that must be communicated for solution exchange. ===
+    // === Create now the local to global index and local to dof index mappings.  ===
 
-    sendDofs = sendNewDofs;
-    recvDofs = recvNewDofs;
-
-
-    // === Create now the local to global index, and vice verse, mappings.     ===
+    createLocalMappings(rankDofsNewLocalIndex, rankOwnedDofsNewLocalIndex,
+			rankDofsNewGlobalIndex);
+  }
 
+  void ParallelDomainBase::createLocalMappings(DofIndexMap &rankDofsNewLocalIndex,
+					       DofIndexMap &rankOwnedDofsNewLocalIndex,
+					       DofIndexMap &rankDofsNewGlobalIndex)
+  {
     mapLocalGlobalDOFs.clear();
     mapLocalToDofIndex.clear();
 
@@ -1032,13 +988,11 @@ namespace AMDiS {
       mapLocalGlobalDOFs[localDof] = globalDof;
     }
 
-    mapLocalToDofIndex.clear();
     for (DofIndexMap::iterator dofIt = rankOwnedDofsNewLocalIndex.begin();
 	 dofIt != rankOwnedDofsNewLocalIndex.end(); ++dofIt)
       mapLocalToDofIndex[dofIt->second] = *(dofIt->first);
   }
 
-
   void ParallelDomainBase::addAllVertexDOFs(Element *el, int ithEdge, 
 					    DofContainer& dofs)
   {
@@ -1081,19 +1035,17 @@ namespace AMDiS {
 
     switch (ithEdge) {
     case 0:
-      if (el->getSecondChild()) {
+      if (el->getSecondChild())
 	addAllEdgeDOFs(el->getSecondChild(), 2, dofs);
-      } else {
+      else
 	addThisEdge = true;
-      }
 
       break;
     case 1:
-      if (el->getFirstChild()) {
+      if (el->getFirstChild())
 	addAllEdgeDOFs(el->getFirstChild(), 2, dofs);
-      } else {
+      else
 	addThisEdge = true;
-      }
 
       break;
     case 2:
@@ -1113,10 +1065,9 @@ namespace AMDiS {
       ElementDofIterator elDofIter(feSpace, true);
       elDofIter.reset(el);
       do {
-	if (elDofIter.getCurrentPos() == 1 &&
-	    elDofIter.getCurrentElementPos() == ithEdge) {
-	  dofs.push_back(elDofIter.getDofPtr());
-	}
+	if (elDofIter.getCurrentPos() == 1 && 
+	    elDofIter.getCurrentElementPos() == ithEdge)
+	  dofs.push_back(elDofIter.getDofPtr());	
       } while(elDofIter.next());      
     }
   }
@@ -1439,72 +1390,4 @@ namespace AMDiS {
     }
   }
 
-
-  ParallelDomainScal::ParallelDomainScal(const std::string& name,
-					 ProblemScal *problem,
-					 ProblemInstatScal *problemInstat)
-    : ParallelDomainBase(name, 
-			 problem, 
-			 problemInstat, 
-			 problem->getFESpace(),
-			 problem->getRefinementManager()),
-      probScal(problem)
-  {
-    info = problem->getInfo();
-  }
-
-  void ParallelDomainScal::initParallelization(AdaptInfo *adaptInfo)
-  {
-    FUNCNAME("ParallelDomainScal::initParallelization()");
-
-    ParallelDomainBase::initParallelization(adaptInfo);
-
-    DOFMatrix* m = probScal->getSystemMatrix();
-
-    TEST_EXIT(m)("No DOF Matrix!\n");
-
-    m->setIsRankDOF(isRankDof);
-  }
-
-  void ParallelDomainScal::solve()
-  {
-    FUNCNAME("ParallelDomainScal::solve()");
-
-#ifdef _OPENMP
-    double wtime = omp_get_wtime();
-#endif
-    clock_t first = clock();
-
-    fillPetscMatrix(probScal->getSystemMatrix(), probScal->getRHS());      
-    solvePetscMatrix(probScal->getSolution());
-
-#ifdef _OPENMP
-    INFO(info, 8)("solution of discrete system needed %.5f seconds system time / %.5f seconds wallclock time\n",
-		   TIME_USED(first, clock()),
-		   omp_get_wtime() - wtime);
-#else
-    INFO(info, 8)("solution of discrete system needed %.5f seconds\n",
-		   TIME_USED(first, clock()));
-#endif
-  }
-
-  Flag ParallelDomainScal::oneIteration(AdaptInfo *adaptInfo, Flag toDo)
-  {
-    FUNCNAME("ParallelDomainScal::oneIteration()");
-
-    Flag flag =  dynamic_cast<StandardProblemIteration*>(iterationIF)->
-      buildAndAdapt(adaptInfo, toDo);
-
-    if (toDo.isSet(SOLVE))
-      solve();
-
-    if (toDo.isSet(SOLVE_RHS))
-      ERROR_EXIT("Not yet implemented!\n");
-
-    if (toDo.isSet(ESTIMATE))
-      iterationIF->getProblem()->estimate(adaptInfo);
-
-    return flag;
-  }
-
 }
diff --git a/AMDiS/src/ParallelDomainProblem.h b/AMDiS/src/ParallelDomainBase.h
similarity index 89%
rename from AMDiS/src/ParallelDomainProblem.h
rename to AMDiS/src/ParallelDomainBase.h
index 796a39fed1d1a60af99a2d7a9ad425989e1ffcce..bccb4efcd2af1d1304432b2cdfa99a2156f48cc1 100644
--- a/AMDiS/src/ParallelDomainProblem.h
+++ b/AMDiS/src/ParallelDomainBase.h
@@ -17,10 +17,11 @@
 // ==                                                                        ==
 // ============================================================================
 
-/** \file ParallelDomain.h */
+/** \file ParallelDomainBase.h */
+
+#ifndef AMDIS_PARALLELDOMAINBASE_H
+#define AMDIS_PARALLELDOMAINBASE_H
 
-#ifndef AMDIS_PARALLELDOMAIN_H
-#define AMDIS_PARALLELDOMAIN_H
 
 #include <map>
 #include <set>
@@ -38,12 +39,14 @@
 #include "petscao.h"
 #include "mpi.h"
 
+#include "Global.h"
+
 namespace AMDiS {
 
   class ParMetisPartitioner;
 
   class ParallelDomainBase : public ProblemIterationInterface,
-                                    public ProblemTimeInterface
+			     public ProblemTimeInterface
   {
   private:
     /// Defines type for a vector of DOFs.
@@ -163,8 +166,7 @@ namespace AMDiS {
      * Determine the interior boundaries, i.e. boundaries between ranks, and store
      * all information about them in \ref interiorBoundary.
      */
-    void createInteriorBoundaryInfo(DofContainer& rankDOFs,
-				    DofToRank& boundaryDOFs);
+    void createInteriorBoundaryInfo(DofContainer& rankDOFs);
 
     /// Removes all macro elements from the mesh that are not part of ranks partition.
     void removeMacroElements();
@@ -175,19 +177,32 @@ namespace AMDiS {
      *
      * \param[out] rankDOFs      Returns all DOFs from the macro mesh, which are owned
      *                           by the rank after partitioning the macro mesh.
-     * \param[out] boundaryDOFs  Returns all DOFs from the macro mesh, which lies at
-     *                           an interior boundary of the rank. This object maps
-     *                           each such DOF to the rank that owns this DOF.
      * \param[out] nRankDOFs     Number of DOFs owned by rank.
      * \param[out] nOverallDOFs  Number of all DOFs in macro mesh.
      */
     void createLocalGlobalNumbering(DofContainer& rankDOFs,
-				    DofToRank& boundaryDOFs,
 				    int& nRankDOFs, 
 				    int& nOverallDOFs);
 
     void updateLocalGlobalNumbering(int& nRankDOFs, int& nOverallDOFs);
 
+    /** \brief
+     * This function create new mappings from local to global indices, 
+     * \ref mapLocalGlobalDOFs, and from local to dof indices, \ref mapLocalToDofIndex.
+     * Furthermore, using the first argument the dof indices in ranks partition are
+     * changed.
+     * 
+     * \param[in] rankDofsNewLocalIndex       Map from dof pointers of all dofs in rank
+     *                                        to new dof indices.
+     * \param[in] rankOwnedDofsNewLocalIndex  Map from dof pointers of dofs owned by
+     *                                        the rank to the new local index.
+     * \param[in] rankDofsNewGlobalIndex      Map from dof pointers of all dofs in rank
+     *                                        to the new global index.
+     */
+    void createLocalMappings(DofIndexMap &rankDofsNewLocalIndex,
+			     DofIndexMap &rankOwnedDofsNewLocalIndex,
+			     DofIndexMap &rankDofsNewGlobalIndex);
+
     void addAllVertexDOFs(Element *el, int ithEdge, DofContainer& dofs);
 
     void addAllEdgeDOFs(Element *el, int ithEdge, DofContainer& dofs);
@@ -320,12 +335,6 @@ namespace AMDiS {
     /// Number of DOFs in the rank mesh.
     int nRankDOFs;
 
-    /** \brief
-     * Set of all interior boundary DOFs in ranks partition. The object maps to
-     * each such DOF to the number of the rank that owns this DOF.
-     */
-    DofToRank boundaryDOFs;
-
     /** \brief 
      * Defines the interior boundaries of the domain that result from partitioning
      * the whole mesh. Contains only the boundaries, which are owned by the rank, i.e.,
@@ -370,30 +379,6 @@ namespace AMDiS {
     int rstart;
   };
 
-  bool cmpDofsByValue(const DegreeOfFreedom* dof1, const DegreeOfFreedom* dof2)
-  {
-    return (*dof1 < *dof2);
-  }
-
-  class ParallelDomainScal : public ParallelDomainBase
-  {
-  public:
-    ParallelDomainScal(const std::string& name,
-			      ProblemScal *problem,
-			      ProblemInstatScal *problemInstat);
-
-    void initParallelization(AdaptInfo *adaptInfo);
-
-    virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION);
-
-  protected:
-    /// Starts the solution of the linear system using Petsc.
-    void solve();
-
-  protected:
-    /// Pointer to the stationary problem.
-    ProblemScal *probScal;
-  };
 }
 
-#endif // AMDIS_PARALLELDOMAIN_H
+#endif // AMDIS_PARALLELDOMAINBASE_H
diff --git a/AMDiS/src/ParallelDomainScal.cc b/AMDiS/src/ParallelDomainScal.cc
new file mode 100644
index 0000000000000000000000000000000000000000..fc675845c2bb53a48bf4426f0ef78e90faeeb304
--- /dev/null
+++ b/AMDiS/src/ParallelDomainScal.cc
@@ -0,0 +1,74 @@
+#include "ParallelDomainScal.h"
+#include "ProblemScal.h"
+#include "ProblemInstat.h"
+
+namespace AMDiS {
+
+  ParallelDomainScal::ParallelDomainScal(const std::string& name,
+					 ProblemScal *problem,
+					 ProblemInstatScal *problemInstat)
+    : ParallelDomainBase(name, 
+			 problem, 
+			 problemInstat, 
+			 problem->getFESpace(),
+			 problem->getRefinementManager()),
+      probScal(problem)
+  {
+    info = problem->getInfo();
+  }
+
+  void ParallelDomainScal::initParallelization(AdaptInfo *adaptInfo)
+  {
+    FUNCNAME("ParallelDomainScal::initParallelization()");
+
+    ParallelDomainBase::initParallelization(adaptInfo);
+
+    DOFMatrix* m = probScal->getSystemMatrix();
+
+    TEST_EXIT(m)("No DOF Matrix!\n");
+
+    m->setIsRankDOF(isRankDof);
+  }
+
+  void ParallelDomainScal::solve()
+  {
+    FUNCNAME("ParallelDomainScal::solve()");
+
+#ifdef _OPENMP
+    double wtime = omp_get_wtime();
+#endif
+    clock_t first = clock();
+
+    fillPetscMatrix(probScal->getSystemMatrix(), probScal->getRHS());      
+    solvePetscMatrix(probScal->getSolution());
+
+#ifdef _OPENMP
+    INFO(info, 8)("solution of discrete system needed %.5f seconds system time / %.5f seconds wallclock time\n",
+		   TIME_USED(first, clock()),
+		   omp_get_wtime() - wtime);
+#else
+    INFO(info, 8)("solution of discrete system needed %.5f seconds\n",
+		   TIME_USED(first, clock()));
+#endif
+  }
+
+  Flag ParallelDomainScal::oneIteration(AdaptInfo *adaptInfo, Flag toDo)
+  {
+    FUNCNAME("ParallelDomainScal::oneIteration()");
+
+    Flag flag =  dynamic_cast<StandardProblemIteration*>(iterationIF)->
+      buildAndAdapt(adaptInfo, toDo);
+
+    if (toDo.isSet(SOLVE))
+      solve();
+
+    if (toDo.isSet(SOLVE_RHS))
+      ERROR_EXIT("Not yet implemented!\n");
+
+    if (toDo.isSet(ESTIMATE))
+      iterationIF->getProblem()->estimate(adaptInfo);
+
+    return flag;
+  }
+
+}
diff --git a/AMDiS/src/ParallelDomainScal.h b/AMDiS/src/ParallelDomainScal.h
new file mode 100644
index 0000000000000000000000000000000000000000..20c15fa2445e0ff8cac9703ac680a0641a995856
--- /dev/null
+++ b/AMDiS/src/ParallelDomainScal.h
@@ -0,0 +1,51 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  crystal growth group                                                  ==
+// ==                                                                        ==
+// ==  Stiftung caesar                                                       ==
+// ==  Ludwig-Erhard-Allee 2                                                 ==
+// ==  53175 Bonn                                                            ==
+// ==  germany                                                               ==
+// ==                                                                        ==
+// ============================================================================
+// ==                                                                        ==
+// ==  http://www.caesar.de/cg/AMDiS                                         ==
+// ==                                                                        ==
+// ============================================================================
+
+/** \file ParallelDomainScal.h */
+
+#ifndef AMDIS_PARALLELDOMAINSCAL_H
+#define AMDIS_PARALLELDOMAINSCAL_H
+
+#include "ParallelDomainBase.h"
+
+namespace AMDiS {
+
+  class ParallelDomainScal : public ParallelDomainBase
+  {
+  public:
+    ParallelDomainScal(const std::string& name,
+		       ProblemScal *problem,
+		       ProblemInstatScal *problemInstat);
+
+    void initParallelization(AdaptInfo *adaptInfo);
+
+    virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION);
+
+  protected:
+    /// Starts the solution of the linear system using Petsc.
+    void solve();
+
+  protected:
+    /// Pointer to the stationary problem.
+    ProblemScal *probScal;
+  };
+
+}
+
+#endif // AMDIS_PARALLELDOMAINSCAL_H
diff --git a/AMDiS/src/ProblemIterationInterface.h b/AMDiS/src/ProblemIterationInterface.h
index d423f9a0921097fc187a382913b1179211452003..eb7a15c4768824fa05f2261e0870195ec30316c9 100644
--- a/AMDiS/src/ProblemIterationInterface.h
+++ b/AMDiS/src/ProblemIterationInterface.h
@@ -49,7 +49,7 @@ namespace AMDiS {
   class ProblemIterationInterface
   {
   public:
-    virtual ~ProblemIterationInterface() {};
+    virtual ~ProblemIterationInterface() {}
 
     /// Called before each adaption loop iteration.
     virtual void beginIteration(AdaptInfo *adaptInfo) {}
@@ -74,7 +74,8 @@ namespace AMDiS {
     virtual ProblemStatBase *getProblem(int number = 0) = 0;
 
     /// Returns the problem with the given name. 
-    virtual ProblemStatBase *getProblem(const std::string& name) { 
+    virtual ProblemStatBase *getProblem(const std::string& name) 
+    { 
       return NULL; 
     }