diff --git a/AMDiS/CMakeLists.txt b/AMDiS/CMakeLists.txt
index 3b9b8190a3b362d1d44b7f1da6d040ad3699c4d3..07cce3d2a4fb75d09258065ce4033396fd613a2c 100644
--- a/AMDiS/CMakeLists.txt
+++ b/AMDiS/CMakeLists.txt
@@ -335,6 +335,45 @@ if(ENABLE_BDDCML)
 endif(ENABLE_BDDCML)
 
 
+if(ENABLE_EXTENSIONS)
+  find_path(EXTENSIONS_DIR NAMES ${SOURCE_DIR}/../../extensions/Helpers.h DOC "Path to AMDiS extensions.")
+  if (EXTENSIONS_DIR)
+    if (NOT EXISTS ${EXTENSIONS_DIR}/Helpers.h OR NOT EXISTS ${EXTENSIONS_DIR}/base_problems/BaseProblem.h)
+      message(FATAL_ERROR "Wrong extensions directory! Directory must contain the 'Helpers.h' and the subdirectory 'base_problems'")
+    else()
+  
+    SET(EXTENSIONS_SRC
+	    ${EXTENSIONS_DIR}/Helpers.cc
+	    ${EXTENSIONS_DIR}/BackgroundMesh.cc
+	    ${EXTENSIONS_DIR}/GeometryTools.cc
+	    ${EXTENSIONS_DIR}/POperators.cc
+	    ${EXTENSIONS_DIR}/time/ExtendedRosenbrockStationary.cc
+	    ${EXTENSIONS_DIR}/pugixml/src/pugixml.cpp)
+  list(APPEND COMPILEFLAGS "-DHAVE_EXTENSIONS=1")
+
+
+  if(ENABLE_BASE_PROBLEMS)
+      SET(BASE_PROBLEMS_SRC
+	      ${EXTENSIONS_DIR}/base_problems/CahnHilliard.cc
+# 	      ${EXTENSIONS_DIR}/base_problems/DiffuseDomainFsi.cc
+	      ${EXTENSIONS_DIR}/base_problems/LinearElasticity.cc
+	      ${EXTENSIONS_DIR}/base_problems/LinearElasticityPhase.cc
+# 	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_Chorin.cc
+# 	      ${EXTENSIONS_DIR}/base_problems/NavierStokesPhase_Chorin.cc
+	      ${EXTENSIONS_DIR}/base_problems/NavierStokesPhase_TaylorHood.cc
+	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood.cc
+	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_TaylorHood_RB.cc
+	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_TH_MultiPhase.cc
+	      ${EXTENSIONS_DIR}/base_problems/NavierStokes_TH_MultiPhase_RB.cc
+	      ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_Base.cc
+# 	      ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal.cc
+	      ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_Phase.cc
+	      ${EXTENSIONS_DIR}/base_problems/PhaseFieldCrystal_RB.cc)
+    list(APPEND COMPILEFLAGS "-DHAVE_BASE_PROBLEMS=1")
+    
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
+
 
 SET(COMPOSITE_SOURCE_DIR ${SOURCE_DIR}/compositeFEM)
 SET(COMPOSITE_FEM_SRC ${COMPOSITE_SOURCE_DIR}/CFE_Integration.cc 
@@ -361,6 +400,14 @@ list(APPEND AMDIS_INCLUDE_DIRS ${MUPARSER_SOURCE_DIR}/include)
 list(APPEND AMDIS_INCLUDE_DIRS ${MTL_INCLUDE_DIR})
 #include_directories(${MTL_INCLUDE_DIR})
 list(APPEND AMDIS_INCLUDE_DIRS ${SOURCE_DIR})
+
+if(ENABLE_EXTENSIONS)
+  list(APPEND AMDIS_INCLUDE_DIRS ${EXTENSIONS_DIR})
+  if(ENABLE_BASE_PROBLEMS)
+    list(APPEND AMDIS_INCLUDE_DIRS ${EXTENSIONS_DIR}/base_problems)
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
+
 #include_directories(${SOURCE_DIR})
 include_directories(${AMDIS_INCLUDE_DIRS})
 
@@ -368,9 +415,23 @@ add_library(amdis SHARED ${AMDIS_SRC} ${PARALLEL_DOMAIN_AMDIS_SRC})
 add_library(compositeFEM SHARED ${COMPOSITE_FEM_SRC})
 add_library(reinit SHARED ${REINIT_SRC})
 add_library(muparser SHARED ${MUPARSER_SRC})
+
+if(ENABLE_EXTENSIONS)
+  add_library(extensions SHARED ${EXTENSIONS_SRC})
+  if(ENABLE_BASE_PROBLEMS)
+    add_library(base_problems SHARED ${BASE_PROBLEMS_SRC})
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
+
 #target_link_libraries(compositeFEM amdis)
 #target_link_libraries(reinit amdis)
 list(APPEND AMDIS_LIBS amdis ${Boost_LIBRARIES})
+if(ENABLE_EXTENSIONS)
+  list(APPEND AMDIS_LIBS extensions)
+  if(ENABLE_BASE_PROBLEMS)
+    list(APPEND AMDIS_LIBS base_problems)
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
 
 if(WIN32)
 	list(APPEND COMPILEFLAGS "-D_SCL_SECURE_NO_WARNINGS" "-D_CRT_SECURE_NO_WARNINGS")
@@ -428,6 +489,52 @@ FILE(GLOB HEADERS "${SOURCE_DIR}/io/*.hh")
 INSTALL(FILES ${HEADERS}
 	DESTINATION include/amdis/io)
 
+# ========== (begin) extensions ==========================
+if (ENABLE_EXTENSIONS)
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/*.h")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/)
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/*.hh")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/)
+  
+  list(APPEND deb_add_dirs "include/amdis/extensions")
+
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/time/*.h")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/time/)
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/time/*.hh")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/time/)
+  
+  list(APPEND deb_add_dirs "include/amdis/extensions/time")
+
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/nanoflann/*.hpp")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/nanoflann/)
+
+  list(APPEND deb_add_dirs "include/amdis/extensions/nanoflann")
+
+  FILE(GLOB HEADERS "${EXTENSIONS_DIR}/pugixml/src/*.hpp")
+  INSTALL(FILES ${HEADERS}
+	  DESTINATION include/amdis/extensions/pugixml/)
+
+  list(APPEND deb_add_dirs "include/amdis/extensions/pugixml")
+  
+  if(ENABLE_BASE_PROBLEMS)
+    FILE(GLOB HEADERS "${EXTENSIONS_DIR}/base_problems/*.h")
+    INSTALL(FILES ${HEADERS}
+	    DESTINATION include/amdis/base_problems/)
+    FILE(GLOB HEADERS "${EXTENSIONS_DIR}/base_problems/*.hh")
+    INSTALL(FILES ${HEADERS}
+	    DESTINATION include/amdis/base_problems/)
+
+    list(APPEND deb_add_dirs "include/amdis/base_problems")
+    
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
+# ========== (end) extensions ==========================
+
 FILE(GLOB HEADERS "${REINIT_SOURCE_DIR}/*.h")
 INSTALL(FILES ${HEADERS}
 	DESTINATION include/amdis/reinit)
@@ -447,6 +554,17 @@ list(APPEND deb_add_dirs "lib/amdis")
 install(TARGETS amdis compositeFEM reinit muparser
 	LIBRARY DESTINATION lib/amdis/ )
 
+if (ENABLE_EXTENSIONS)
+  list(APPEND deb_add_dirs "lib/amdis/extensions")
+  install(TARGETS extensions
+	  LIBRARY DESTINATION lib/amdis/extensions/ )
+  if(ENABLE_BASE_PROBLEMS)
+    list(APPEND deb_add_dirs "lib/amdis/extensions/base_problems")
+    install(TARGETS base_problems
+	    LIBRARY DESTINATION lib/amdis/base_problems/ )
+  endif(ENABLE_BASE_PROBLEMS)
+endif(ENABLE_EXTENSIONS)
+
 configure_file(${AMDIS_SOURCE_DIR}/AMDISConfig.cmake.in
 		${AMDIS_BINARY_DIR}/AMDISConfig.cmake
 		@ONLY
diff --git a/AMDiS/src/Functors.h b/AMDiS/src/Functors.h
index d0555a7315f223b238fe9c86316823b6731d123a..73cdb35c132a401e1710a10d0f98313ca5234588 100644
--- a/AMDiS/src/Functors.h
+++ b/AMDiS/src/Functors.h
@@ -100,18 +100,6 @@ struct Diff : public BinaryAbstractFunction<T,T,T>
   T operator()(const T &v1, const T &v2) const { return abs(v1-v2); }
 };
 
-template<typename T>
-struct L1Diff : public BinaryAbstractFunction<T,T,T>
-{
-  T operator()(const T &v1, const T &v2) const { return abs(v1-v2); }
-};
-
-template<typename T>
-struct L2Diff : public BinaryAbstractFunction<T,T,T>
-{
-  T operator()(const T &v1, const T &v2) const { return sqr(v1-v2); }
-};
-
 template<typename T>
 struct Abs : public AbstractFunction<T,T>
 {
@@ -181,6 +169,18 @@ struct Norm2Sqr_comp3 : public TertiaryAbstractFunction<T,T,T,T>
   T operator()(const T &v1, const T &v2, const T &v3) const { return sqr(v1)+sqr(v2)+sqr(v3); }
 };
 
+template<typename T>
+struct L1Diff : public BinaryAbstractFunction<T,T,T>
+{
+  T operator()(const T &v1, const T &v2) const { return abs(v1-v2); }
+};
+
+template<typename TOut, typename T=TOut>
+struct L2Diff : public BinaryAbstractFunction<TOut,T,T>
+{
+  TOut operator()(const T &v1, const T &v2) const { return Norm2<TOut, T>()(v1-v2); }
+};
+
 template<typename T>
 struct Vec1WorldVec : public AbstractFunction<WorldVector<T>,T>
 {
diff --git a/AMDiS/src/io/VtkVectorWriter.h b/AMDiS/src/io/VtkVectorWriter.h
index 081cab83b27c99027ee327838fd8c1bec867af22..128e0fc5878800d7cb060354d49fa02c8974c647 100644
--- a/AMDiS/src/io/VtkVectorWriter.h
+++ b/AMDiS/src/io/VtkVectorWriter.h
@@ -104,8 +104,11 @@ namespace AMDiS {
     inline void writeCoord(boost::iostreams::filtering_ostream &file,
 			   WorldVector<double> coord)
     {
+      file << std::scientific;
+      file.precision(15);
+      
       for (int i = 0; i < Global::getGeo(WORLD); i++)
-	file << " " << std::scientific << coord[i];
+	file << " " << coord[i];
       for (int i = Global::getGeo(WORLD); i < 3; i++)
 	file << " "<<0.0;
 
@@ -115,8 +118,11 @@ namespace AMDiS {
     /// Writes a world coordinate to a given file.
     inline void writeCoord(std::ofstream &file, WorldVector<double> coord)
     {
+      file << std::scientific;
+      file.precision(15);
+    
       for (int i = 0; i < Global::getGeo(WORLD); i++)
-	file << " " << std::scientific << coord[i];
+	file << " " << coord[i];
       for (int i = Global::getGeo(WORLD); i < 3; i++)
 	file << " "<<0.0;
 
diff --git a/AMDiS/src/io/VtkVectorWriter.hh b/AMDiS/src/io/VtkVectorWriter.hh
index 965d9e987934791be1ba621231c0973c7f410e05..cf1818e9535c863eb9e61d0f16a1f7c8d4023cfb 100644
--- a/AMDiS/src/io/VtkVectorWriter.hh
+++ b/AMDiS/src/io/VtkVectorWriter.hh
@@ -251,7 +251,7 @@ namespace AMDiS {
     DOFVector< std::list<WorldVector<double> > >::Iterator coordIt(dofCoords, USED_DOFS);
 
     file << std::scientific;
-    file.precision(5);
+    file.precision(15);
          
     // Write the values for all vertex DOFs.
     for (intPointIt.reset(), valueIt.reset(), coordIt.reset();
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
index af25bdb426d1d243608331d133954e0bcc89e016..24a0a85675347c241fb9dcaf029a201d0c87c54a 100644
--- a/demo/CMakeLists.txt
+++ b/demo/CMakeLists.txt
@@ -124,6 +124,31 @@ if (TOOLS_DIR)
     add_executable("navierStokesDd" ${navierStokesDd})
     target_link_libraries("navierStokesDd" ${BASIS_LIBS})
 
+    set(linearElasticityDd ${TOOLS_DIR}/baseProblems/LinearElasticityPhase.cc
+			${TOOLS_DIR}/diffuseDomain/POperators.cc
+		    /home/spraetor/projects/src/common/GeometryTools.cc
+		    src/linearElasticity.cc)
+    add_executable("linearElasticityDd" ${linearElasticityDd})
+    target_link_libraries("linearElasticityDd" ${BASIS_LIBS})
+
+    set(fsi ${TOOLS_DIR}/baseProblems/LinearElasticityPhase.cc
+	      ${TOOLS_DIR}/baseProblems/NavierStokes_TaylorHood.cc
+	      ${TOOLS_DIR}/baseProblems/NavierStokesPhase_TaylorHood.cc
+	      ${TOOLS_DIR}/misc/Helpers.cc
+	      ${TOOLS_DIR}/diffuseDomain/POperators.cc
+	      /home/spraetor/projects/src/common/GeometryTools.cc
+	      src/fsi/fluidStructureInteraction.cc)
+    add_executable("fsi" ${fsi})
+    target_link_libraries("fsi" ${BASIS_LIBS})
+
+    set(ddFsi ${TOOLS_DIR}/baseProblems/DiffuseDomainFsi.cc
+	      ${TOOLS_DIR}/misc/Helpers.cc
+	      ${TOOLS_DIR}/diffuseDomain/POperators.cc
+	      /home/spraetor/projects/src/common/GeometryTools.cc
+	      src/diffuseDomainFsi.cc)
+    add_executable("ddFsi" ${ddFsi})
+    target_link_libraries("ddFsi" ${BASIS_LIBS})
+    
   endif()
 else()
     message(WARNING "No tools directory specified! Some demos will not be build.")
diff --git a/demo/init/linearElasticity.inc.2d b/demo/init/linearElasticity.inc.2d
index 1b167a12eb3d433d3cf67e7be9647f174dd42393..d8c73da92ed44f40f83fbbb0e2c22ece8da177de 100644
--- a/demo/init/linearElasticity.inc.2d
+++ b/demo/init/linearElasticity.inc.2d
@@ -25,7 +25,7 @@ elasticity->space->solver: umfpack
 elasticity->space->solver->symmetric strategy: 0
 elasticity->space->solver->ell:               3
 elasticity->space->solver->max iteration:     500
-elasticity->space->solver->tolerance:         1.e-8
+elasticity->space->solver->tolerance:         10% 1.e-8
 elasticity->space->solver->info:              1
 elasticity->space->solver->left precon:       ilu
 
diff --git a/demo/init/navierStokesDd.dat.2d b/demo/init/navierStokesDd.dat.2d
index 19df53b0543e88f8d457f4e9739037f2489850e7..6209e51e65dfd64fff960e81b4f2ca535149ea4e 100644
--- a/demo/init/navierStokesDd.dat.2d
+++ b/demo/init/navierStokesDd.dat.2d
@@ -2,7 +2,7 @@ dimension of world: 2
 
 % ====================== VARIABLES ========================
 output_folder: output
-output_postfix: _phase
+output_postfix: _phase2
 mesh_name: mesh
 polynomial-degree: 1
 
diff --git a/demo/init/navierStokes_TaylorHood.inc.2d b/demo/init/navierStokes_TaylorHood.inc.2d
index 94d008eecbffdaeff792609e0171dde26e6354d2..868aff11896b70ce32132f9e3bdbce792d290398 100644
--- a/demo/init/navierStokes_TaylorHood.inc.2d
+++ b/demo/init/navierStokes_TaylorHood.inc.2d
@@ -42,7 +42,7 @@ ns->space->solver->symmetric strategy: 0
 ns->space->solver->ell:               3
 ns->space->solver->max iteration:     500
 ns->space->solver->restart:           10  %  only used for GMRES
-ns->space->solver->tolerance:         1.e-8
+ns->space->solver->tolerance:         10 %1.e-8
 ns->space->solver->info:              1
 ns->space->solver->left precon:       ilu
 
diff --git a/demo/src/navierStokes.h b/demo/src/navierStokes.h
index a97d758b1037ec5d2637fc79ddb52c865195f40a..f01bdd0c867dd419c7a43fbc710026f95cec1e32 100644
--- a/demo/src/navierStokes.h
+++ b/demo/src/navierStokes.h
@@ -4,7 +4,6 @@
 #define NAVIER_STOKES_H
 
 #include "AMDiS.h"
-#include "Views.h"
 #include "GeometryTools.h"
 
 struct InflowBC : AbstractFunction<double, WorldVector<double> >
@@ -19,63 +18,18 @@ protected:
 };
 
 
-class Polygon : public AbstractFunction<double, WorldVector<double> >
+struct MinWrapper : AbstractFunction<double, WorldVector<double> >
 {
-public:
-
-  Polygon(WorldVector<double> x0_, WorldVector<double> x1_, WorldVector<double> x2_, WorldVector<double> x3_)
-  {
-    vertices.push_back(x0_);
-    vertices.push_back(x1_);
-    vertices.push_back(x2_);
-    vertices.push_back(x3_);
-    vertices.push_back(x0_);
-  }
-
-  Polygon(std::vector<WorldVector<double> > xi_) : vertices(xi_) { }
+  MinWrapper(AbstractFunction<double, WorldVector<double> >* dist1_, AbstractFunction<double, WorldVector<double> >* dist2_)
+  : dist1(dist1_), dist2(dist2_) {}
 
   double operator()(const WorldVector<double>& x) const
   {
-    double result = 1.e15;
-    for (size_t i = 0; i < vertices.size()-1; i++)
-      result = std::min(result, meshconv::distance_point_line_2d(x.begin(), vertices[i].begin(), vertices[i+1].begin()));
-    return result * (meshconv::point_in_polygon(x.begin(), vertices) ? -1.0 : 1.0);
-  }
-  
-  void refine(int np)
-  {
-    std::vector<WorldVector<double> > newVertices;
-    
-    for (size_t i = 0; i < vertices.size()-1; i++) {
-      for (size_t j = 0; j < np-1; j++) {
-	double lambda = static_cast<double>(j)/static_cast<double>(np - 1.0);
-	WorldVector<double> p = lambda*vertices[i+1] + (1.0-lambda)*vertices[i];
-	newVertices.push_back(p);
-      }
-    }
-    swap(vertices, newVertices);
+    return std::min((*dist1)(x), (*dist2)(x));
   }
-  
-  void move(const DOFVector<WorldVector<double> >* velocity)
-  {
-    for (size_t i = 0; i < vertices.size()-1; i++) {
-      WorldVector<double> shift = evalAtPoint(*velocity, vertices[i]);
-      vertices[i] += shift;
-    }
-    vertices[vertices.size()-1] = vertices[0];
-  }
-  
-  void move(AbstractFunction<WorldVector<double>, WorldVector<double> >* velocity)
-  {
-    for (size_t i = 0; i < vertices.size()-1; i++) {
-      WorldVector<double> shift = (*velocity)(vertices[i]);
-      vertices[i] += shift;
-    }
-    vertices[vertices.size()-1] = vertices[0];
-  }
-
 private:
-  std::vector<WorldVector<double> > vertices;
+  AbstractFunction<double, WorldVector<double> >* dist1;
+  AbstractFunction<double, WorldVector<double> >* dist2;
 };
 
 #endif
diff --git a/demo/src/navierStokes_diffuseDomain.cc b/demo/src/navierStokes_diffuseDomain.cc
index e80d05bf5c116313e86790f0133963be472c2ef2..b2a226c3dae933b0af629eaaf51bcc33e9d18ed1 100644
--- a/demo/src/navierStokes_diffuseDomain.cc
+++ b/demo/src/navierStokes_diffuseDomain.cc
@@ -13,11 +13,21 @@ using namespace boost::posix_time;
 
 struct BeamDisplacement1d : AbstractFunction<double, double>
 {
-  BeamDisplacement1d(double P_, double L_, double EI_, double* time_, double tau_) : P(P_), L(L_), EI(EI_), time(time_), tau(tau_) {}
+  BeamDisplacement1d(double P_, double L_, double EI_, double* time_ = NULL, double* tau_ = NULL) : P(P_), L(L_), EI(EI_), time(time_), tau(tau_) {}
 
   double operator()(const double& x) const
   {
-    return (*time < DBL_TOL ? 0.0 : (sin(*time)-sin(*time - tau))*P*sqr(x)*(3.0*L-x)/(6.0*EI));
+    return (*time < DBL_TOL ? 0.0 : (sin(*time)-sin(*time - *tau))*P*sqr(x)*(3.0*L-x)/(6.0*EI));
+  }
+
+  void setTimePtr(double* time_)
+  {
+    time = time_;
+  }
+
+  void setTauPtr(double* tau_)
+  {
+    tau = tau_;
   }
   
 private:
@@ -25,12 +35,12 @@ private:
   double L;
   double EI;
   double* time;
-  double tau;
+  double* tau;
 };
 
 struct BeamDisplacement : AbstractFunction<WorldVector<double>, WorldVector<double> >
 {
-  BeamDisplacement(double P, double L, double EI, double* time, double tau, WorldVector<double> fixedPoint_)
+  BeamDisplacement(double P, double L, double EI, WorldVector<double> fixedPoint_, double* time = NULL, double* tau = NULL)
   : fct(new BeamDisplacement1d(P, L, EI, time, tau)), fixedPoint(fixedPoint_) {}
   
   WorldVector<double> operator()(const WorldVector<double>& x) const
@@ -39,9 +49,19 @@ struct BeamDisplacement : AbstractFunction<WorldVector<double>, WorldVector<doub
     displacement[1] = (x[0] >= fixedPoint[0] ? (*fct)(x[0] - fixedPoint[0]) : 0.0);
     return displacement;
   }
-  
+
+  void setTimePtr(double* time_)
+  {
+    fct->setTimePtr(time_);
+  }
+
+  void setTauPtr(double* tau_)
+  {
+    fct->setTauPtr(tau_);
+  }
+
 private:
-  AbstractFunction<double, double>* fct;
+  BeamDisplacement1d* fct;
   WorldVector<double> fixedPoint;
 };
 
@@ -93,14 +113,8 @@ public:
     refinement->refine(10);
     
     phaseField->interpol(new SignedDistFctToPhaseField(getEpsilon(), obstacle, -3.0));
-    
-    double P = 0.1, L = 2.0, EI = 1.0;
-    WorldVector<double> fixedPoint; fixedPoint[0] = 2.5; fixedPoint[1] = 2.0;
-    Parameters::get("obstacle->P",P);
-    Parameters::get("obstacle->L",L);
-    Parameters::get("obstacle->EI",EI);
-    Parameters::get("obstacle->fixed point",fixedPoint);
-    beamDisplacement = new BeamDisplacement(P, L, EI, adaptInfo->getTimePtr(), adaptInfo->getTimestep(), fixedPoint);
+    beamDisplacement->setTimePtr(adaptInfo->getTimePtr());
+    beamDisplacement->setTauPtr(adaptInfo->getTimestepPtr());
     obstacle->refine(10);
   }
   
@@ -112,9 +126,14 @@ protected:
     AbstractFunction<double, WorldVector<double> > *zero = new AMDiS::Const<double, WorldVector<double> >(0.0);
     size_t dow = Global::getGeo(WORLD);
 
-    WorldVector<double> nullVec; nullVec.set(0.0);
-    AbstractFunction<WorldVector<double>, WorldVector<double> > *zeroVec = new AMDiS::Const<WorldVector<double>, WorldVector<double> >(nullVec);
-    super::setBcFct(zeroVec);
+    double P = 0.1, L = 2.0, EI = 1.0;
+    WorldVector<double> fixedPoint; fixedPoint[0] = 2.5; fixedPoint[1] = 2.0;
+    Parameters::get("obstacle->P",P);
+    Parameters::get("obstacle->L",L);
+    Parameters::get("obstacle->EI",EI);
+    Parameters::get("obstacle->fixed point",fixedPoint);
+    beamDisplacement = new BeamDisplacement(P, L, EI, fixedPoint);
+    super::setBcFct(beamDisplacement);
     
     super::fillBoundaryConditions();
     
@@ -139,8 +158,8 @@ protected:
     Parameters::get("ns->Um",Um);
 
     /// at left wall: prescribed velocity
-    getProblem(0)->addDirichletBC(2, 0, 0, new InflowBC(H,Um));
-    getProblem(0)->addDirichletBC(2, 1, 1, zero);
+//     getProblem(0)->addDirichletBC(2, 0, 0, new InflowBC(H,Um));
+//     getProblem(0)->addDirichletBC(2, 1, 1, zero);
   }
   
   void initTimestep(AdaptInfo* adaptInfo)
@@ -156,7 +175,7 @@ protected:
 private:
   
   DOFVector<double>* phaseField;
-  AbstractFunction<WorldVector<double>, WorldVector<double> >* beamDisplacement;
+  BeamDisplacement* beamDisplacement;
   Polygon* obstacle;
   
   SignedDistRefinement* refFunction;
diff --git a/extensions/BackgroundMesh.cc b/extensions/BackgroundMesh.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9e098169eb28c47bce819fb7d5fc880490a4f9b6
--- /dev/null
+++ b/extensions/BackgroundMesh.cc
@@ -0,0 +1,373 @@
+#include "BackgroundMesh.h"
+#include "VectorOperations.h"	// getMin, sort, CompairPair
+#include "Initfile.h"
+
+namespace experimental {
+  
+  std::map<const FiniteElemSpace*, std::pair<int, Box*> > Box::boxMap;
+
+
+  Box::Box(int DOW_, std::vector<int> N_)
+  : DOW(DOW_), N(N_), boxFilled(false)
+  {
+    min_corner.set(-1.0);
+    max_corner.set(1.0);
+    init();
+  }
+
+
+  Box::Box(int DOW_, PointType min_corner_, PointType max_corner_, std::vector<int> N_)
+  : DOW(DOW_),
+    min_corner(min_corner_),
+    max_corner(max_corner_),
+    N(N_), boxFilled(false)
+  {
+    init();
+  }
+
+
+  void Box::fillBox(const FiniteElemSpace* feSpace)
+  {
+    DOFVector<WorldVector<double> > coords(feSpace, "coords");
+    feSpace->getMesh()->dofCompress();
+    feSpace->getMesh()->getDofIndexCoords(feSpace, coords);
+
+    for (DegreeOfFreedom i = 0; i < coords.getUsedSize(); i++) {
+      PointType location(coords[i]);
+      addData(location, std::make_pair(i, location));
+    }
+    boxFilled = true;
+  }
+
+
+  void Box::clearBox()
+  {
+    boxData.clear();
+  }
+
+
+  void Box::clearBoxData()
+  {
+    for (size_t i = 0; i < boxData.size(); i++) {
+      boxData[i].clear();
+    }
+  }
+  
+
+  int Box::getMaxBoxSize()
+  {
+    size_t maxSize = 0;
+    for (size_t i = 0; i < boxData.size(); i++) {
+      maxSize = std::max(maxSize, boxData[i].size());
+    }
+    return maxSize;
+  }
+
+
+  bool Box::inBox(PointType& x)
+  {
+    for (size_t i = 0; i < DOW; i++)
+      if (min_corner[i] > x[i] || max_corner[i] < x[i])
+	return false;
+    return true;
+  }
+
+
+  /**
+   *
+   * Ny=2
+   * ^----------------
+   * | 4 | 5 | 6 | 7 |
+   * ----+---+---+----
+   * | 0 | 1 | 2 | 3 |
+   * -----------------> Nx=4
+   **/
+  int Box::getBox(PointType& x)
+  {
+    std::vector<int> idx(DOW);
+    for (size_t i = 0; i < DOW; i++)
+      idx[i] = static_cast<int>((x[i]-min_corner[i])*N[i]/(max_corner[i]-min_corner[i]));
+//       idx[i] = static_cast<int>(floor((x[i]-min_corner[i])*N[i]/(max_corner[i]-min_corner[i])));
+    return idx2nr(idx);
+  }
+
+
+  bool Box::getNearestData(PointType& x, DataType& data)
+  {
+    if (!inBox(x))
+      return false;
+
+    int nr = getBox(x);
+    unsigned int n = boxData[nr].size();
+    // Box, in der x liegt, ist leer
+    if (n == 0) {
+      std::vector<DataType> datas;
+      getNearestData(x, datas, 1);
+      data = datas[0];
+      return true;
+    }
+    // suche Punkt in aktueller Box, der am nächsten zu x liegt
+    std::vector<double> distances;
+    std::vector<DataType>::iterator dataIter;
+    for (dataIter = boxData[nr].begin(); dataIter != boxData[nr].end(); dataIter++) {
+      distances.push_back(distance2(x, (*dataIter).second, DOW));
+    }
+    double minDist = 1.e15;
+    size_t minIdx = 0;
+    vector_operations::getMin(distances, minDist, minIdx);
+    data = boxData[nr][minIdx];
+    return true;
+  }
+
+
+  bool Box::getNearestData(PointType& x, std::vector<DataType>& data, int nData)
+  {
+    if (!inBox(x))
+      return false;
+    int center_box = getBox(x);
+
+    std::set<int> nrs; nrs.insert(center_box);
+    double boxBoundaryDist = getBoxBoundaryDist(center_box, x);
+    std::vector<double> distances;
+    std::set<int>::iterator nrIter;
+    int level = 0;
+    for (int level = 0; data.size() < nData && nrs.size() > 0; level++) {
+      int oldDataSize = data.size();
+      for (nrIter = nrs.begin(); nrIter != nrs.end(); nrIter++) {
+	data.insert(data.end(), boxData[*nrIter].begin(), boxData[*nrIter].end());
+      }
+      int addon = data.size()-oldDataSize;
+      if (addon > 0) {
+	// 1.) bestimme Abstand zu x
+	int n = distances.size();
+	TEST_EXIT(n + addon == data.size() && oldDataSize == n)("hier ist ein Index falsch: distances.size = %d, addon = %d, data.size = %d, oldDataSize = %d!\n",n,addon,data.size(),oldDataSize);
+	for (size_t i = 0; i < addon; i++) {
+	  distances.push_back(distance2(x, data[n+i].second, DOW));
+	}
+	// 2.) sortiere Paare aus dist und data
+	comparePair<double, DataType, 0> comp;
+	vector_operations::sort(distances, data, comp);
+      }
+
+      // 3.) wenn noch nicht genügend Punkte, dann umgebende Boxen mit durchsuchen
+      if (data.size() < nData
+	|| (level == 0 && distances[distances.size()-1] > boxBoundaryDist))
+      {
+	getSurroundingBoxes(center_box, level+1, nrs);
+      }
+    }
+    data.resize(nData);
+    return true;
+  }
+
+
+  Box* Box::provideBackgroundMesh(const FiniteElemSpace* feSpace)
+  {
+    if (boxMap.find(feSpace) != boxMap.end()) {
+      if (boxMap[feSpace].first != feSpace->getMesh()->getChangeIndex()) {
+	boxMap[feSpace].second->clearBox();
+	boxMap[feSpace].second->init();
+	boxMap[feSpace].second->fillBox(feSpace);
+	boxMap[feSpace].first = feSpace->getMesh()->getChangeIndex();
+	std::cout<<"max #data/box = "<<boxMap[feSpace].second->getMaxBoxSize()<<"\n";
+      }
+    } else {
+      int N_const = 1<<Global::getGeo(WORLD);
+      PointType min_corner_; min_corner_.set(-1.0);
+      PointType max_corner_; max_corner_.set(1.0);
+      Parameters::get("backgroundMesh->N", N_const); // Gesamtanzahl an Boxen
+      Parameters::get("backgroundMesh->min_corner", min_corner_);
+      Parameters::get("backgroundMesh->max_corner", max_corner_);
+
+      // Anzahl an Box je Dimension anhand der Größe des gesamten Box bestimmen
+      double sum_lengths = 0.0;
+      std::vector<double> lengths;
+      for (int i = 0; i < Global::getGeo(WORLD); i++) {
+	lengths.push_back(abs(max_corner_[i]-min_corner_[i]));
+	sum_lengths += lengths[i];
+      }
+      std::vector<int> N_;
+      int N_sum = 0;
+      for (int i = 0; i < Global::getGeo(WORLD); i++) {
+	N_.push_back(static_cast<int>(round(pow(static_cast<double>(N_const),lengths[i]/sum_lengths))));
+	N_sum += N_[i];
+      }
+      
+      Box* box = new Box(Global::getGeo(WORLD), min_corner_, max_corner_, N_);
+      box->fillBox(feSpace);
+
+      boxMap[feSpace] = std::make_pair(feSpace->getMesh()->getChangeIndex(), box);
+      std::cout<<"max #data/box = "<<boxMap[feSpace].second->getMaxBoxSize()<<"\n";
+    }
+
+    return boxMap[feSpace].second;
+  }
+
+
+  void Box::delete_all()
+  {
+    std::map<const FiniteElemSpace*, std::pair<int, Box*> >::iterator boxIter;
+    for (boxIter = boxMap.begin(); boxIter != boxMap.end(); boxIter++) {
+      (*boxIter).second.second->clearBox();
+      delete (*boxIter).second.second;
+    }
+    boxMap.clear();
+  }
+
+
+  void Box::init()
+  {
+    int maxNr = 1.0;
+    for (size_t i = 0; i < DOW; i++)
+      maxNr *= N[i];
+    boxData.resize(maxNr);
+
+    std::cout<<"\n background mesh\n";
+    std::cout<<"=================\n";
+    std::cout<<"min_corner: "<<min_corner<<"\n";
+    std::cout<<"max_corner: "<<max_corner<<"\n";
+    std::cout<<"N: "<<N<<"\n\n";
+
+    PointType tolerance; tolerance.set(2.0*DBL_TOL);
+    min_corner -= tolerance;
+    max_corner += tolerance;
+  }
+
+
+/// protected methods
+///_____________________________________________________________________________________________
+
+
+  inline int Box::idx2nr(std::vector<int>& idx)
+  {
+    int nr = idx.back();
+    std::vector<int>::reverse_iterator iIter, nIter;
+    for (iIter = idx.rbegin()+1, nIter = N.rbegin()+1; iIter < idx.rend(); iIter++,nIter++) {
+      nr = *iIter + nr*(*nIter);
+    }
+    return nr;
+  }
+
+
+  inline void Box::nr2idx(int nr, std::vector<int>& idx)
+  {
+    idx.resize(DOW);
+    switch (DOW) {
+      case 1:
+	idx[0] = nr % N[0];
+	break;
+      case 2:
+	idx[1] = nr / N[0];
+	idx[0] = nr % N[0];
+	break;
+      case 3:
+	idx[2] = nr / (N[1]*N[0]);
+	nr = nr % (N[1]*N[0]);
+	idx[1] = nr / N[0];
+	idx[0] = nr % N[0];
+	break;
+      default:
+	throw(std::runtime_error("DOW="+boost::lexical_cast<std::string>(DOW)+", nur die Version für DOW=1 verwendet!"));
+	break;
+    }
+  }
+
+
+  void Box::getSurroundingBoxes(int center, int radius, std::set<int> &nrs)
+  {
+    std::set<int> newNrs;
+    std::vector<int> idx, newIdx;
+    nr2idx(center, idx); // --> idx
+    newIdx.resize(idx.size());
+    double incr = m_pi/3.0/radius;
+    switch(DOW) {
+      case 1:
+	if (idx[0]-radius >= 0) { newIdx[0] = idx[0]-radius; newNrs.insert(idx2nr(newIdx)); }
+	if (idx[0]+radius < N[0]) { newIdx[0] = idx[0]+radius; newNrs.insert(idx2nr(newIdx)); }
+	break;
+      case 2:
+	for (double phi = 0.0; phi < 2.0*m_pi; phi += incr) {
+	  newIdx[0] = idx[0] + static_cast<int>(round(radius*cos(phi)));
+	  newIdx[1] = idx[1] + static_cast<int>(round(radius*sin(phi)));
+	  if (newIdx[0] >= 0 && newIdx[0] < N[0]
+	   && newIdx[1] >= 0 && newIdx[1] < N[1])
+	    newNrs.insert(idx2nr(newIdx));
+	}
+	break;
+      case 3:
+	for (double phi = -m_pi; phi < m_pi; phi += incr) {
+	for (double theta = 0.0; theta < m_pi; theta += incr) {
+	  newIdx[0] = idx[0] + static_cast<int>(round(radius*sin(theta)*cos(phi)));
+	  newIdx[1] = idx[1] + static_cast<int>(round(radius*sin(theta)*sin(phi)));
+	  newIdx[2] = idx[2] + static_cast<int>(round(radius*cos(theta)));
+	  if (newIdx[0] >= 0 && newIdx[0] < N[0]
+	   && newIdx[1] >= 0 && newIdx[1] < N[1]
+	   && newIdx[2] >= 0 && newIdx[2] < N[2])
+	    newNrs.insert(idx2nr(newIdx));
+	}
+	}
+	break;
+      default:
+	ERROR("unknown dimension!\n");
+    }
+    
+    std::set<int>::iterator nrsIter;
+    for (nrsIter = nrs.begin(); nrsIter != nrs.end(); nrsIter++)
+      newNrs.erase(*nrsIter);
+    swap(nrs, newNrs);
+  }
+  
+
+  void Box::getSurroundingBoxes(int nr, std::set<int> &surrounding_nrs)
+  {
+    std::vector<int> idx;
+    nr2idx(nr, idx); // --> idx
+
+    for (size_t i = 0; i < DOW; i++) {
+      std::vector<int> idx_i = idx;
+      idx_i[i] = std::min(N[i]-1, idx_i[i]+1);
+      surrounding_nrs.insert(idx2nr(idx_i));
+      idx_i[i] = std::max(0, idx_i[i]-2);
+      surrounding_nrs.insert(idx2nr(idx_i));
+    }
+    surrounding_nrs.erase(nr);
+  }
+
+
+  void Box::getSurroundingBoxes(std::set<int> &nrs, std::set<int> &surrounding_nrs)
+  {
+    std::set<int>::iterator nrsIter;
+    for (nrsIter = nrs.begin(); nrsIter != nrs.end(); nrsIter++)
+      getSurroundingBoxes(*nrsIter, surrounding_nrs);
+
+    for (nrsIter = nrs.begin(); nrsIter != nrs.end(); nrsIter++)
+      surrounding_nrs.erase(*nrsIter);
+  }
+
+
+  /// berechne die minimale Entfernung der Ränder der Box zu x
+  double Box::getBoxBoundaryDist(int nr, PointType& x)
+  {
+    std::vector<int> idx;
+    nr2idx(nr, idx);
+    PointType min_c, max_c;
+    for (size_t i = 0; i < DOW; i++) {
+      min_c[i] = min_corner[i] + (max_corner[i]-min_corner[i])*idx[i]/N[i];
+      max_c[i] = min_corner[i] + (max_corner[i]-min_corner[i])*(idx[i]+1)/N[i];
+    }
+    double dist = 1.e15;
+    for (int i = 0; i < DOW; i++)
+      dist = std::min(dist, std::min(abs(max_c[i]-x[i]), abs(min_c[i]-x[i])));
+    return dist;
+  }
+
+
+  void Box::addData(PointType x, DataType data)
+  {
+    int nr = getBox(x);
+    if (nr < 0 || nr >= boxData.size())
+      throw(std::runtime_error("box-nr out of range: nr = "+boost::lexical_cast<std::string>(nr)+", x = "+boost::lexical_cast<std::string>(x)+", boxSize = "+boost::lexical_cast<std::string>(boxData.size())));
+    boxData[nr].push_back(data);
+  }
+  
+}
\ No newline at end of file
diff --git a/extensions/BackgroundMesh.h b/extensions/BackgroundMesh.h
new file mode 100644
index 0000000000000000000000000000000000000000..05d0e7b427958dcd00665f7e33554670dc7d1782
--- /dev/null
+++ b/extensions/BackgroundMesh.h
@@ -0,0 +1,117 @@
+/** \file BackgroundMesh.h */
+
+#ifndef BACKGROUND_MESH_H
+#define BACKGROUND_MESH_H
+
+// AMDiS-includes
+#include "DOFVector.h"		// DOFVector
+#include "FiniteElemSpace.h"	// FiniteElemSpace
+#include "FixVec.h"		// WorldVector
+#include "Global.h"		// DegreeOfFreedom
+
+#ifndef USE_EXPERIMENTAL
+#define USE_EXPERIMENTAL
+#endif
+
+namespace experimental {
+
+  using namespace AMDiS;
+  
+  typedef WorldVector<double> PointType;
+  
+  inline double distance(PointType &x, PointType &y, unsigned int n)
+  {
+    double d = 0.0;
+    for (unsigned int i = 0; i < n; i++)
+      d += sqr(x[i]-y[i]);
+    return sqrt(d);
+  }
+  
+  inline double distance2(PointType &x, PointType &y, unsigned int n)
+  {
+    double d = 0.0;
+    for (unsigned int i = 0; i < n; i++)
+      d += sqr(x[i]-y[i]);
+    return d;
+  }
+  
+  typedef std::pair<DegreeOfFreedom, PointType> DataType;
+
+  struct Box {
+
+    Box(int DOW_, std::vector<int> N_);
+    Box(int DOW_, PointType min_corner_, PointType max_corner_, std::vector<int> N_);
+    void init();
+
+    void fillBox(const FiniteElemSpace* feSpace);
+    void clearBox();
+    void clearBoxData();
+
+    int getMaxBoxSize();
+
+    bool inBox(PointType& x);
+    int getBox(PointType& x);
+
+    bool getNearestData(PointType& x, DataType& data);
+    bool getNearestData(PointType& x, std::vector<DataType>& data, int nData);
+
+    /**
+    * strategies:
+    * 0 .. get nearest point to x and eval DOFVector at this DOF-index
+    * 1 .. get n nearest points, calc weighted sum of data at these points
+    * 2 .. get n nearest points, calc regression plane and eval at x
+    * 3 .. get n nearest points, calc weighted regression plane and eval at x
+    **/
+    template<typename T>
+    T evalAtPoint(DOFVector<T>& vec, PointType& x, int strategy = 0, int nrOfPoints = -1);
+
+    static Box* provideBackgroundMesh(const FiniteElemSpace* feSpace);
+    static void delete_all();
+
+    void addData(PointType x, DataType data);
+
+  protected:
+
+    template<typename T>
+    T evalAtPoint_simple(DOFVector<T>& vec, PointType& x);
+
+    template<typename T>
+    T evalAtPoint_weighted_sum(DOFVector<T>& vec, PointType& x, int nrOfPoints);
+
+    template<typename T>
+    T evalAtPoint_regression(DOFVector<T>& vec, PointType& x, int nrOfPoints);
+
+    template<typename T>
+    T evalAtPoint_weighted_regression(DOFVector<T>& vec, PointType& x, int nrOfPoints);
+
+    inline int idx2nr(std::vector<int>& idx);
+
+    inline void nr2idx(int nr, std::vector<int>& idx);
+
+
+    void getSurroundingBoxes(int nr, std::set<int> &surrounding_nrs);
+    void getSurroundingBoxes(int center, int radius, std::set<int> &nrs);
+    void getSurroundingBoxes(std::set<int> &nrs, std::set<int> &surrounding_nrs);
+
+    /// berechne die minimale Entfernung der Ränder der Box zu x
+    double getBoxBoundaryDist(int nr, PointType& x);
+
+    static std::map<const FiniteElemSpace*, std::pair<int, Box*> > boxMap;
+
+  private:
+
+    int DOW;
+    std::vector<int> N;
+    bool boxFilled;
+
+    PointType min_corner;
+    PointType max_corner;
+
+    std::vector<std::vector<DataType> > boxData;
+  };
+
+} // end namespace experimental
+
+#include "BackgroundMesh.hh"
+
+#endif // BACKGROUND_MESH_H
diff --git a/extensions/BackgroundMesh.hh b/extensions/BackgroundMesh.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d77c6574d160147b2ae97a56bc68ad6c4f68089a
--- /dev/null
+++ b/extensions/BackgroundMesh.hh
@@ -0,0 +1,133 @@
+#include "Tools.h"	// tools::Regression
+
+namespace experimental {
+
+  /**
+   * strategies:
+   * 0 .. get nearest point to x and eval DOFVector at this DOF-index
+   * 1 .. get n nearest points, calc weighted sum of data at these points
+   * 2 .. get n nearest points, calc regression plane and eval at x
+   * 3 .. get n nearest points, calc weighted regression plane and eval at x
+   **/
+  template<typename T>
+  T Box::evalAtPoint(DOFVector<T>& vec, PointType& x, int strategy, int nrOfPoints)
+  {
+    T value;
+    switch (strategy) {
+      case 0:
+	value = evalAtPoint_simple(vec, x);
+	break;
+      case 1:
+	value = evalAtPoint_weighted_sum(vec, x, nrOfPoints);
+	break;
+      case 2:
+	value = evalAtPoint_regression(vec, x, nrOfPoints);
+	break;
+      case 3:
+	value = evalAtPoint_weighted_regression(vec, x, nrOfPoints);
+	break;
+      default:
+	ERROR("ERROR: unknown strategy [%d]!\n",strategy);
+	break;
+    }
+    return value;
+  }
+
+  
+  template<typename T>
+  T Box::evalAtPoint_simple(DOFVector<T>& vec, PointType& x)
+  {
+    DataType dof;
+    T value; nullify(value);
+    if (getNearestData(x, dof))
+      value = vec[dof.first];
+    return value;
+  }
+
+  
+  template<typename T>
+  T Box::evalAtPoint_weighted_sum(DOFVector<T>& vec, PointType& x, int nrOfPoints)
+  {
+    T value; nullify(value);
+
+    std::vector<DataType> dofs;
+    int nPoints = (nrOfPoints > 0 ? nrOfPoints : vec.getFeSpace()->getBasisFcts()->getNumber()+1);
+
+    bool inside = getNearestData(x, dofs, nPoints);
+    if (!inside)
+      return value;
+
+    // gewichtete Summe der einzelnen Funktionswerte in der Nähe von x
+    std::vector<double> weights;
+    for (size_t i = 0; i < dofs.size(); i++) {
+      double dist = distance(x, dofs[i].second, DOW);
+      weights.push_back(1.0/std::max(1.e-8, dist));
+    }
+
+    double weight = 0.0;
+    for (size_t i = 0; i < dofs.size(); i++) {
+      value += vec[dofs[i].first] * weights[i];
+      weight += weights[i];
+    }
+    value *= 1.0/weight;
+
+    return value;
+  }
+
+
+  template<typename T>
+  T Box::evalAtPoint_regression(DOFVector<T>& vec, PointType& x, int nrOfPoints)
+  {
+    T value; nullify(value);
+
+    std::vector<DataType> dofs;
+    int nPoints = (nrOfPoints > 0 ? nrOfPoints : vec.getFeSpace()->getBasisFcts()->getNumber()+1);
+
+    bool inside = getNearestData(x, dofs, nPoints);
+    if (!inside)
+      return value;
+
+    std::vector<WorldVector<double> > points;
+    std::vector<double> values;
+    for (size_t i = 0; i < dofs.size(); i++) {
+      points.push_back(dofs[i].second);
+      values.push_back(vec[dofs[i].first]);
+    }
+
+    tools::Regression reg(DOW);
+    reg.apply(points, values);
+    value = reg.value(x);
+    return value;
+  }
+
+
+  template<typename T>
+  T Box::evalAtPoint_weighted_regression(DOFVector<T>& vec, PointType& x, int nrOfPoints)
+  {
+    T value; nullify(value);
+
+    std::vector<DataType> dofs;
+    int nPoints = (nrOfPoints > 0 ? nrOfPoints : vec.getFeSpace()->getBasisFcts()->getNumber()+1);
+
+    bool inside = getNearestData(x, dofs, nPoints);
+    if (!inside)
+      return value;
+
+    std::vector<WorldVector<double> > points;
+    std::vector<double> values,weights;
+    for (size_t i = 0; i < dofs.size(); i++) {
+      points.push_back(dofs[i].second);
+      values.push_back(vec[dofs[i].first]);
+
+      double dist = distance(x, dofs[i].second, DOW);
+      weights.push_back(1.0/std::max(1.e-8, dist));
+    }
+
+    tools::Regression reg(DOW);
+    reg.apply(points, values, weights);
+    value = reg.value(x);
+
+    return value;
+  }
+
+} // end namespace experimental
diff --git a/extensions/BackgroundMesh2.h b/extensions/BackgroundMesh2.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6b0b8f35e310479454219721cb21ae022bbb47f
--- /dev/null
+++ b/extensions/BackgroundMesh2.h
@@ -0,0 +1,345 @@
+/** \file BackgroundMesh2.h */
+
+#ifndef BACKGROUND_MESH2_H
+#define BACKGROUND_MESH2_H
+
+#include "AMDiS.h"
+#include "Tools.h"
+
+#define USE_EXPERIMENTAL
+
+namespace experimental {
+
+typedef WorldVector<double> PointType_;
+typedef boost::tuple<const MacroElement*, int, unsigned long> ElInfoDataType; // data to recover elInfo
+typedef std::pair<ElInfoDataType, PointType_> DataType_;
+
+template<typename PointType, typename DataType>
+struct ElementBox {
+
+  ElementBox(int DOW_, std::vector<int> N_)
+  : DOW(DOW_), N(N_), boxFilled(false)
+  {
+    min_corner.set(-1.0);
+    max_corner.set(1.0);
+    init();
+  }
+  
+  ElementBox(int DOW_, PointType min_corner_, PointType max_corner_, std::vector<int> N_)
+  : DOW(DOW_), 
+    min_corner(min_corner_),
+    max_corner(max_corner_),
+    N(N_), boxFilled(false)
+  {
+    init();
+  }
+    
+
+  void fillBox(const FiniteElemSpace* feSpace);  
+  
+  void clearBox()
+  {
+    boxData.clear();
+  }
+  
+  
+  int getMaxBoxSize()
+  {
+    size_t maxSize = 0;
+    for (size_t i = 0; i < boxData.size(); i++) {
+      maxSize = std::max(maxSize, boxData[i].size());
+    }
+    return maxSize;
+  }
+  
+  
+  bool inBox(PointType& x)
+  {
+    for (size_t i = 0; i < DOW; i++)
+      if (min_corner[i] > x[i] || max_corner[i] < x[i])
+	return false;
+    return true;
+  }
+  
+  /**
+   * 
+   * Ny=2
+   * ^----------------
+   * | 4 | 5 | 6 | 7 |
+   * ----+---+---+----
+   * | 0 | 1 | 2 | 3 |
+   * -----------------> Nx=4
+   **/
+  
+  int getBox(PointType& x)
+  {
+    std::vector<int> idx(DOW);
+    for (size_t i = 0; i < DOW; i++)
+      idx[i] = static_cast<int>(floor((x[i]-min_corner[i])*N[i]/(max_corner[i]-min_corner[i])));
+    return idx2nr(idx);
+  }
+  
+  
+  bool getNearestElInfo(PointType &x, ElInfo*& minElInfo);
+  
+  
+  bool getNearestData(PointType& x, DataType& data)
+  {
+    if (!inBox(x))
+      return false;
+    
+    int nr = getBox(x);
+    if (boxData[nr].size() == 0) {
+      std::vector<DataType> datas;
+      getNearestData(x, datas, 1);
+      data = datas[0];
+      return true;
+    }
+    std::vector<double> distances;
+    typename std::vector<DataType>::iterator dataIter;
+    for (dataIter = boxData[nr].begin(); dataIter != boxData[nr].end(); dataIter++) {
+      distances.push_back(norm(x - (*dataIter).second));
+    }
+    double minDist = 1.e15;
+    size_t minIdx = 0;
+    vector_operations::getMin(distances, minDist, minIdx);
+    data = boxData[nr][minIdx];
+    return true;
+  }
+  
+  bool getNearestData(PointType& x, std::vector<DataType>& data, int nData)
+  {
+    if (!inBox(x))
+      return false;
+    
+    std::set<int> nrs; nrs.insert(getBox(x));
+    double boxBoundaryDist = getBoxBoundaryDist(*(nrs.begin()), x);
+    std::vector<int> visited;
+    std::vector<int>::iterator visitedIter;
+    std::set<int>::iterator nrIter;
+    int level = 0;
+    for (int level = 0; data.size() < nData && nrs.size() > 0; level++) {
+      for (nrIter = nrs.begin(); nrIter != nrs.end(); nrIter++) {
+	data.insert(data.end(), boxData[*nrIter].begin(), boxData[*nrIter].end());
+      }
+      visited.insert(visited.end(), nrs.begin(), nrs.end());
+      
+      std::vector<double> distances;
+      if (data.size() > 0) {
+	// 1.) bestimme Abstand zu x 
+	for (size_t i = 0; i < data.size(); i++) {
+	  distances.push_back(norm(x - data[i].second));
+	}
+	// 2.) sortiere Paare aus dist und data
+	compare0<double, DataType> comp;
+	vector_operations::sort(distances, data, comp);
+      }
+      
+      // 3.) wenn noch nicht genügend Punkte, dann umgebende Boxen mit durchsuchen
+      if (data.size() < nData 
+	|| (level == 0 && distances[std::min(nData,static_cast<int>(distances.size()))-1] > boxBoundaryDist))
+      {
+	std::set<int> surrounding_nrs;
+	getSurroundingBoxes(nrs, surrounding_nrs);
+	swap (nrs, surrounding_nrs);
+      }
+      
+      for (visitedIter = visited.begin(); visitedIter != visited.end(); visitedIter++)
+	nrs.erase(*visitedIter);
+    }
+    data.resize(nData);
+    return true;
+  }
+
+  /**
+   * strategies:
+   * 0 .. get nearest point to x and eval DOFVector at this DOF-index
+   * 1 .. get n nearest points, calc weighted sum of data at these points
+   * 2 .. get n nearest points, calc regression plane and eval at x
+   * 3 .. get n nearest points, calc weighted regression plane and eval at x
+   **/
+  template<typename T>
+  T evalAtPoint(DOFVector<T>& vec, PointType& x, int strategy = 0, int nrOfPoints = -1)
+  {
+    T value;
+    switch (strategy) {
+      case 0:
+	value = evalAtPoint_simple(vec, x);
+	break;   
+      default:
+	ERROR("ERROR: unknown strategy [%d]!\n",strategy);
+	break;
+    }
+    return value;
+  }
+
+  
+  static ElementBox<PointType, DataType>* provideBackgroundMesh(const FiniteElemSpace* feSpace)
+  {
+    if (boxMap.find(feSpace) != boxMap.end()) {
+      if (boxMap[feSpace].first != feSpace->getMesh()->getChangeIndex()) {
+	boxMap[feSpace].second->clearBox();
+	boxMap[feSpace].second->init();
+	boxMap[feSpace].second->fillBox(feSpace);
+	boxMap[feSpace].first = feSpace->getMesh()->getChangeIndex();
+	std::cout<<"max box size = "<<boxMap[feSpace].second->getMaxBoxSize()<<"\n";   
+      }
+    } else {
+      int N_const = 2;
+      PointType min_corner_; min_corner_.set(-1.0);
+      PointType max_corner_; max_corner_.set(1.0);
+      Parameters::get("backgroundMesh->N", N_const);
+      Parameters::get("backgroundMesh->min_corner", min_corner_);
+      Parameters::get("backgroundMesh->max_corner", max_corner_);
+      std::vector<int> N_(Global::getGeo(WORLD), N_const);
+      ElementBox<PointType, DataType>* box = new ElementBox<PointType, DataType>(Global::getGeo(WORLD), min_corner_, max_corner_, N_);
+      box->fillBox(feSpace);
+      
+      boxMap[feSpace] = std::make_pair(feSpace->getMesh()->getChangeIndex(), box);   
+      std::cout<<"max box size = "<<boxMap[feSpace].second->getMaxBoxSize()<<"\n";   
+    }
+    
+    return boxMap[feSpace].second;
+  }
+  
+  static void delete_all()
+  {
+    typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> >::iterator boxIter;
+    for (boxIter = boxMap.begin(); boxIter != boxMap.end(); boxIter++) {
+      (*boxIter).second.second->clearBox();
+      delete (*boxIter).second.second;
+    }
+    boxMap.clear();
+  }
+  
+  void init()
+  {
+    int maxNr = 1.0;
+    for (size_t i = 0; i < DOW; i++)
+      maxNr *= N[i];
+    boxData.resize(maxNr);
+    
+    std::cout<<"\n background mesh\n";
+    std::cout<<"=================\n";
+    std::cout<<"min_corner: "<<min_corner<<"\n";
+    std::cout<<"max_corner: "<<max_corner<<"\n";
+    std::cout<<"N: "<<N<<"\n\n";
+    
+    PointType tolerance; tolerance.set(2.0*DBL_TOL);
+    min_corner -= tolerance;
+    max_corner += tolerance;
+  }
+  
+protected:
+  
+  template<typename T>
+  T evalAtPoint_simple(DOFVector<T>& vec, PointType& x);
+  
+  inline int idx2nr(std::vector<int>& idx)
+  {
+    int nr = idx.back();
+    std::vector<int>::reverse_iterator iIter, nIter;
+    for (iIter = idx.rbegin()+1, nIter = N.rbegin()+1; iIter < idx.rend(); iIter++,nIter++) {
+      nr = *iIter + nr*(*nIter);
+    }
+    return nr;
+  }
+  
+  inline void nr2idx(int nr, std::vector<int>& idx) // template specialization see below
+  {
+    switch (DOW) {
+      case 1:
+	idx.resize(1);
+	idx[0] = nr % N[0];
+	break;
+      case 2:
+	idx.resize(2);
+	idx[1] = nr / N[0];
+	idx[0] = nr % N[0];
+	break;
+      case 3:
+	idx.resize(3);
+	idx[2] = nr / (N[1]*N[0]);
+	nr = nr % (N[1]*N[0]);
+	idx[1] = nr / N[0];
+	idx[0] = nr % N[0];
+	break;
+      default:
+	throw(std::runtime_error("DOW="+boost::lexical_cast<std::string>(DOW)+", nur die Version für DOW=1 verwendet!"));
+	break;
+    }
+  }
+  
+  
+  void getSurroundingBoxes(int nr, std::set<int> &surrounding_nrs)
+  {
+    std::vector<int> idx;
+    nr2idx(nr, idx); // --> idx
+    
+    for (size_t i = 0; i < DOW; i++) {
+      std::vector<int> idx_i = idx;
+      idx_i[i] = std::min(N[i]-1, idx_i[i]+1);
+      surrounding_nrs.insert(idx2nr(idx_i));
+      idx_i[i] = std::max(0, idx_i[i]-2);
+      surrounding_nrs.insert(idx2nr(idx_i));
+    }
+    surrounding_nrs.erase(nr);
+  }
+  
+  void getSurroundingBoxes(std::set<int> &nrs, std::set<int> &surrounding_nrs)
+  {
+    std::set<int>::iterator nrsIter;
+    for (nrsIter = nrs.begin(); nrsIter != nrs.end(); nrsIter++)
+      getSurroundingBoxes(*nrsIter, surrounding_nrs);
+    
+    for (nrsIter = nrs.begin(); nrsIter != nrs.end(); nrsIter++)
+      surrounding_nrs.erase(*nrsIter);
+  }  
+  
+  /// berechne die minimale Entfernung der Ränder der Box zu x
+  double getBoxBoundaryDist(int nr, PointType& x)
+  {
+    std::vector<int> idx;
+    nr2idx(nr, idx);
+    PointType min_c, max_c;
+    for (size_t i = 0; i < DOW; i++) {
+      min_c[i] = min_corner[i] + (max_corner[i]-min_corner[i])*idx[i]/N[i];
+      max_c[i] = min_corner[i] + (max_corner[i]-min_corner[i])*(idx[i]+1)/N[i];
+    }
+    double dist = 1.e15;
+    for (int i = 0; i < DOW; i++)
+      dist = std::min(dist, std::min(abs(max_c[i]-x[i]), abs(min_c[i]-x[i])));
+    return dist;
+  }
+  
+  void addData(PointType x, DataType data)
+  {
+    int nr = getBox(x);
+    if (nr < 0 || nr >= boxData.size())
+      throw(std::runtime_error("box-nr out of range: nr = "+boost::lexical_cast<std::string>(nr)+", boxSize = "+boost::lexical_cast<std::string>(boxData.size())));
+    boxData[nr].push_back(data);
+  }
+  
+  
+  static typename std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> > boxMap;
+
+protected:
+
+  int DOW;
+  std::vector<int> N;
+  bool boxFilled;
+
+  PointType min_corner;
+  PointType max_corner;
+  
+  std::vector<std::vector<DataType> > boxData;
+};
+
+template<typename PointType, typename DataType>
+std::map<const FiniteElemSpace*, std::pair<int, ElementBox<PointType, DataType>*> > ElementBox<PointType, DataType>::boxMap;
+
+} // end namespace tools
+
+#include "BackgroundMesh2.hh"
+
+#endif // BACKGROUND_MESH_H
diff --git a/extensions/BackgroundMesh2.hh b/extensions/BackgroundMesh2.hh
new file mode 100644
index 0000000000000000000000000000000000000000..777d8ca41731549e667f69dc8cc6a7204c1a58d2
--- /dev/null
+++ b/extensions/BackgroundMesh2.hh
@@ -0,0 +1,71 @@
+#include "ElementFunction.h"
+
+namespace experimental {
+
+  template<>
+  void ElementBox<PointType_, std::pair<ElInfoDataType, PointType_> >::fillBox(const FiniteElemSpace* feSpace)
+  {
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+
+    int dim = feSpace->getMesh()->getDim();
+    while (elInfo) {
+      ElInfo* macroElInfo = feSpace->getMesh()->createNewElInfo();
+      macroElInfo->fillMacroInfo(elInfo->getMacroElement());
+      stack.fillRefinementPath(*elInfo, *macroElInfo);
+
+      ElInfoDataType elInfoData = boost::tuples::make_tuple(elInfo->getMacroElement(), elInfo->getRefinementPathLength(), elInfo->getRefinementPath());
+
+      WorldVector<double> centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+
+      addData(centroid, std::make_pair(elInfoData, centroid));
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+    boxFilled = true;
+  }
+  
+
+  template<>
+  bool ElementBox<PointType_, DataType_>::getNearestElInfo(PointType_ &x, ElInfo*& minElInfo)
+  {
+    DataType_ data;
+    if (getNearestData(x, data)) {
+      minElInfo->fillElInfo(data.first.get<0>(), data.first.get<1>(), data.first.get<2>());
+      return true;
+    } else
+      return false;
+  }
+  
+
+  template<typename PointType, typename DataType>
+  template<typename T>
+  T ElementBox<PointType,DataType>::evalAtPoint_simple(DOFVector<T>& vec, PointType& x)
+  {
+    ElInfo* elInfo = vec.getFeSpace()->getMesh()->createNewElInfo();
+    elInfo->setFillFlag(Mesh::FILL_COORDS);
+    T value; nullify(value);
+    if (getNearestElInfo(x, elInfo)) {
+      std::cout<<"elInfo = "<<elInfo->getElement()->getIndex()<<"\n";
+      int dim = vec.getFeSpace()->getMesh()->getDim();
+      DimVec<double> lambda(dim, NO_INIT);
+      for (int i = 0; i < dim+1; i++)
+	lambda[i] = 1.0/std::max(1.e-8, norm(x - elInfo->getCoord(i)));
+      // normalize barycentric coords
+      double sum = 0.0;
+      for (int i = 0; i < dim+1; i++)
+	sum += lambda[i];
+      for (int i = 0; i < dim+1; i++)
+	lambda[i] *= 1.0/sum;
+
+      ElementFunctionDOFVec<T> elFct(&vec);
+      elFct.setElInfo(elInfo);
+      value = elFct(lambda);
+    }
+    return value;
+  }
+
+} // end namespace experimental
diff --git a/extensions/BoundaryFunctions.h b/extensions/BoundaryFunctions.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7d643759ed2eb347a8c266e4d63ca9243d3473c
--- /dev/null
+++ b/extensions/BoundaryFunctions.h
@@ -0,0 +1,247 @@
+/** \file BoundaryFunctions.h */
+
+#ifndef BOUNDARY_FUNCTIONS_H
+#define BOUNDARY_FUNCTIONS_H
+
+#include "AMDiS.h"
+#include <time.h>
+
+using namespace std;
+using namespace AMDiS;
+
+
+// parabolic inflow
+class ParabolicInflow: public AbstractFunction<double, WorldVector<double> >
+{
+public:
+	ParabolicInflow() : AbstractFunction<double, WorldVector<double> >(2), dim(1.0),c(1.0), dir(1) {};
+	ParabolicInflow(double dim_, double c_, int dir_= 0) : AbstractFunction<double, WorldVector<double> >(2), dim(dim_),c(c_),dir(dir_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		return c*std::max(0.0, 1.0-sqr(x[1-dir])/sqr(dim)); 
+	};
+protected: 
+	double dim,c;
+	int dir;
+};
+
+// parabolic inflow
+class ParabolicInflowPressure: public AbstractFunction<double, WorldVector<double> >
+{
+public:
+        ParabolicInflowPressure() : AbstractFunction<double, WorldVector<double> >(2), dim(1.0),c(1.0), dir(1), viscosity(1.0) {};
+        ParabolicInflowPressure(double dim_, double c_, int dir_= 0, double viscosity_= 1.0) : AbstractFunction<double, WorldVector<double> >(2), dim(dim_),c(c_),dir(dir_),viscosity(viscosity_) {};
+        double operator()(const WorldVector<double>& x) const  {  
+                return -2.0*c*viscosity*x[dir]/sqr(dim); 
+        };
+protected: 
+        double dim,c,viscosity;
+        int dir;
+};
+
+class ParabolicInflow_robin: public AbstractFunction<double, WorldVector<double> >
+{
+public:
+	ParabolicInflow_robin() : AbstractFunction<double, WorldVector<double> >(1), y(1.0),c(1.0) {};
+	ParabolicInflow_robin(double y_, double c_) : AbstractFunction<double, WorldVector<double> >(1), y(y_),c(c_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		double result = c*(1.0-sqr(x[1])/sqr(y)); 
+		double n = (x[0]<0.0?-1.0:1.0);
+		return -1.0*result*n;
+	};
+protected: 
+	double y,c;
+};
+
+// parabolic inflow 2
+class BoundaryFct1: public AbstractFunction<double, WorldVector<double> >
+{
+public:
+	BoundaryFct1() : AbstractFunction<double, WorldVector<double> >(1), y(0.205), c(6.0) {};
+	BoundaryFct1(double y_, double c_) : AbstractFunction<double, WorldVector<double> >(1), y(y_),c(c_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		return 1.0/sqr(2.0*y)*c*(y+x[1])*(y-x[1]);
+	};
+protected: 
+	double y,c;
+};
+
+class BoundaryFct1_robin: public AbstractFunction<double, WorldVector<double> >
+{
+public:
+	BoundaryFct1_robin() : AbstractFunction<double, WorldVector<double> >(1), y(0.205), c(6.0) {};
+	BoundaryFct1_robin(double y_, double c_) : AbstractFunction<double, WorldVector<double> >(1), y(y_),c(c_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		double result = 1.0/sqr(2.0*y)*c*(y+x[1])*(y-x[1]);
+		double n = (x[0]<0.0?-1.0:1.0);
+		return -1.0*result*n;
+	};
+protected: 
+	double y,c;
+};
+
+// time-dependent inflow
+class BoundaryFct2: public AbstractFunction<double, WorldVector<double> >, public TimedObject
+{
+public:
+	BoundaryFct2() : AbstractFunction<double, WorldVector<double> >(1), y(0.205), c(6.0) {};
+	BoundaryFct2(double y_, double c_) : AbstractFunction<double, WorldVector<double> >(1), y(y_),c(c_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		return 1.0/sqr(2.0*y) * sin(M_PI*(*timePtr)/8.0)*c*(y+x[1])*(y-x[1]);
+	};
+protected: 
+	double y,c;
+};
+
+class BoundaryFct2_robin: public AbstractFunction<double, WorldVector<double> >, public TimedObject
+{
+public:
+	BoundaryFct2_robin() : AbstractFunction<double, WorldVector<double> >(1), y(0.205), c(6.0) {};
+	BoundaryFct2_robin(double y_, double c_) : AbstractFunction<double, WorldVector<double> >(1), y(y_),c(c_) {};
+	double operator()(const WorldVector<double>& x) const  {  
+		double result = 1.0/sqr(2.0*y) * sin(M_PI*(*timePtr)/8.0)*c*(y+x[1])*(y-x[1]);
+		double n = (x[0]<0.0?-1.0:1.0);
+		return -1.0*result*n;
+	};
+protected: 
+	double y,c;
+};
+
+// Stokes flow (analytic definition)
+class StokesFlow : public AbstractFunction<WorldVector<double>, WorldVector<double> >
+{
+  public:
+    StokesFlow(double peclet_) : AbstractFunction<WorldVector<double>, WorldVector<double> >(6), peclet(peclet_) {
+      // parameters for pfc
+      double R=0.5, density=-0.3, r=0.1, D=1.0;
+      Initfile::get("user parameter->colloidal radius",R, 1);
+      Initfile::get("pfc-parameter->density",density, 1);
+      Initfile::get("pfc-parameter->r",r, 1);
+      radius = R/(1.0-R) * 2.0*M_PI/sqrt(3.0);
+      D = radius + 2.0*M_PI/sqrt(3.0);
+
+      center.set(0.0);
+      Initfile::get("user parameter->colloids position[0]",center, 1);
+
+      c.set(0.0);
+      c[0] = peclet/D*abs(r/density);
+    }
+    WorldVector<double> operator()(const WorldVector<double> &x) const {
+      WorldVector<double> xTrans = x-center;
+      WorldVector<double> result;
+
+      if(norm(xTrans)<radius)
+	      result.set(0.0);
+      else {
+	      result = c-(3.0*radius/(4.0*norm(xTrans)))*(1.0+sqr(radius)/(3.0*sqr(norm(xTrans))))*c;
+	      result+= 3*radius/(4.0*norm(xTrans)*sqr(norm(xTrans)))*(xTrans*c)*(sqr(radius)/sqr(norm(xTrans))-1.0)*xTrans;
+      }
+
+      return result;
+    }
+  protected:
+    double peclet;
+    double radius;
+    WorldVector<double> center,c;
+};
+class StokesFlow_component : public AbstractFunction<double, WorldVector<double> >
+{
+  public:
+    StokesFlow_component(double peclet_, int comp_) : AbstractFunction<double, WorldVector<double> >(6), peclet(peclet_),comp(comp_) {
+      // parameters for pfc
+      double R=0.5, density=-0.3, r=0.1, D=1.0;
+      Initfile::get("user parameter->colloidal radius",R, 1);
+      Initfile::get("pfc-parameter->density",density, 1);
+      Initfile::get("pfc-parameter->r",r, 1);
+      radius = R/(1.0-R) * 2.0*M_PI/sqrt(3.0);
+      D = radius + 2.0*M_PI/sqrt(3.0);
+
+      center.set(0.0);
+      Initfile::get("user parameter->colloids position[0]",center, 1);
+
+      c.set(0.0);
+      c[0] = peclet/D*abs(r/density);
+    }
+    double operator()(const WorldVector<double> &x) const {
+      WorldVector<double> xTrans = x-center;
+      WorldVector<double> result;
+
+      if(norm(xTrans)<radius)
+	      result.set(0.0);
+      else {
+	      result = c-(3.0*radius/(4.0*norm(xTrans)))*(1.0+sqr(radius)/(3.0*sqr(norm(xTrans))))*c;
+	      result+= 3*radius/(4.0*norm(xTrans)*sqr(norm(xTrans)))*(xTrans*c)*(sqr(radius)/sqr(norm(xTrans))-1.0)*xTrans;
+      }
+
+      return result[comp];
+    }
+  protected:
+    double peclet;
+    int comp;
+    double radius;
+    WorldVector<double> center,c;
+};
+class StokesFlow_robin : public AbstractFunction<double, WorldVector<double> >
+{
+  public:
+    StokesFlow_robin(double y_, double peclet_) : AbstractFunction<double, WorldVector<double> >(6), y(y_), peclet(peclet_) {
+      // parameters for pfc
+      double R=0.5, density=-0.3, r=0.1, D=1.0;
+      Initfile::get("user parameter->colloidal radius",R, 1);
+      Initfile::get("pfc-parameter->density",density, 1);
+      Initfile::get("pfc-parameter->r",r, 1);
+      radius = R/(1.0-R) * 2.0*M_PI/sqrt(3.0);
+      D = radius + 2.0*M_PI/sqrt(3.0);
+
+      center.set(0.0);
+      Initfile::get("user parameter->colloids position[0]",center, 1);
+
+      c.set(0.0);
+      c[0] = peclet/D*abs(r/density);
+    }
+    double operator()(const WorldVector<double> &x) const {
+      WorldVector<double> xTrans = x-center;
+      WorldVector<double> result;
+
+      if(norm(xTrans)<radius)
+	      result.set(0.0);
+      else {
+	      result = c-(3.0*radius/(4.0*norm(xTrans)))*(1.0+sqr(radius)/(3.0*sqr(norm(xTrans))))*c;
+	      result+= 3*radius/(4.0*norm(xTrans)*sqr(norm(xTrans)))*(xTrans*c)*(sqr(radius)/sqr(norm(xTrans))-1.0)*xTrans;
+      }
+
+      WorldVector<double> n;
+      n[0] = (abs(x[1])<y-1.e-8?(x[0]<0.0?-1.0:1.0):0.0);
+      n[1] = (abs(x[1])>y-1.e-8?(x[1]<0.0?-1.0:1.0):0.0);
+      return -1.0*n*result;
+    }
+  protected:
+    double y,peclet;
+    double radius;
+    WorldVector<double> center,c;
+};
+
+// constant inflow
+class ConstantFct : public AbstractFunction<double, WorldVector<double> >
+{
+public:
+  ConstantFct(double c)
+    : AbstractFunction<double, WorldVector<double> >(1), constant(c)  {};
+  double operator()(const WorldVector<double>& x) const  { return constant;  }
+
+protected:
+  double constant;
+};
+
+// constant inflow
+class ConstantTimeFct : public AbstractFunction<double, WorldVector<double> >, public TimedObject
+{
+public:
+  ConstantTimeFct(double c, double endTime_)
+    : AbstractFunction<double, WorldVector<double> >(1), constant(c), endTime(endTime_)  {};
+  double operator()(const WorldVector<double>& x) const  { return constant*max(0.0, std::min(1.0, (endTime-(*timePtr))/endTime));  }
+
+protected:
+  double constant;
+  double endTime;
+};
+#endif // BOUNDARY_FUNCTIONS_H
diff --git a/extensions/ExtendedProblemStat.h b/extensions/ExtendedProblemStat.h
new file mode 100644
index 0000000000000000000000000000000000000000..adbbc4c4563678a1a1680c4455e766bdb591b8e9
--- /dev/null
+++ b/extensions/ExtendedProblemStat.h
@@ -0,0 +1,473 @@
+/** \file ExtendedProblemStat.h */
+
+#ifndef EXTENDED_PROBLEM_STAT_H
+#define EXTENDED_PROBLEM_STAT_H
+
+#include "AMDiS.h"
+#include "SingularDirichletBC.h"
+#if defined NONLIN_PROBLEM
+  #include "nonlin/ProblemNonLin.h"
+#endif
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  #include "parallel/PetscProblemStat.h"
+#endif
+
+using namespace AMDiS;
+
+const Flag INIT_EXACT_SOLUTION = 0X2000L;
+const Flag UPDATE_PERIODIC_BC = 0X4000L;
+const Flag UPDATE_DIRICHLET_BC = 0X8000L;
+
+#if defined NONLIN_PROBLEM
+typedef ProblemNonLin ProblemStat_;
+#else
+typedef ProblemStat ProblemStat_;
+#endif
+class ExtendedProblemStat : public ProblemStat_
+{
+public:
+  
+  ExtendedProblemStat(std::string nameStr, ProblemIterationInterface *problemIteration = NULL)
+  :
+  #if defined NONLIN_PROBLEM
+  ProblemStat_(nameStr)
+  #else
+  ProblemStat_(nameStr, problemIteration)
+  #endif
+  , oldMeshChangeIdx(0)
+  {
+    exactSolutions.resize(nComponents);
+    for (int i = 0; i < nComponents; ++i)
+      exactSolutions[i] = NULL;
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+      ksp_type = "bcgs";
+      pc_type = "bjacobi";
+      pc_factor_mat_solver_package = "mumps";
+      ksp_rtol = 0.0;
+      ksp_abstol = 1.e-8;
+      ksp_maxits = 500;
+
+      Parameters::get(nameStr + "->petsc->ksp_type",ksp_type);
+      Parameters::get(nameStr + "->petsc->pc_type",pc_type);
+      Parameters::get(nameStr + "->petsc->pc_factor_mat_solver_package",pc_factor_mat_solver_package);
+      Parameters::get(nameStr + "->petsc->rtol",ksp_rtol);
+      Parameters::get(nameStr + "->petsc->abstol",ksp_abstol);
+      Parameters::get(nameStr + "->petsc->maxits",ksp_maxits);
+#endif
+  }
+
+  void initialize(Flag initFlag,
+		  ProblemStatSeq *adoptProblem = NULL,
+		  Flag adoptFlag = INIT_NOTHING)
+  {
+    ProblemStat_::initialize(initFlag, adoptProblem, adoptFlag);
+    
+//     if (initFlag.isSet(INIT_EXACT_SOLUTION)) {
+      for (int i = 0; i < nComponents; ++i)
+	exactSolutions[i] = new DOFVector< double >(getFeSpace(i), "exact_solution");
+//     }
+  }
+
+  inline DOFVector<double>* getRhsVector(int i = 0)
+  {
+    return rhs->getDOFVector(i);
+  }
+
+  ///
+  void setExactSolution(DOFVector<double> *dof, int component) 
+  {
+    TEST_EXIT(exactSolutions[component] != NULL)
+      ("You have to initialize the exactSolutions vector! Set the initFlag INIT_EXACT_SOLUTION for the problem.\n");
+    exactSolutions[component]->copy(*dof);
+  }
+
+  ///
+  inline DOFVector<double> *getExactSolution(int i = 0) 
+  {
+    TEST_EXIT(exactSolutions[i] != NULL)
+      ("You have to initialize the exactSolutions vector! Set the initFlag INIT_EXACT_SOLUTION for the problem.\n");
+    return exactSolutions[i];
+  }
+
+  void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
+			  bool asmMatrix, bool asmVector)
+  { FUNCNAME("ExtendedProblemStat::buildAfterCoarsen()");
+  
+    ProblemStat_::buildAfterCoarsen(adaptInfo, flag, asmMatrix, asmVector);
+
+#ifndef HAVE_PARALLEL_DOMAIN_AMDIS
+    // update periodic data
+    if (oldMeshChangeIdx != getMesh()->getChangeIndex()
+      || flag.isSet(UPDATE_PERIODIC_BC)
+      || (PeriodicBcDataList.size() > 0 && manualPeriodicBC.size() == 0)) {
+      manualPeriodicBC.clear();
+      std::vector<PeriodicBcData>::iterator it;
+      for (it = PeriodicBcDataList.begin(); it != PeriodicBcDataList.end(); it++)
+	it->addToList(getFeSpace(), manualPeriodicBC);
+    }
+    
+    // update dirichlet data
+    if (oldMeshChangeIdx != getMesh()->getChangeIndex()
+      || flag.isSet(UPDATE_DIRICHLET_BC)
+      || (DirichletBcDataList.size() > 0 && singularDirichletBC.size() == 0)) {
+      singularDirichletBC.clear();
+      std::vector<DirichletBcData>::iterator it;
+      for (it = DirichletBcDataList.begin(); it != DirichletBcDataList.end(); it++) {
+	it->addToList(getFeSpace(it->row), singularDirichletBC);
+      }
+    }
+
+    // apply periodic boundary conditions
+    for (size_t k = 0; k < manualPeriodicBC.size(); k++)
+      applyPeriodicBC(manualPeriodicBC[k], asmMatrix, asmVector);
+    
+    // apply dirichlet boundary conditions
+    for (size_t k = 0; k < singularDirichletBC.size(); k++)
+      applyDirichletBC(singularDirichletBC[k], asmMatrix, asmVector);
+
+    // update solverMatrix
+    if (asmMatrix && (singularDirichletBC.size() > 0 || manualPeriodicBC.size() > 0)) {
+      solverMatrix.setMatrix(*getSystemMatrix());
+    }
+#endif
+  }
+
+  void solve(AdaptInfo *adaptInfo,
+	      bool createMatrixData = true,
+	      bool storeMatrixData = false)
+  { FUNCNAME("ExtendedProblemStat::solve()");
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    TEST_EXIT(meshDistributor)("Should not happen!\n");
+    TEST_EXIT(singularDirichletBC.size() == 0)
+      ("Singular Dirichlet BC not implemented for parallel computing!\n");
+
+    double wtime = MPI::Wtime();
+
+    if (createMatrixData) {
+      petscSolver->setMeshDistributor(meshDistributor);
+      petscSolver->fillPetscMatrix(systemMatrix);
+    }
+
+    petscSolver->fillPetscRhs(rhs);
+
+    MSG("set PETSC-Parameters...\n");
+    KSPSetType(petscSolver->getSolver(), ksp_type.c_str());
+    KSPSetTolerances(petscSolver->getSolver(), ksp_rtol, ksp_abstol, PETSC_DEFAULT, ksp_maxits);
+    if (ksp_type == "preonly") {
+      KSPSetInitialGuessNonzero(petscSolver->getSolver(), PETSC_FALSE);
+    }
+    PCSetType(petscSolver->getPc(),  pc_type.c_str());
+    if (pc_type == "lu") {
+      PCFactorSetMatSolverPackage(petscSolver->getPc(), pc_factor_mat_solver_package.c_str());
+    }
+
+    petscSolver->solvePetscMatrix(*solution, adaptInfo);
+
+    if (!storeMatrixData)
+      petscSolver->destroyMatrixData();
+
+    INFO(info, 8)("solution of discrete system needed %.5f seconds\n",
+		  MPI::Wtime() - wtime);
+#endif
+    
+    ProblemStat_::solve(adaptInfo, createMatrixData, storeMatrixData);
+
+    oldMeshChangeIdx = getMesh()->getChangeIndex();
+  }
+
+  /// Add arbitrary boundary condition to system
+  void addBoundaryCondition(BoundaryCondition *bc, int row, int col)
+  {
+    FUNCNAME("ProblemStatType::addBoundaryCondition()");
+
+    boundaryConditionSet = true;
+
+    if (systemMatrix && (*systemMatrix)[row][col])
+      (*systemMatrix)[row][col]->getBoundaryManager()->addBoundaryCondition(bc);
+    if (rhs)
+      rhs->getDOFVector(row)->getBoundaryManager()->addBoundaryCondition(bc);
+  }
+
+  /**
+    * Dirichlet boundary condition at DOF-Index of vertex near to coords 'pos'.
+    * Value defined by AbstractFunction, that is evaluated at 'pos'
+    **/
+  template<typename ValueContainer>
+  void addSingularDirichletBC(WorldVector<double> &pos, int row, int col,
+			      ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, pos, values));
+  }
+
+  /**
+    * Dirichlet boundary condition at DOF-Index 'idx'. Value defined by double.
+    **/
+  template<typename ValueContainer>
+  void addSingularDirichletBC(DegreeOfFreedom idx, int row, int col,
+			      ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, idx, values));
+  }
+
+  /**
+    * set dirichlet boundary condition on implicitly defined boundary by zero levelset
+    * of signed distance function.
+    * An algebraic equation is forced in the region with dist<0
+    * 
+    **/
+  template<typename ValueContainer>
+  void addImplicitDirichletBC(DOFVector<double> &signedDist,
+			      int row, int col,
+			      ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, &signedDist, values));
+  }
+  
+  template<typename ValueContainer>
+  void addImplicitDirichletBC(AbstractFunction<double, WorldVector<double> > &signedDist,
+			      int row, int col,
+			      ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, &signedDist, values));
+  }
+
+  template<typename ValueContainer>
+  void addManualDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			    int row, int col,
+			    ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, nr, meshIndicator, values));
+  }
+  
+
+  template<typename ValueContainer>
+  void addManualDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			    int row, int col,
+			    ValueContainer &values)
+  {
+    DirichletBcDataList.push_back(DirichletBcData(row, col, meshIndicator, values));
+  }
+  
+  
+  void addManualPeriodicBC(int row,
+			    BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			    AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap)
+  {
+    PeriodicBcDataList.push_back(PeriodicBcData(row, nr, meshIndicator, periodicMap));
+  }
+
+  void addManualPeriodicBC(int row,
+			    AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			    AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap)
+  {
+    PeriodicBcDataList.push_back(PeriodicBcData(row, meshIndicator, periodicMap));
+  }
+
+  /// write Systemmatrix to file in matlab-format
+  void writeMatrix(std::string filename)
+  {
+    mtl::io::matrix_market_ostream out(filename);
+    SolverMatrix<Matrix<DOFMatrix*> > solverMatrix;
+    solverMatrix.setMatrix(*getSystemMatrix());
+    out << solverMatrix.getMatrix();
+    out.close();
+  }
+  
+  /// Returns the name of the problem
+  inline string getComponentName(int comp = 0)
+  {
+    TEST_EXIT(comp < static_cast<int>(componentNames.size()) && comp >= 0)
+      ("invalid component number\n");
+    return componentNames[comp];
+  }
+    
+protected:
+
+  // traverse matrix rows and set unity row where dirichlet condition shall be applied.
+  void applyDirichletBC(size_t row_, size_t col_, DegreeOfFreedom idx, double value, bool asmMatrix = true, bool asmVector = true)
+  {
+    using namespace mtl;
+    typedef DOFMatrix::base_matrix_type Matrix;
+
+    Matrix::size_type idx_= idx;
+    bool value1set = false;
+
+    if (asmMatrix) {
+      typedef traits::range_generator<tag::row, Matrix>::type c_type;
+      typedef traits::range_generator<tag::nz, c_type>::type  ic_type;
+
+      for (size_t col = 0; col < getNumComponents(); col++) {
+	TEST_EXIT(getSystemMatrix(row_, col) != NULL || col != col_)
+	  ("SystemMatrix block (%d,%d) must not be NULL! Insert a Simple_ZOT(0.0) as Workaround.\n",row_,col);
+	if (getSystemMatrix(row_, col) == NULL)
+	  continue;
+
+	// set Dirichlet-row in matrix
+	Matrix &m = getSystemMatrix(row_, col)->getBaseMatrix();
+
+	traits::row<Matrix>::type r(m);
+	traits::col<Matrix>::type c(m);
+	traits::value<Matrix>::type v(m);
+
+	c_type cursor(begin<tag::row>(m)+idx_);
+	for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
+	  value1set = value1set || r(*icursor) == c(*icursor) && col == col_;
+	  v(*icursor, (r(*icursor) == c(*icursor) && col == col_ ? 1.0 : 0.0));
+	}
+      }
+
+      if (!value1set) {
+	matrix::inserter<Matrix, update_plus<double> > ins(getSystemMatrix(row_, col_)->getBaseMatrix());
+	ins[row_][col_] << 1.0;
+      }
+    }
+    if (asmVector)
+      (*getRhsVector(row_))[idx] = value; // set Dirichlet-Value at rhs-vector
+      
+    (*solution->getDOFVector(row_))[idx] = value; // set Dirichlet-value for solution component
+  }
+  
+  void applyDirichletBC(SingularDirichletBC &sbc, bool asmMatrix = true, bool asmVector = true)
+  {
+    applyDirichletBC(sbc.row, sbc.col, sbc.idx, sbc.value, asmMatrix, asmVector);
+  }
+
+  void applyPeriodicBC(size_t row, std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &indices, bool asmMatrix = true, bool asmVector = true)
+  {
+    using namespace mtl;
+    typedef DOFMatrix::base_matrix_type Matrix;
+
+    typedef traits::range_generator<tag::row, Matrix>::type c_type;
+    typedef traits::range_generator<tag::nz, c_type>::type  ic_type;
+
+    for (size_t col = 0; col < getNumComponents(); col++) {
+      TEST_EXIT(getSystemMatrix(row, col) != NULL)
+	("SystemMatrix block (%d,%d) must not be NULL! Insert a Simple_ZOT(0.0) as Workaround.\n",row,col);
+
+      Matrix &m = getSystemMatrix(row, col)->getBaseMatrix();
+
+      traits::row<Matrix>::type r(m);
+      traits::col<Matrix>::type c(m);
+      traits::value<Matrix>::type v(m);
+      
+      std::vector<std::vector<std::pair<DegreeOfFreedom, double> > > row_values;
+      row_values.resize(indices.size());
+
+      // erase the rows for all first indices
+      for (size_t i = 0; i < indices.size(); i++) {
+	if (asmMatrix) {
+	  c_type cursor(begin<tag::row>(m)+indices[i].first);
+	  for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
+	    row_values[i].push_back(std::make_pair(c(*icursor), v(*icursor)));
+	    v(*icursor, 0.0);
+	  }
+	}
+	if (asmVector) {
+	  (*(getRhsVector(row)))[indices[i].second] += (*(getRhsVector(row)))[indices[i].first];
+	  (*(getRhsVector(row)))[indices[i].first] = 0.0;
+	}
+      }
+
+      // add periodic associations of first and second indices, but only in the diagonal blocks
+      if (asmMatrix) {
+	matrix::inserter<Matrix, update_plus<double> > ins(m);
+	if (row == col) {
+	  for (size_t i = 0; i < indices.size(); i++) {
+	    ins[indices[i].first][indices[i].first] << 1.0;
+	    ins[indices[i].first][indices[i].second] << -1.0;
+	  }
+	}
+	for (size_t i = 0; i < indices.size(); i++) {
+	  for (size_t j = 0; j < row_values[i].size(); j++) {
+	    ins[indices[i].second][row_values[i][j].first] << row_values[i][j].second;
+	  }
+	}
+      }
+    }
+  }
+
+  void applyPeriodicBC(ManualPeriodicBC &pbc, bool asmMatrix = true, bool asmVector = true)
+  {
+    applyPeriodicBC(pbc.row, pbc.indices, asmMatrix, asmVector);
+  }
+
+  void applyAlgebraicEquation(size_t row,
+			      std::vector<DegreeOfFreedom> &row_idx,
+			      std::vector<std::vector<double> > &coefficients,
+			      std::vector<double> &rhs)
+  {
+    using namespace mtl;
+    typedef DOFMatrix::base_matrix_type Matrix;
+
+    typedef traits::range_generator<tag::row, Matrix>::type c_type;
+    typedef traits::range_generator<tag::nz, c_type>::type  ic_type;
+
+    TEST_EXIT(row_idx.size() == coefficients.size() && row_idx.size() == rhs.size() && rhs.size()>0)
+      ("rhs_idx, coefficients and rhs must have the same size and size >! 0\n");
+    TEST_EXIT(coefficients[0].size() == getNumComponents())
+      ("You have to give coefficients for all variables\n");
+
+    for (size_t col = 0; col < getNumComponents(); col++) {
+      TEST_EXIT(getSystemMatrix(row, col) != NULL)
+	("SystemMatrix block (%d,%d) must not be NULL! Insert a Simple_ZOT(0.0) as Workaround.\n",row,col);
+
+      Matrix &m = getSystemMatrix(row, col)->getBaseMatrix();
+
+      traits::row<Matrix>::type r(m);
+      traits::col<Matrix>::type c(m);
+      traits::value<Matrix>::type v(m);
+
+      // erase the rows for all row-indices and set rhs values
+      for (size_t i = 0; i < coefficients.size(); i++) {
+	c_type cursor(begin<tag::row>(m)+row_idx[i]);
+	for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
+	  v(*icursor, (r(*icursor) == c(*icursor) ? coefficients[i][col] : 0.0));
+	}
+	(*(getRhsVector(row)))[row_idx[i]] = rhs[i];
+      }
+    }
+  }
+
+  void applyAlgebraicEquation(size_t row,
+			      DegreeOfFreedom &row_idx0,
+			      std::vector<double> &coefficients0,
+			      double rhs0)
+  {
+    std::vector<DegreeOfFreedom> row_idx; row_idx.push_back(row_idx0);
+    std::vector<std::vector<double> > coefficients; coefficients.push_back(coefficients0);
+    std::vector<double> rhs; rhs.push_back(rhs0);
+
+    applyAlgebraicEquation(row, row_idx, coefficients, rhs);
+  }
+
+private:
+  
+  int oldMeshChangeIdx;
+  std::vector<DOFVector<double>*> exactSolutions;
+
+  // data for periodic boundary conditions
+  std::vector<ManualPeriodicBC> manualPeriodicBC;
+  std::vector<PeriodicBcData> PeriodicBcDataList;
+
+  // data for dirichlet boundary conditions
+  std::vector<SingularDirichletBC> singularDirichletBC;
+  std::vector<DirichletBcData> DirichletBcDataList;
+
+  std::map<const FiniteElemSpace*, bool> feSpaceVisited;
+  
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  std::string ksp_type; 
+  std::string pc_type;
+  std::string pc_factor_mat_solver_package;
+  
+  double ksp_rtol;
+  double ksp_abstol;
+  
+  int ksp_maxits;
+#endif
+
+};
+#endif // EXTENDED_PROBLEM_STAT_H
diff --git a/extensions/GeometryTools.cc b/extensions/GeometryTools.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f59ea8d37299506c992b909a0c2630ae0ccc1ade
--- /dev/null
+++ b/extensions/GeometryTools.cc
@@ -0,0 +1,1503 @@
+#include "GeometryTools.h"
+
+#define EPSILON FLT_EPSILON
+
+namespace meshconv {
+
+//                                      ###############
+//                                      ##  General  ##
+//                                      ###############
+
+//----------------------------------------< coordinate_extrema_triangle >
+//returns in 'small_coord' the smallest coordinate of 'sm' in the given dimension and in 'big_coord' the
+//biggest coordinate in the given dimension. Note: 'sm' has to be a triangle in a 2d or 3d world.
+// void coordinate_extrema_triangle(mesh &m, element &sm, long dimension, double &small_coord,
+//                                                                           double &big_coord){
+//   if(m.vertices[sm.v[0]][dimension] <= m.vertices[sm.v[1]][dimension]){
+//     if(m.vertices[sm.v[0]][dimension] <= m.vertices[sm.v[2]][dimension]){
+//       small_coord = m.vertices[sm.v[0]][dimension];
+//       if(m.vertices[sm.v[1]][dimension] >= m.vertices[sm.v[2]][dimension])
+//         big_coord = m.vertices[sm.v[1]][dimension];
+//       else
+//         big_coord = m.vertices[sm.v[2]][dimension];
+//     }
+//     else{
+//       small_coord = m.vertices[sm.v[2]][dimension];
+//       big_coord = m.vertices[sm.v[1]][dimension];
+//     }
+//   }
+//   else{
+//     if(m.vertices[sm.v[1]][dimension] <= m.vertices[sm.v[2]][dimension]){
+//       small_coord = m.vertices[sm.v[1]][dimension];
+//       if(m.vertices[sm.v[0]][dimension] >= m.vertices[sm.v[2]][dimension])
+//         big_coord = m.vertices[sm.v[0]][dimension];
+//       else
+//         big_coord = m.vertices[sm.v[2]][dimension];
+//     }
+//     else{
+//       small_coord = m.vertices[sm.v[2]][dimension];
+//       big_coord = m.vertices[sm.v[0]][dimension];
+//     }
+//   }
+// }
+
+//----------------------------------------< solve_determinant4 >
+double solve_determinant4(double x11, double x12, double x13, double x14,
+                          double x21, double x22, double x23, double x24,
+                          double x31, double x32, double x33, double x34,
+                          double x41, double x42, double x43, double x44){
+  return x11*(x22*x33*x44 + x23*x34*x42 + x24*x32*x43 - x24*x33*x42 - x23*x32*x44 - x22*x34*x43)
+        -x12*(x21*x33*x44 + x23*x34*x41 + x24*x31*x43 - x24*x33*x41 - x23*x31*x44 - x21*x34*x43)
+        +x13*(x21*x32*x44 + x22*x34*x41 + x24*x31*x42 - x24*x32*x41 - x22*x31*x44 - x21*x34*x42)
+        -x14*(x21*x32*x43 + x22*x33*x41 + x23*x31*x42 - x23*x32*x41 - x22*x31*x43 - x21*x33*x42);
+}
+
+//                                      #################
+//                                      ##  2D Worlds  ##
+//                                      #################
+
+//----------------------------------------< edge_length_2d >
+double edge_length_2d(double lin0[], double lin1[]){
+  long i;
+  double p[2];
+
+  for(i=0; i<2; ++i) p[i] = lin0[i] - lin1[i];
+  return sqrt(p[0] * p[0] + p[1] * p[1]);
+}
+
+//----------------------------------------< boundingbox_triangle_2d >
+void boundingbox_triangle_2d(double tri0[], double tri1[], double tri2[],
+			     double min_corner[], double max_corner[]){
+  min_corner[0] = std::min(std::min(tri0[0],tri1[0]),tri2[0]);
+  min_corner[1] = std::min(std::min(tri0[1],tri1[1]),tri2[1]);
+  max_corner[0] = std::max(std::max(tri0[0],tri1[0]),tri2[0]);
+  max_corner[1] = std::max(std::max(tri0[1],tri1[1]),tri2[1]);
+}
+
+//----------------------------------------< centroid_of_box_2d >
+void centroid_of_box_2d(double min_corner[], double max_corner[], double c[]){
+  c[0] = 0.5*(max_corner[0]+min_corner[0]);
+  c[1] = 0.5*(max_corner[1]+min_corner[1]);
+}
+
+//----------------------------------------< centroid_of_triangle_2d >
+void centroid_of_triangle_2d(double tri0[], double tri1[], double tri2[], double c[]){
+  c[0] = (tri0[0]+tri1[0],tri2[0])/3.0;
+  c[1] = (tri0[1]+tri1[1],tri2[1])/3.0;
+}
+
+//----------------------------------------< point_in_triangle_2d >
+bool point_in_triangle_2d(double p[], double a[], double b[], double c[]){
+  long i;
+  double v0[2], v1[2], v2[2];
+  double dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
+
+  //compute direction vectors
+  for(i=0; i<2; i++) v0[i] = c[i] - a[i];
+  for(i=0; i<2; i++) v1[i] = b[i] - a[i];
+  for(i=0; i<2; i++) v2[i] = p[i] - a[i];
+
+  //compute dot products
+  dot00 = v0[0]*v0[0] + v0[1]*v0[1]; //dot(v0, v0)
+  dot01 = v0[0]*v1[0] + v0[1]*v1[1]; //dot(v0, v1)
+  dot02 = v0[0]*v2[0] + v0[1]*v2[1]; //dot(v0, v2)
+  dot11 = v1[0]*v1[0] + v1[1]*v1[1]; //dot(v1, v1)
+  dot12 = v1[0]*v2[0] + v1[1]*v2[1]; //dot(v1, v2)
+
+  //compute barycentric coordinates
+  invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
+  u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+  v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+  //check if point is in triangle
+  return (u >= 0.0) && (v >= 0.0) && (u + v <= 1.0);
+}
+
+//----------------------------------------< point_in_triangle_generous_2d >
+bool point_in_triangle_generous_2d(double p[], double a[], double b[], double c[]){
+  long i;
+  double v0[2], v1[2], v2[2];
+  double dot00, dot01, dot02, dot11, dot12, invDenom, u, v;
+
+  //compute direction vectors
+  for(i=0; i<2; i++) v0[i] = c[i] - a[i];
+  for(i=0; i<2; i++) v1[i] = b[i] - a[i];
+  for(i=0; i<2; i++) v2[i] = p[i] - a[i];
+
+  //compute dot products
+  dot00 = v0[0]*v0[0] + v0[1]*v0[1]; //dot(v0, v0)
+  dot01 = v0[0]*v1[0] + v0[1]*v1[1]; //dot(v0, v1)
+  dot02 = v0[0]*v2[0] + v0[1]*v2[1]; //dot(v0, v2)
+  dot11 = v1[0]*v1[0] + v1[1]*v1[1]; //dot(v1, v1)
+  dot12 = v1[0]*v2[0] + v1[1]*v2[1]; //dot(v1, v2)
+
+  //compute barycentric coordinates
+  invDenom = 1.0 / (dot00 * dot11 - dot01 * dot01);
+  u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+  v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+
+  //check if point is in triangle
+  return (u >= -EPSILON) && (v >= -EPSILON) && (u + v - 1.0 <= EPSILON);
+}
+
+
+//----------------------------------------< point_in_box_2d >
+bool point_in_box_2d(double p[], double min_corner[], double max_corner[]){
+  
+  return (p[0] >= min_corner[0]) && (p[0] <= max_corner[0]) &&
+	 (p[1] >= min_corner[1]) && (p[1] <= max_corner[1]);
+}
+
+//----------------------------------------< point_in_box_generous_2d >
+bool point_in_box_generous_2d(double p[], double min_corner[], double max_corner[]){
+  
+  return (p[0]-min_corner[0] >= -EPSILON) && (p[0]-max_corner[0] <= EPSILON) &&
+	 (p[1]-min_corner[1] >= -EPSILON) && (p[1]-max_corner[1] <= EPSILON);
+}
+
+//----------------------------------------< intersection_line_line_2d >
+//tests whether the line segment defined by end points 'lin0' and 'lin1' intersects the connection
+//between lamp and new_dof. If the line segment is intersected in one of its vertices the index of that
+//vertex (0 or 1) is returned in hit_vertex otherwise hit_vertex is set to -1.
+bool intersection_line_line_2d(double lin0[], double lin1[],
+                               double lamp[], double new_dof[], long &hit_vertex){
+  long i;
+  double x=-1.0, y=-1.0, tmp;
+  double p3[2], q3[2];
+  hit_vertex = -1;
+
+  for(i=0; i<2; ++i){
+    p3[i] = lin1[i] - lin0[i];
+    q3[i] = new_dof[i] - lamp[i];
+  }
+
+  //partial coincidence of small element and center-connection is a special case, it does not count as an
+  //intersection
+  tmp = p3[0]*q3[1] - p3[1]*q3[0];
+  if(abs(tmp) > EPSILON){
+
+    //no partial coincidence; test for intersection
+    if(abs(q3[0]) < EPSILON){
+      if(abs(p3[0]) > EPSILON){
+        x = (lamp[0] - lin0[0]) / p3[0];
+        y = (lamp[1] - lin0[1] - p3[1]*x) / -q3[1];
+      }
+    }
+    else if(abs(q3[1]) < EPSILON){
+      if(abs(p3[1]) > EPSILON){
+        x = (lamp[1] - lin0[1]) / p3[1];
+        y = (lamp[0] - lin0[0] - p3[0]*x) / -q3[0];
+      }
+    }
+    else{
+      if(abs(tmp) > EPSILON){
+        x = ((lamp[0]-lin0[0])*q3[1] - (lamp[1]-lin0[1])*q3[0]) / tmp;
+        y = (lamp[0] - lin0[0] - p3[0]*x) / -q3[0];
+      }
+    }
+
+    if(x>-EPSILON && x-1<EPSILON && y>-EPSILON && y-1<-EPSILON){
+      if(x<EPSILON) hit_vertex = 0;
+      else if(x-1>-EPSILON) hit_vertex = 1;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+//----------------------------------------< intersection_line_triangle_2d >
+bool intersection_line_triangle_2d(double lin0[], double lin1[],
+                                   double tri0[], double tri1[], double tri2[]){
+  if(point_in_triangle_generous_2d(lin0, tri0, tri1, tri2)){
+    return true;
+  }
+  if(point_in_triangle_generous_2d(lin1, tri0, tri1, tri2)){
+    return true;
+  }
+
+  long hit_vertex;
+  if(intersection_line_line_2d(tri0, tri1, lin0, lin1, hit_vertex)){
+    return true;
+  }
+  if(intersection_line_line_2d(tri1, tri2, lin0, lin1, hit_vertex)){
+    return true;
+  }
+  if(intersection_line_line_2d(tri2, tri0, lin0, lin1, hit_vertex)){
+    return true;
+  }
+
+  return false;
+}
+
+//----------------------------------------< intersection_line_box_2d >
+bool intersection_line_box_2d(double lin0[], double lin1[],
+			      double min_corner[], double max_corner[]){
+  double p0[2];
+  double p1[2];
+  p0[0] = min_corner[0]; p0[1] = max_corner[1];
+  p1[0] = max_corner[0]; p1[1] = min_corner[1]; 
+  
+  long hit_vertex;
+  if (intersection_line_line_2d(lin0,lin1,min_corner,p0,hit_vertex))
+    return true;
+  if (intersection_line_line_2d(lin0,lin1,min_corner,p1,hit_vertex))
+    return true;
+  if (intersection_line_line_2d(lin0,lin1,max_corner,p0,hit_vertex))
+    return true;
+  if (intersection_line_line_2d(lin0,lin1,max_corner,p1,hit_vertex))
+    return true;
+  
+  return false;
+}
+
+//----------------------------------------< intersection_box_box_2d >
+bool intersection_box_box_2d(double min_corner0[], double max_corner0[],
+			     double min_corner1[], double max_corner1[]){
+  double p[2];
+  
+  if (edge_length_2d(min_corner0,max_corner0) < edge_length_2d(min_corner1,max_corner1)) {
+  // box0 is smaller than box1
+    if (point_in_box_2d(min_corner0, min_corner1, max_corner1))
+      return true;
+    if (point_in_box_2d(max_corner0, min_corner1, max_corner1))
+      return true;
+    
+    p[0] = min_corner0[0]; p[1] = max_corner0[1];
+    if (point_in_box_2d(p, min_corner1, max_corner1))
+      return true;
+    
+    p[0] = max_corner0[0]; p[1] = min_corner0[1];    
+    if (point_in_box_2d(p, min_corner1, max_corner1))
+      return true;
+  } else {
+  // box1 is smaller than box0
+    if (point_in_box_2d(min_corner1, min_corner0, max_corner0))
+      return true;
+    if (point_in_box_2d(max_corner1, min_corner0, max_corner0))
+      return true;
+    
+    p[0] = min_corner1[0]; p[1] = max_corner1[1];
+    if (point_in_box_2d(p, min_corner0, max_corner0))
+      return true;
+    
+    p[0] = max_corner1[0]; p[1] = min_corner1[1];    
+    if (point_in_box_2d(p, min_corner0, max_corner0))
+      return true;
+  }
+}
+
+//----------------------------------------< intersection_triangle_box_2d >
+bool intersection_triangle_box_2d(double tri0[], double tri1[], double tri2[],
+				  double min_corner[], double max_corner[]){
+  // vertices of triangle covered by box
+  if (point_in_box_generous_2d(tri0,min_corner,max_corner))
+    return true;
+  if (point_in_box_generous_2d(tri1,min_corner,max_corner))
+    return true;
+  if (point_in_box_generous_2d(tri2,min_corner,max_corner))
+    return true;
+  
+  // bounding box of triangle does not intersect the box
+  double p0[2];
+  double p1[2];
+  boundingbox_triangle_2d(tri0,tri1,tri2,p0,p1);
+  if (!intersection_box_box_2d(min_corner,max_corner,p0,p1))
+    return false;
+  
+  // vertices of box covered by triangle
+  if (point_in_triangle_generous_2d(min_corner, tri0, tri1, tri2))
+    return true;
+  if (point_in_triangle_generous_2d(max_corner, tri0, tri1, tri2))
+    return true;
+  
+  p0[0] = min_corner[0]; p0[1] = max_corner[1];
+  if (point_in_triangle_generous_2d(p0, tri0, tri1, tri2))
+    return true;
+  
+  p1[0] = max_corner[0]; p1[1] = min_corner[1]; 
+  if (point_in_triangle_generous_2d(p1, tri0, tri1, tri2))
+    return true;
+  
+  // edges of triangle intersect box
+  if (intersection_line_box_2d(tri0,tri1,min_corner,max_corner))
+    return true;
+  if (intersection_line_box_2d(tri1,tri2,min_corner,max_corner))
+    return true;
+  if (intersection_line_box_2d(tri2,tri0,min_corner,max_corner))
+    return true;
+  
+  return false;
+}
+
+//----------------------------------------< distance_point_line_2d >
+//calculates the distance between a given point and the line segment between 'lin0' and 'lin1'.
+double distance_point_line_2d(double point[], double lin0[], double lin1[]){
+  double gx, gy, fx, fy, dx, dy, t;
+  //the (complete) line through 'lin0' and 'lin1' is given by 'l = lin0 + t*g' with g as follows:
+  gx = lin1[0] - lin0[0];
+  gy = lin1[1] - lin0[1];
+
+  //the normal-vector from 'point' to l is 'v = lin0 + t*g - point' for some t which is determined
+  // by 'v*g = 0'
+  t = (-gx * (lin0[0]-point[0]) - gy * (lin0[1]-point[1])) / (gx*gx + gy*gy);
+
+  //if the orthogonal projection of 'point' onto l is not on the given line segment then one of the
+  //vertices 'lin0' or 'lin1' is the nearest point to 'point'
+  if(t<0){
+    //'lin0' is nearest
+    fx = lin0[0];
+    fy = lin0[1];
+  }
+  else if(t>1){
+    //'lin1' is nearest
+    fx = lin1[0];
+    fy = lin1[1];
+  }
+  else{
+    //orthogonal projection is nearest
+    fx = lin0[0] + t * gx;
+    fy = lin0[1] + t * gy;
+  }
+
+  //calculate distance
+  dx = point[0] - fx;
+  dy = point[1] - fy;
+  return sqrt(dx*dx + dy*dy);
+}
+
+//----------------------------------------< distance_point_line_with_intersection_2d >
+//calculates the distance between a given point and the line-segment between 'lin0' and 'lin1'.
+//This version also returns the intersection-point of the perpendicular with the given line-segment.
+double distance_point_line_with_intersection_2d(double point[], double lin0[], double lin1[],
+                                                                           double intersection[]){
+  double gx, gy, dx, dy, t;
+  //the (complete) line through 'lin0' and 'lin1' is given by 'l = lin0 + t*g' with g as follows:
+  gx = lin1[0] - lin0[0];
+  gy = lin1[1] - lin0[1];
+
+  //the normal-vector from 'point' to l is 'v = lin0 + t*g - point' for some t which is determined
+  // by 'v*g = 0'
+  t = (-gx * (lin0[0]-point[0]) - gy * (lin0[1]-point[1])) / (gx*gx + gy*gy);
+
+  //if the orthogonal projection of 'point' onto l is not on the given line segment then one of the
+  //vertices 'lin0' or 'lin1' is the nearest point to 'point'
+  if(t<0){
+    //'lin0' is nearest
+    intersection[0] = lin0[0];
+    intersection[1] = lin0[1];
+  }
+  else if(t>1){
+    //'lin1' is nearest
+    intersection[0] = lin1[0];
+    intersection[1] = lin1[1];
+  }
+  else{
+    //orthogonal projection is nearest
+    intersection[0] = lin0[0] + t * gx;
+    intersection[1] = lin0[1] + t * gy;
+  }
+
+  //calculate distance
+  dx = point[0] - intersection[0];
+  dy = point[1] - intersection[1];
+  return sqrt(dx*dx + dy*dy);
+}
+
+
+//----------------------------------------< distance_point_box_2d >
+double distance_point_box_2d(double point[], double min_corner[], double max_corner[]){
+  if (point_in_box_2d(point,min_corner,max_corner))
+    return 0.0;
+  
+  double p[2];
+  double dist = edge_length_2d(point, min_corner);  
+  dist = std::min(dist, edge_length_2d(point, min_corner)); 
+  p[0] = min_corner[0]; p[1] = max_corner[1];
+  dist = std::min(dist, edge_length_2d(point, p));   
+  p[0] = max_corner[0]; p[1] = min_corner[1];    
+  dist = std::min(dist, edge_length_2d(point, p));
+  
+  return dist;
+}
+
+//----------------------------------------< distance_point_triangle_2d >
+double distance_point_triangle_2d(double point[], double tri0[], double tri1[], double tri2[]){
+  if (point_in_triangle_2d(point,tri0,tri1,tri2))
+    return 0.0;
+  
+  double dist = edge_length_2d(point, tri0);  
+  dist = std::min(dist, edge_length_2d(point, tri1)); 
+  dist = std::min(dist, edge_length_2d(point, tri2));
+  
+  return dist;
+}
+
+bool point_in_polygon(double point[], const std::vector<AMDiS::WorldVector<double> > &vertices) {
+  bool inside = false;
+
+  int i, j;
+  for (i = 0, j = vertices.size()-1; i < vertices.size(); j = i++) {
+    if ((((vertices[i][1] <= point[1]) && (point[1] < vertices[j][1])) ||
+         ((vertices[j][1] <= point[1]) && (point[1] < vertices[i][1]))) &&
+        (point[0] < (vertices[j][0] - vertices[i][0]) * (point[1] - vertices[i][1]) / (vertices[j][1] - vertices[i][1]) + vertices[i][0]))
+      inside = !inside;
+  }
+
+  return inside;
+}
+
+//                                      #################
+//                                      ##  3D Worlds  ##
+//                                      #################
+
+//----------------------------------------< points_identical_3d >
+bool points_identical_3d(double p1[], double p2[]){
+  long i;
+
+  for(i=0; i<3; ++i){
+    if(abs(p1[i] - p2[i]) > EPSILON) break;
+  }
+  if(i == 3){
+    return true;
+  }else{
+    return false;
+  }
+}
+
+//----------------------------------------< normal_vector_3d >
+void normal_vector_3d(double tri0[], double tri1[], double tri2[], double normal[]){
+  long i;
+  double p[3], q[3];
+
+  for(i=0; i<3; ++i) p[i] = tri0[i] - tri1[i];
+  for(i=0; i<3; ++i) q[i] = tri0[i] - tri2[i];
+  normal[0] = p[1] * q[2] - p[2] * q[1];
+  normal[1] = p[2] * q[0] - p[0] * q[2];
+  normal[2] = p[0] * q[1] - p[1] * q[0];
+}
+
+//----------------------------------------< triangle_area_3d >
+double triangle_area_3d(double tri0[], double tri1[], double tri2[]){
+  long i;
+  double p[3], q[3], n[3];
+
+  for(i=0; i<3; ++i) p[i] = tri0[i] - tri1[i];
+  for(i=0; i<3; ++i) q[i] = tri0[i] - tri2[i];
+  n[0] = p[1] * q[2] - p[2] * q[1];
+  n[1] = p[2] * q[0] - p[0] * q[2];
+  n[2] = p[0] * q[1] - p[1] * q[0];
+  return sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]) / 2;
+}
+
+//----------------------------------------< edge_length_3d >
+double edge_length_3d(double lin0[], double lin1[]){
+  long i;
+  double p[3];
+
+  for(i=0; i<3; ++i) p[i] = lin0[i] - lin1[i];
+  return sqrt(p[0] * p[0] + p[1] * p[1] + p[2] * p[2]);
+}
+
+//----------------------------------------< triangle_max_edge_length_3d >
+double triangle_max_edge_length_3d(double tri0[], double tri1[], double tri2[]){
+  long i;
+  double p[3], max_el, a;
+
+  for(i=0; i<3; ++i) p[i] = tri0[i] - tri1[i];
+  a = p[0] * p[0] + p[1] * p[1] + p[2] * p[2];
+  max_el = a;
+
+  for(i=0; i<3; ++i) p[i] = tri1[i] - tri2[i];
+  a = p[0] * p[0] + p[1] * p[1] + p[2] * p[2];
+  if(a > max_el) max_el = a;
+
+  for(i=0; i<3; ++i) p[i] = tri2[i] - tri0[i];
+  a = p[0] * p[0] + p[1] * p[1] + p[2] * p[2];
+  if(a > max_el) max_el = a;
+
+  return sqrt(max_el);
+}
+
+//----------------------------------------< unit_normal_vector_3d >
+void unit_normal_vector_3d(double tri0[], double tri1[], double tri2[], double normal[]){
+  long i;
+  double b;
+  double p[3], q[3];
+
+  for(i=0; i<3; ++i) p[i] = tri0[i] - tri1[i];
+  for(i=0; i<3; ++i) q[i] = tri0[i] - tri2[i];
+  normal[0] = p[1] * q[2] - p[2] * q[1];
+  normal[1] = p[2] * q[0] - p[0] * q[2];
+  normal[2] = p[0] * q[1] - p[1] * q[0];
+  b = sqrt(normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2]);
+  for(i=0; i<3; ++i) normal[i] /= b;
+}
+
+//----------------------------------------< degenerate_triangle_3d >
+bool degenerate_triangle_3d(double tri0[], double tri1[], double tri2[]){
+  long i;
+  double p[3], q[3], n[3];
+
+  for(i=0; i<3; ++i) p[i] = tri0[i] - tri1[i];
+  for(i=0; i<3; ++i) q[i] = tri0[i] - tri2[i];
+  n[0] = p[1] * q[2] - p[2] * q[1];
+  n[1] = p[2] * q[0] - p[0] * q[2];
+  n[2] = p[0] * q[1] - p[1] * q[0];
+  if(abs(n[0])<EPSILON && abs(n[1])<EPSILON && abs(n[2])<EPSILON){
+    return true;
+  }else{
+    return false;
+  }
+}
+
+//----------------------------------------< boundingbox_triangle_3d >
+void boundingbox_triangle_3d(double tri0[], double tri1[], double tri2[],
+			     double min_corner[], double max_corner[]){
+  min_corner[0] = std::min(std::min(tri0[0],tri1[0]),tri2[0]);
+  min_corner[1] = std::min(std::min(tri0[1],tri1[1]),tri2[1]);
+  min_corner[2] = std::min(std::min(tri0[2],tri1[2]),tri2[2]);
+  max_corner[0] = std::max(std::max(tri0[0],tri1[0]),tri2[0]);
+  max_corner[1] = std::max(std::max(tri0[1],tri1[1]),tri2[1]);
+  max_corner[2] = std::max(std::max(tri0[2],tri1[2]),tri2[2]);
+}
+
+//----------------------------------------< centroid_of_box_3d >
+void centroid_of_box_3d(double min_corner[], double max_corner[], double c[]){
+  c[0] = 0.5*(max_corner[0]+min_corner[0]);
+  c[1] = 0.5*(max_corner[1]+min_corner[1]);
+  c[2] = 0.5*(max_corner[2]+min_corner[2]);
+}
+
+//----------------------------------------< centroid_of_triangle_3d >
+void centroid_of_triangle_3d(double tri0[], double tri1[], double tri2[], double c[]){
+  c[0] = (tri0[0]+tri1[0],tri2[0])/3.0;
+  c[1] = (tri0[1]+tri1[1],tri2[1])/3.0;
+  c[2] = (tri0[2]+tri1[2],tri2[2])/3.0;
+}
+
+//----------------------------------------< point_in_box_3d >
+bool point_in_box_3d(double p[], double min_corner[], double max_corner[]){
+  
+  return (p[0] >= min_corner[0]) && (p[0] <= max_corner[0]) &&
+	 (p[1] >= min_corner[1]) && (p[1] <= max_corner[1]) &&
+	 (p[2] >= min_corner[2]) && (p[2] <= max_corner[2]);
+}
+
+//----------------------------------------< point_in_box_generous_3d >
+bool point_in_box_generous_3d(double p[], double min_corner[], double max_corner[]){
+  
+  return (p[0]-min_corner[0] >= -EPSILON) && (p[0]-max_corner[0] <= EPSILON) &&
+	 (p[1]-min_corner[1] >= -EPSILON) && (p[1]-max_corner[1] <= EPSILON) &&
+	 (p[2]-min_corner[2] >= -EPSILON) && (p[2]-max_corner[2] <= EPSILON);
+}
+
+//----------------------------------------< point_in_tetrahedron_3d >
+bool point_in_tetrahedron_3d(double p[], double a[], double b[], double c[], double d[]){
+  double d0, d1, d2, d3, d4;
+
+  d0 = solve_determinant4(a[0], a[1], a[2], 1.0, b[0], b[1], b[2], 1.0,
+                          c[0], c[1], c[2], 1.0, d[0], d[1], d[2], 1.0);
+  d1 = solve_determinant4(p[0], p[1], p[2], 1.0, b[0], b[1], b[2], 1.0,
+                          c[0], c[1], c[2], 1.0, d[0], d[1], d[2], 1.0);
+  d2 = solve_determinant4(a[0], a[1], a[2], 1.0, p[0], p[1], p[2], 1.0,
+                          c[0], c[1], c[2], 1.0, d[0], d[1], d[2], 1.0);
+  d3 = solve_determinant4(a[0], a[1], a[2], 1.0, b[0], b[1], b[2], 1.0,
+                          p[0], p[1], p[2], 1.0, d[0], d[1], d[2], 1.0);
+  d4 = solve_determinant4(a[0], a[1], a[2], 1.0, b[0], b[1], b[2], 1.0,
+                          c[0], c[1], c[2], 1.0, p[0], p[1], p[2], 1.0);
+  //if(d0>=0.0){
+  //  return (d1>=0.0 && d2>=0.0 && d3>=0.0 && d4>=0.0);
+  //}else{
+  //  return (d1<=0.0 && d2<=0.0 && d3<=0.0 && d4<=0.0);
+  //}
+  //the following code is highly experimental and should not be trusted!
+  if(d0>=0.0){
+    return (d1>=-EPSILON && d2>=-EPSILON && d3>=-EPSILON && d4>=-EPSILON);
+  }else{
+    return (d1<=EPSILON && d2<=EPSILON && d3<=EPSILON && d4<=EPSILON);
+  }
+}
+
+//----------------------------------------< intersection_line_line_3d >
+bool intersection_line_line_3d(double p1[], double p2[], double p3[], double p4[]){
+  double p13[3], p43[3], p21[3];
+  double d1343, d4321, d1321, d4343, d2121;
+  double numer, denom;
+  double mua, mub;
+
+  p13[0] = p1[0] - p3[0];
+  p13[1] = p1[1] - p3[1];
+  p13[2] = p1[2] - p3[2];
+  p43[0] = p4[0] - p3[0];
+  p43[1] = p4[1] - p3[1];
+  p43[2] = p4[2] - p3[2];
+  p21[0] = p2[0] - p1[0];
+  p21[1] = p2[1] - p1[1];
+  p21[2] = p2[2] - p1[2];
+
+  //test for collinearity
+  if( abs(p21[1]*p43[2] - p21[2]*p43[1]) < EPSILON
+      && abs(p21[2]*p43[0] - p21[0]*p43[2]) < EPSILON
+      && abs(p21[0]*p43[1] - p21[1]*p43[0]) < EPSILON ){
+    //lines are collinear; now test for an intersection
+    double x11, x12, x21, x22, y11, y12, y21, y22, z11, z12, z21, z22;
+    if(p1[0]<=p2[0]){
+      x11 = p1[0];
+      x12 = p2[0];
+    }
+    else{
+      x11 = p2[0];
+      x12 = p1[0];
+    }
+    if(p1[1]<=p2[1]){
+      y11 = p1[1];
+      y12 = p2[1];
+    }
+    else{
+      y11 = p2[1];
+      y12 = p1[1];
+    }
+    if(p1[2]<=p2[2]){
+      z11 = p1[2];
+      z12 = p2[2];
+    }
+    else{
+      z11 = p2[2];
+      z12 = p1[2];
+    }
+    if(p3[0]<=p4[0]){
+      x21 = p3[0];
+      x22 = p4[0];
+    }
+    else{
+      x21 = p4[0];
+      x22 = p3[0];
+    }
+    if(p3[1]<=p4[1]){
+      y21 = p3[1];
+      y22 = p4[1];
+    }
+    else{
+      y21 = p4[1];
+      y22 = p3[1];
+    }
+    if(p3[2]<=p4[2]){
+      z21 = p3[2];
+      z22 = p4[2];
+    }
+    else{
+      z21 = p4[2];
+      z22 = p3[2];
+    }
+    if(x11<=x22 && x12>=x21 && y11<=y22 && y12>=y21 && z11<=z22 && z12>=z21){
+      if(abs(p21[0]) > EPSILON){
+        mua = -p13[0]/p21[0];
+        if(abs(p1[1] + p21[1]*mua - p3[1]) < EPSILON && abs(p1[2] + p21[2]*mua - p3[2]) < EPSILON){
+          return true;
+        }
+      }else if(abs(p21[1]) > EPSILON){
+        mua = -p13[1]/p21[1];
+        if(abs(p1[0] + p21[0]*mua - p3[0]) < EPSILON && abs(p1[2] + p21[2]*mua - p3[2]) < EPSILON){
+          return true;
+        }
+      }else{
+        mua = -p13[2]/p21[2];
+        if(abs(p1[0] + p21[0]*mua - p3[0]) < EPSILON && abs(p1[1] + p21[1]*mua - p3[1]) < EPSILON){
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  d1343 = p13[0] * p43[0] + p13[1] * p43[1] + p13[2] * p43[2];
+  d4321 = p43[0] * p21[0] + p43[1] * p21[1] + p43[2] * p21[2];
+  d1321 = p13[0] * p21[0] + p13[1] * p21[1] + p13[2] * p21[2];
+  d4343 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2];
+  d2121 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2];
+
+  denom = d2121 * d4343 - d4321 * d4321;
+  if(abs(denom) < EPSILON){
+    return false;
+  }
+  numer = d1343 * d4321 - d1321 * d4343;
+
+  mua = numer / denom;
+  mub = (d1343 + d4321 * mua) / d4343;
+
+  if(mua<-EPSILON || mua-1>EPSILON || mub<-EPSILON || mub-1>EPSILON){
+    return false;
+  }
+  if(abs(p1[0] + mua * p21[0] - p3[0] - mub * p43[0]) < EPSILON
+         && abs(p1[1] + mua * p21[1] - p3[1] - mub * p43[1]) < EPSILON
+         && abs(p1[2] + mua * p21[2] - p3[2] - mub * p43[2]) < EPSILON){
+    return true;
+  }else{
+    return false;
+  }
+}
+
+//----------------------------------------< intersection_line_line_with_intersection_3d >
+bool intersection_line_line_with_intersection_3d(double p1[], double p2[], double p3[], double p4[],
+                                                                               double intersection[]){
+  double p13[3], p43[3], p21[3];
+  double d1343, d4321, d1321, d4343, d2121;
+  double numer, denom;
+  double mua, mub;
+  int ci = -1;
+
+  p13[0] = p1[0] - p3[0];
+  p13[1] = p1[1] - p3[1];
+  p13[2] = p1[2] - p3[2];
+  p43[0] = p4[0] - p3[0];
+  p43[1] = p4[1] - p3[1];
+  p43[2] = p4[2] - p3[2];
+  p21[0] = p2[0] - p1[0];
+  p21[1] = p2[1] - p1[1];
+  p21[2] = p2[2] - p1[2];
+
+  //test for collinearity
+  if( abs(p21[1]*p43[2] - p21[2]*p43[1]) < EPSILON
+      && abs(p21[2]*p43[0] - p21[0]*p43[2]) < EPSILON
+      && abs(p21[0]*p43[1] - p21[1]*p43[0]) < EPSILON ){
+    //lines are collinear; now test for an intersection
+    double x11, x12, x21, x22, y11, y12, y21, y22, z11, z12, z21, z22;
+    if(p1[0]<=p2[0]){
+      x11 = p1[0];
+      x12 = p2[0];
+    }
+    else{
+      x11 = p2[0];
+      x12 = p1[0];
+    }
+    if(p1[1]<=p2[1]){
+      y11 = p1[1];
+      y12 = p2[1];
+    }
+    else{
+      y11 = p2[1];
+      y12 = p1[1];
+    }
+    if(p1[2]<=p2[2]){
+      z11 = p1[2];
+      z12 = p2[2];
+    }
+    else{
+      z11 = p2[2];
+      z12 = p1[2];
+    }
+    if(p3[0]<=p4[0]){
+      x21 = p3[0];
+      x22 = p4[0];
+    }
+    else{
+      x21 = p4[0];
+      x22 = p3[0];
+    }
+    if(p3[1]<=p4[1]){
+      y21 = p3[1];
+      y22 = p4[1];
+    }
+    else{
+      y21 = p4[1];
+      y22 = p3[1];
+    }
+    if(p3[2]<=p4[2]){
+      z21 = p3[2];
+      z22 = p4[2];
+    }
+    else{
+      z21 = p4[2];
+      z22 = p3[2];
+    }
+    if(x11<=x22 && x12>=x21 && y11<=y22 && y12>=y21 && z11<=z22 && z12>=z21){
+      if(abs(p21[0]) > EPSILON){
+        mua = -p13[0] / p21[0];
+        if(abs(p1[1] + p21[1]*mua - p3[1]) < EPSILON && abs(p1[2] + p21[2]*mua - p3[2]) < EPSILON) ci = 0;
+      }else if(abs(p21[1]) > EPSILON){
+        mua = -p13[1] / p21[1];
+        if(abs(p1[0] + p21[0]*mua - p3[0]) < EPSILON && abs(p1[2] + p21[2]*mua - p3[2]) < EPSILON) ci = 1;
+      }else{
+        mua = -p13[2] / p21[2];
+        if(abs(p1[0] + p21[0]*mua - p3[0]) < EPSILON && abs(p1[1] + p21[1]*mua - p3[1]) < EPSILON) ci = 2;
+      }
+      if(ci != -1){
+        //determine best intersection-point
+        //priority is p3(*) > p4 > p3 > p2 (one of these three points must be part of both line segments
+        //(*): p3 is only priorized over p4 if it is not a vertex of the first line segment
+        if(mua > EPSILON && mua-1< -EPSILON){
+          intersection[0] = p3[0];
+          intersection[1] = p3[1];
+          intersection[2] = p3[2];
+        }else{
+          mub = (p4[ci]-p1[ci]) / p21[ci];
+          if(mub > -EPSILON && mub-1 < EPSILON){
+            intersection[0] = p4[0];
+            intersection[1] = p4[1];
+            intersection[2] = p4[2];
+          }else if(mua > -EPSILON && mua-1 < EPSILON){
+            intersection[0] = p3[0];
+            intersection[1] = p3[1];
+            intersection[2] = p3[2];
+          }else{
+            intersection[0] = p2[0];
+            intersection[1] = p2[1];
+            intersection[2] = p2[2];
+          }
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
+  d1343 = p13[0] * p43[0] + p13[1] * p43[1] + p13[2] * p43[2];
+  d4321 = p43[0] * p21[0] + p43[1] * p21[1] + p43[2] * p21[2];
+  d1321 = p13[0] * p21[0] + p13[1] * p21[1] + p13[2] * p21[2];
+  d4343 = p43[0] * p43[0] + p43[1] * p43[1] + p43[2] * p43[2];
+  d2121 = p21[0] * p21[0] + p21[1] * p21[1] + p21[2] * p21[2];
+
+  denom = d2121 * d4343 - d4321 * d4321;
+  if(abs(denom) < EPSILON){
+    return false;
+  }
+  numer = d1343 * d4321 - d1321 * d4343;
+
+  mua = numer / denom;
+  mub = (d1343 + d4321 * mua) / d4343;
+  if(mua<-EPSILON || mua-1>EPSILON || mub<-EPSILON || mub-1>EPSILON){
+    return false;
+  }
+
+  //determine potential intersection-point
+  intersection[0] = p1[0] + mua * p21[0];
+  intersection[1] = p1[1] + mua * p21[1];
+  intersection[2] = p1[2] + mua * p21[2];
+
+  //check if this really is an intersection
+  if(abs(intersection[0] - p3[0] - mub * p43[0]) < EPSILON
+         && abs(intersection[1] - p3[1] - mub * p43[1]) < EPSILON
+         && abs(intersection[2] - p3[2] - mub * p43[2]) < EPSILON){
+    return true;
+  }else{
+    return false;
+  }
+}
+
+//----------------------------------------< intersection_line_triangle_3d_chirkov >
+//ATTENTION: function does not work for lines almost in the plane of the triangle!
+//calculates the intersection of a line segment and a triangle if it exists. The intersection-point is not
+//calculated, the last argument "sol" remains unchanged.
+//    input:  a line segment (lin0, lin1), and a triangle (tri0, tri1, tri2)
+//    return: 0      disjoint
+//            1      intersection inside triangle
+//            2,3,4  intersection in edge of triangle (edge_index is 0, 1, 2 respectively)
+//this algorithm is based on an implementation by Nick Chirkov (journal of graphics tools 10(3):13-18, 2005).
+int intersection_line_triangle_3d(double tri0[], double tri1[], double tri2[],
+                                            double lin0[], double lin1[], double sol[]){
+  long i, type;
+  double org[3];
+  double end[3];
+  double dir[3];
+  double x, y, z, d;
+
+  //cube-collision-detection to determine necessity of real intersection check
+  //note: this does not seem to improve performance unfortunately.
+  //double p3[3],q3[3],p4[3],q4[3];
+  //for(i=0; i<3; ++i){
+  //  if(tri0[i] <= tri1[i]){
+  //    if(tri0[i] <= tri2[i]){
+  //      p3[i] = tri0[i];
+  //      q3[i] = ((tri1[i]>=tri2[i])? tri1[i] : tri2[i]);
+  //    }
+  //    else{
+  //      p3[i] = tri2[i];
+  //      q3[i] = tri1[i];
+  //    }
+  //  }
+  //  else{
+  //    if(tri1[i] <= tri2[i]){
+  //      p3[i] = tri1[i];
+  //      q3[i] = ((tri0[i]>=tri2[i])? tri2[i] : tri0[i]);
+  //    }
+  //    else{
+  //      p3[i] = tri2[i];
+  //      q3[i] = tri0[i];
+  //    }
+  //  }
+  //  if(lin0[i] <= lin1[i]){
+  //    p4[i] = lin0[i];
+  //    q4[i] = lin1[i];
+  //  }
+  //  else{
+  //    p4[i] = lin1[i];
+  //    q4[i] = lin0[i];
+  //  }
+  //}
+  //if(p3[0]>q4[0] || q3[0]<p4[0] || p3[1]>q4[1] || q3[1]<p4[1] || p3[2]>q4[2] || q3[2]<p4[2]){
+  //  return 0;
+  //}
+
+  double ax = tri1[0] - tri0[0];
+  double ay = tri1[1] - tri0[1];
+  double az = tri1[2] - tri0[2];
+  double bx = tri2[0] - tri0[0];
+  double by = tri2[1] - tri0[1];
+  double bz = tri2[2] - tri0[2];
+  x = ay * bz - az * by;
+  y = az * bx - ax * bz;
+  z = ax * by - ay * bx;
+  d = x*tri0[0] + y*tri0[1] + z*tri0[2];
+
+  static const double SQ = sqrt(1.0/3.0);
+  double len = (x*x + y*y + z*z)*SQ;
+
+  if(fabs(x)>len) type = 1;
+  else if(fabs(y)>len) type = 2;
+  else type = 3;
+
+  for(i=0;i<=2;i++){
+    org[i] = lin0[i]; //todo: org can be replaced by lin0 throughout the whole function
+    end[i] = lin1[i]; //todo: replace end by lin1
+    dir[i] = end[i] - org[i];
+  }
+
+  //determine intersection
+  double signSrc = x*org[0] + y*org[1] + z*org[2] - d;
+  double signDst = x*end[0] + y*end[1] + z*end[2] - d;
+  if(signSrc*signDst > 0.0){
+    return 0;
+  }
+
+  double di = signSrc - signDst;
+
+  if(type == 1){
+    double basey = org[1] - tri0[1];
+    double basez = org[2] - tri0[2];
+    double adelx = signSrc*(ay * dir[2] - az * dir[1]);
+    if((adelx + di * (ay*basez-az*basey))
+              * (signSrc*(dir[1]*bz-dir[2]*by) + di * (basey*bz-basez*by)) > 0.0){
+      double e2y = tri1[1] - tri2[1];
+      double e2z = tri1[2] - tri2[2];
+      basey = org[1] - tri1[1];
+      basez = org[2] - tri1[2];
+      if((adelx + di * (ay*basez-az*basey))
+              * (signSrc*(dir[1]*e2z-dir[2]*e2y) + di * (basey*e2z-basez*e2y)) > 0.0){
+        goto test_edges;
+      }
+    }
+  }
+  else if(type == 2){
+    double basex = org[0] - tri0[0];
+    double basez = org[2] - tri0[2];
+    double adely = signSrc*(az * dir[0] - ax * dir[2]);
+    if((adely + di * (az*basex-ax*basez))
+                 * (signSrc*(dir[2]*bx-dir[0]*bz) + di * (basez*bx-basex*bz)) > 0.0){
+      double e2x = tri1[0] - tri2[0];
+      double e2z = tri1[2] - tri2[2];
+      basex = org[0] - tri1[0];
+      basez = org[2] - tri1[2];
+      if((adely + di * (az*basex-ax*basez))
+                 * (signSrc*(dir[2]*e2x-dir[0]*e2z) + di * (basez*e2x-basex*e2z)) > 0.0){
+        goto test_edges;
+      }
+    }
+  }
+  else{
+    double basex = org[0] - tri0[0];
+    double basey = org[1] - tri0[1];
+    double adelz = signSrc*(ax * dir[1] - ay * dir[0]);
+    if((adelz + di * (ax*basey-ay*basex))
+                   * (signSrc*(dir[0]*by-dir[1]*bx) + di * (basex*by-basey*bx)) > 0.0){
+      double e2x = tri1[0] - tri2[0];
+      double e2y = tri1[1] - tri2[1];
+      basex = org[0] - tri1[0];
+      basey = org[1] - tri1[1];
+      if((adelz + di * (ax*basey-ay*basex))
+                   * (signSrc*(dir[0]*e2y-dir[1]*e2x) + di * (basex*e2y-basey*e2x)) > 0.0){
+        goto test_edges;
+      }
+    }
+  }
+
+  return 0;
+
+  test_edges:;
+  if(intersection_line_line_3d(tri0, tri1, lin0, lin1)){
+    return 4;
+  }else if(intersection_line_line_3d(tri1, tri2, lin0, lin1)){
+    return 2;
+  }else if(intersection_line_line_3d(tri2, tri0, lin0, lin1)){
+    return 3;
+  }
+  return 1;
+}
+
+//----------------------------------------< intersection_line_triangle_3d_softsurfer >
+// Copyright 2001, softSurfer (www.softsurfer.com)
+// This code may be freely used and modified for any purpose
+// providing that this copyright notice is included with it.
+// SoftSurfer makes no warranty for this code, and cannot be held
+// liable for any real or imagined damage resulting from its use.
+// Users of this code must verify correctness for their application.
+
+//calculates the intersection point of a line segment and a triangle if it exists
+//    input:  a line segment (lin0, lin1), and a triangle (tri0, tri1, tri2)
+//    output: sol = intersection point (if it exists)
+//    return: 0      disjoint
+//            1      intersection inside triangle
+//            2,3,4  intersection in edge of triangle (edge_index is 0, 1, 2 respectively)
+int intersection_line_triangle_3d_softsurfer(double tri0[], double tri1[], double tri2[],
+                                    double lin0[], double lin1[], double sol[]){
+  double u[3], v[3], n[3];    //triangle vectors
+  double dir[3], w0[3], w[3]; //ray vectors
+  double r, a, b;             //params to calc ray-plane intersect
+  long i, e;
+  double EPSILON2 = 100 * EPSILON;
+
+  double uu, uv, vv, wu, wv, D;
+  double s, t;
+  double distances[3];
+
+  //get triangle edge vectors and plane normal
+  for(i=0; i<3; i++) u[i] = tri1[i] - tri0[i];
+  for(i=0; i<3; i++) v[i] = tri2[i] - tri0[i];
+  n[0] = u[1]*v[2] - u[2]*v[1];
+  n[1] = u[2]*v[0] - u[0]*v[2];
+  n[2] = u[0]*v[1] - u[1]*v[0];
+  if(abs(n[0])<EPSILON && abs(n[1])<EPSILON && abs(n[2])<EPSILON){
+    if(intersection_line_line_with_intersection_3d(tri0, tri1, lin0, lin1, sol)){
+      return 4;
+    }else if(intersection_line_line_with_intersection_3d(tri1, tri2, lin0, lin1, sol)){
+      return 2;
+    }else if(intersection_line_line_with_intersection_3d(tri2, tri0, lin0, lin1, sol)){
+      return 3;
+    }
+  }
+
+  for(i=0; i<3; i++) dir[i] = lin1[i] - lin0[i]; //line direction vector
+  for(i=0; i<3; i++) w0[i] = lin0[i] - tri0[i];
+  a = -(n[0] * w0[0] + n[1] * w0[1] + n[2] * w0[2]);
+  b = n[0] * dir[0] + n[1] * dir[1] + n[2] * dir[2];
+  if(abs(b) < EPSILON){ //ray is parallel to triangle plane
+    if(abs(a) < EPSILON){
+      //test whether one of the line's vertices lies inside the triangle
+      for(e=0; e<2; e++){
+        if(e==0) for(i=0; i<3; i++) sol[i] = lin0[i];
+        else for(i=0; i<3; i++) sol[i] = lin1[i];
+
+        uu = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
+        uv = u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
+        vv = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+        for(i=0; i<3; i++) w[i] = sol[i] - tri0[i];
+
+        wu = w[0] * u[0] + w[1] * u[1] + w[2] * u[2];
+        wv = w[0] * v[0] + w[1] * v[1] + w[2] * v[2];
+        D = uv * uv - uu * vv;
+
+        s = (uv * wv - vv * wu) / D;
+        if (s < -EPSILON || s-1.0 > EPSILON) continue; //sol is outside triangle
+        t = (uv * wu - uu * wv) / D;
+        if (t < -EPSILON || (s + t-1.0) > EPSILON) continue; //sol is outside triangle
+
+        distances[0] = distance_point_line_3d(sol, tri0, tri1);
+        distances[1] = distance_point_line_3d(sol, tri1, tri2);
+        distances[2] = distance_point_line_3d(sol, tri2, tri0);
+        if(distances[0]>EPSILON2 && distances[1]>EPSILON2 && distances[2]>EPSILON2){
+          return 1;
+        }
+      }
+
+      //test whether ray intersects one of the triangle's edges
+      if(intersection_line_line_with_intersection_3d(tri0, tri1, lin0, lin1, sol)){
+        return 4;
+      }else if(intersection_line_line_with_intersection_3d(tri1, tri2, lin0, lin1, sol)){
+        return 2;
+      }else if(intersection_line_line_with_intersection_3d(tri2, tri0, lin0, lin1, sol)){
+        return 3;
+      }
+    }
+    return 0; //ray disjoint from plane
+  }
+
+  //get intersection point of ray with triangle plane
+  r = a / b;
+  if(r < -EPSILON || r-1.0 > EPSILON){
+    return 0; //ray goes away from triangle => no intersection
+  }
+  for(i=0; i<3; i++) sol[i] = lin0[i] + r * dir[i];
+
+  //is sol inside triangle?
+  uu = u[0] * u[0] + u[1] * u[1] + u[2] * u[2];
+  uv = u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
+  vv = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+  for(i=0; i<3; i++) w[i] = sol[i] - tri0[i];
+
+  wu = w[0] * u[0] + w[1] * u[1] + w[2] * u[2];
+  wv = w[0] * v[0] + w[1] * v[1] + w[2] * v[2];
+  D = uv * uv - uu * vv;
+
+  //get and test parametric coords
+  s = (uv * wv - vv * wu) / D;
+  if (s < -EPSILON || s-1.0 > EPSILON){
+    return 0; //sol is outside triangle
+  }
+  t = (uv * wu - uu * wv) / D;
+  if (t < -EPSILON || (s + t-1.0) > EPSILON){
+    return 0; //sol is outside triangle
+  }
+
+  //calculate distance of sol with each edge of the triangle
+  distances[0] = distance_point_line_3d(sol, tri0, tri1);
+  if(distances[0]<EPSILON2){
+    return 4;
+  }
+  distances[1] = distance_point_line_3d(sol, tri1, tri2);
+  if(distances[1]<EPSILON2){
+    return 2;
+  }
+  distances[2] = distance_point_line_3d(sol, tri2, tri0);
+  if(distances[2]<EPSILON2){
+    return 3;
+  }
+  return 1; //sol is inside triangle
+}
+
+//----------------------------------------< intersection_line_tetrahedron_3d >
+bool intersection_line_tetrahedron_3d(double lin0[], double lin1[], double tet0[], double tet1[],
+                                                                     double tet2[], double tet3[]){
+  double sol[3];
+  //test intersection with faces
+  if(intersection_line_triangle_3d(tet0, tet1, tet2, lin0, lin1, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tet0, tet1, tet3, lin0, lin1, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tet0, tet2, tet3, lin0, lin1, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tet1, tet2, tet3, lin0, lin1, sol)){
+    return true;
+  }
+  //test intersection with edges
+  if(intersection_line_line_3d(tet0, tet1, lin0, lin1)){
+    return true;
+  }
+  if(intersection_line_line_3d(tet0, tet2, lin0, lin1)){
+    return true;
+  }
+  if(intersection_line_line_3d(tet0, tet3, lin0, lin1)){
+    return true;
+  }
+  if(intersection_line_line_3d(tet1, tet2, lin0, lin1)){
+    return true;
+  }
+  if(intersection_line_line_3d(tet1, tet3, lin0, lin1)){
+    return true;
+  }
+  if(intersection_line_line_3d(tet2, tet3, lin0, lin1)){
+    return true;
+  }
+  //test intersection with volume
+  if(point_in_tetrahedron_3d(lin0, tet0, tet1, tet2, tet3)
+                 || point_in_tetrahedron_3d(lin1, tet0, tet1, tet2, tet3)){
+    return true;
+  }
+  return false;
+}
+
+//----------------------------------------< intersection_triangle_tetrahedron_3d >
+bool intersection_triangle_tetrahedron_3d(double tri0[], double tri1[], double tri2[],
+                                          double tet0[], double tet1[], double tet2[], double tet3[]){
+  //test intersection with volume
+  if(point_in_tetrahedron_3d(tri0, tet0, tet1, tet2, tet3)
+                 || point_in_tetrahedron_3d(tri1, tet0, tet1, tet2, tet3)
+                 || point_in_tetrahedron_3d(tri2, tet0, tet1, tet2, tet3)){
+    return true;
+  }
+  //test intersection of triangle-edges with tetrahedron
+  if(intersection_line_tetrahedron_3d(tri0, tri1, tet0, tet1, tet2, tet3)){
+    return true;
+  }
+  if(intersection_line_tetrahedron_3d(tri1, tri2, tet0, tet1, tet2, tet3)){
+    return true;
+  }
+  if(intersection_line_tetrahedron_3d(tri2, tri0, tet0, tet1, tet2, tet3)){
+    return true;
+  }
+  //test intersection of tetrahedron-edges with triangle
+  double sol[3];
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet0, tet1, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet0, tet2, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet0, tet3, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet1, tet2, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet1, tet3, sol)){
+    return true;
+  }
+  if(intersection_line_triangle_3d(tri0, tri1, tri2, tet2, tet3, sol)){
+    return true;
+  }
+  return false;
+}
+
+//----------------------------------------< intersection_box_box_3d >
+bool intersection_box_box_3d(double min_corner0[], double max_corner0[],
+			     double min_corner1[], double max_corner1[]){
+  double p[3];
+  
+  if (edge_length_3d(min_corner0,max_corner0) < edge_length_3d(min_corner1,max_corner1)) {
+  // box0 is smaller than box1
+    if (point_in_box_3d(min_corner0, min_corner1, max_corner1))
+      return true;
+    if (point_in_box_3d(max_corner0, min_corner1, max_corner1))
+      return true;
+    
+    p[0] = min_corner0[0]; p[1] = min_corner0[1]; p[2] = max_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+    p[0] = min_corner0[0]; p[1] = max_corner0[1]; p[2] = min_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+    p[0] = min_corner0[0]; p[1] = max_corner0[1]; p[2] = max_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+    
+    p[0] = max_corner0[0]; p[1] = max_corner0[1]; p[2] = min_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+    p[0] = max_corner0[0]; p[1] = min_corner0[1]; p[2] = max_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+    p[0] = max_corner0[0]; p[1] = min_corner0[1]; p[2] = min_corner0[2];
+    if (point_in_box_3d(p, min_corner1, max_corner1))
+      return true;
+  
+  } else {
+  // box1 is smaller than box0
+    if (point_in_box_3d(min_corner1, min_corner0, max_corner0))
+      return true;
+    if (point_in_box_3d(max_corner1, min_corner0, max_corner0))
+      return true;
+    
+    p[0] = min_corner1[0]; p[1] = min_corner1[1]; p[2] = max_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+    p[0] = min_corner1[0]; p[1] = max_corner1[1]; p[2] = min_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+    p[0] = min_corner1[0]; p[1] = max_corner1[1]; p[2] = max_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+    
+    p[0] = max_corner1[0]; p[1] = max_corner1[1]; p[2] = min_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+    p[0] = max_corner1[0]; p[1] = min_corner1[1]; p[2] = max_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+    p[0] = max_corner1[0]; p[1] = min_corner1[1]; p[2] = min_corner1[2];
+    if (point_in_box_3d(p, min_corner0, max_corner0))
+      return true;
+  }
+}
+
+//----------------------------------------< intersection_triangle_box_3d >
+bool intersection_triangle_box_3d(double tri0[], double tri1[], double tri2[],
+				  double min_corner[], double max_corner[]){
+  // vertices of triangle covered by box
+  if (point_in_box_generous_3d(tri0,min_corner,max_corner))
+    return true;
+  if (point_in_box_generous_3d(tri1,min_corner,max_corner))
+    return true;
+  if (point_in_box_generous_3d(tri2,min_corner,max_corner))
+    return true;
+  
+  // bounding box of triangle does not intersect the box
+  double p0[3];
+  double p1[3];
+  boundingbox_triangle_3d(tri0,tri1,tri2,p0,p1);
+  if (!intersection_box_box_3d(min_corner,max_corner,p0,p1))
+    return false;
+  
+  double p2[3];
+    
+  // edges of box intersect triangle
+  p0[0] = min_corner[0]; p0[1] = min_corner[1]; p0[2] = max_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, min_corner, p0, p2))
+    return true;
+  
+  p1[0] = max_corner[0]; p1[1] = min_corner[1]; p1[2] = max_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, max_corner, p1, p2))
+    return true;
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  p1[0] = min_corner[0]; p1[1] = max_corner[1]; p1[2] = max_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, max_corner, p1, p2))
+    return true;
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  p0[0] = min_corner[0]; p0[1] = max_corner[1]; p0[2] = min_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, min_corner, p0, p2))
+    return true;
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  p1[0] = max_corner[0]; p1[1] = max_corner[1]; p1[2] = min_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, max_corner, p1, p2))
+    return true;
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  p0[0] = max_corner[0]; p0[1] = min_corner[1]; p0[2] = min_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, min_corner, p0, p2))
+    return true;
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  p1[0] = max_corner[0]; p1[1] = min_corner[1]; p1[2] = max_corner[2];
+  if (intersection_line_triangle_3d(tri0,tri1,tri2, p0, p1, p2))
+    return true;
+  
+  return false;
+}
+
+//----------------------------------------< distance_point_line_3d >
+//calculates the distance between a given point and the line segment between 'lin0' and 'lin1'.
+double distance_point_line_3d(double point[], double lin0[], double lin1[]){
+  double gx, gy, gz, fx, fy, fz, dx, dy, dz, t;
+
+  //the (complete) line through 'lin0' and 'lin1' is given by 'l = lin0 + t*g' with g as follows:
+  gx = lin1[0] - lin0[0];
+  gy = lin1[1] - lin0[1];
+  gz = lin1[2] - lin0[2];
+
+  //the normal-vector from 'point' to l is 'v = lin0 + t*g - point' for some t which is determined
+  // by 'v*g = 0'
+  t = (-gx * (lin0[0]-point[0]) - gy * (lin0[1]-point[1]) - gz * (lin0[2]-point[2]))
+                                                            / (gx*gx + gy*gy + gz*gz);
+
+  //if the orthogonal projection of 'point' onto l is not on the given line segment then one of the
+  //vertices 'lin0' or 'lin1' is the nearest point to 'point'
+  if(t<0){
+    //'lin0' is nearest
+    fx = lin0[0];
+    fy = lin0[1];
+    fz = lin0[2];
+  }
+  else if(t>1){
+    //'lin1' is nearest
+    fx = lin1[0];
+    fy = lin1[1];
+    fz = lin1[2];
+  }
+  else{
+    //orthogonal projection is nearest
+    fx = lin0[0] + t * gx;
+    fy = lin0[1] + t * gy;
+    fz = lin0[2] + t * gz;
+  }
+
+  //calculate distance
+  dx = point[0] - fx;
+  dy = point[1] - fy;
+  dz = point[2] - fz;
+  return sqrt(dx*dx + dy*dy + dz*dz);
+}
+
+
+//----------------------------------------< distance_point_box_2d >
+double distance_point_box_3d(double point[], double min_corner[], double max_corner[]){
+  if (point_in_box_3d(point,min_corner,max_corner))
+    return 0.0;
+  
+  double p[3];
+  double dist = edge_length_3d(point, min_corner);  
+  dist = std::min(dist, edge_length_3d(point, min_corner)); 
+  
+  p[0] = min_corner[0]; p[1] = min_corner[1]; p[2] = max_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));  
+  p[0] = min_corner[0]; p[1] = max_corner[1]; p[2] = min_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));
+  p[0] = min_corner[0]; p[1] = max_corner[1]; p[2] = max_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));
+  
+  p[0] = max_corner[0]; p[1] = max_corner[1]; p[2] = min_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));  
+  p[0] = max_corner[0]; p[1] = min_corner[1]; p[2] = max_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));
+  p[0] = max_corner[0]; p[1] = min_corner[1]; p[2] = min_corner[2];
+  dist = std::min(dist, edge_length_3d(point, p));
+  
+  return dist;
+}
+
+//----------------------------------------< distance_point_triangle_3d >
+//calculates the distance between a given 'point' and the triangle given by 'tri0', 'tri1', 'tri2'.
+double distance_point_triangle_3d(double point[], double tri0[], double tri1[], double tri2[]){
+  double gx, gy, gz, hx, hy, hz, fx, fy, fz, u, v;
+  double c1, c2, b1, b2, a1, distance, tmp;
+
+  //triangle lies in plane 'p = tri0 + u*g + v*h', where g and h are defined as follows:
+  gx = tri1[0] - tri0[0];
+  gy = tri1[1] - tri0[1];
+  gz = tri1[2] - tri0[2];
+  hx = tri2[0] - tri0[0];
+  hy = tri2[1] - tri0[1];
+  hz = tri2[2] - tri0[2];
+
+  //a vector from 'point' to p can be described by 'l = tri0 + u*g + v*h - point' and since we search the
+  //distance we need such a vector that is orthogonal to p. Thus 'l*g = 0' and 'l*h = 0'. We get a system
+  //of two equations of the form:
+  //a1*u + b1*v = c1
+  //b1*u + b2*v = c2
+  //with a1, b1, b2, c1, c2 as follows:
+  b1 = gx*hx + gy*hy + gz*hz;
+  c2 = -hx*(tri0[0]-point[0]) - hy*(tri0[1]-point[1]) - hz*(tri0[2]-point[2]);
+  b2 = hx*hx + hy*hy + hz*hz;
+  c1 = -gx*(tri0[0]-point[0]) - gy*(tri0[1]-point[1]) - gz*(tri0[2]-point[2]);
+  a1 = gx*gx + gy*gy + gz*gz;
+
+  //solve the system:
+  if(abs(b1) < EPSILON){
+    v = c2/b2;
+    u = c1/a1;
+  }
+  else{
+    v = (c1*b1 - c2*a1) / (b1*b1 - b2*a1);
+    u = (c1 - v*b1) / a1;
+  }
+
+  //now test whether the orthogonal projection of 'point' onto p lies inside the triangle
+  if(u>=0 && v>=0 && u+v<=1){
+    //yes, inside. The length of the normal-vector is the desired distance
+    fx = point[0] - tri0[0] - u*gx - v*hx;
+    fy = point[1] - tri0[1] - u*gy - v*hy;
+    fz = point[2] - tri0[2] - u*gz - v*hz;
+    distance = sqrt(fx*fx + fy*fy + fz*fz);
+  }
+  else{
+    //no, not inside. The desired distance is the distance to one of the triangle-edges
+    distance = 9999999.0;
+    tmp = distance_point_line_3d(point, tri0, tri1);
+    if(tmp<distance) distance = tmp;
+    tmp = distance_point_line_3d(point, tri1, tri2);
+    if(tmp<distance) distance = tmp;
+    tmp = distance_point_line_3d(point, tri2, tri0);
+    if(tmp<distance) distance = tmp;
+  }
+  return distance;
+}
+
+}
diff --git a/extensions/GeometryTools.h b/extensions/GeometryTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..874a19b925a585f55ab06be4e3b128bb70a57430
--- /dev/null
+++ b/extensions/GeometryTools.h
@@ -0,0 +1,250 @@
+/** \file GeometryTools.h */
+
+#ifndef GEOMETRY_TOOLBOX_H
+#define GEOMETRY_TOOLBOX_H
+
+#include "AMDiS.h"
+
+namespace meshconv {
+
+//                                      ###############
+//                                      ##  General  ##
+//                                      ###############
+
+//----------------------------------------< coordinate_extrema_triangle >
+//returns in 'small_coord' the smallest coordinate of 'sm' in the given dimension and in 'big_coord' the
+//biggest coordinate in the given dimension. Note: 'sm' has to be a triangle in a 2d or 3d world.
+// void coordinate_extrema_triangle(mesh &m, element &sm, long dimension, double &small_coord,
+//                                                                           double &big_coord);
+
+//----------------------------------------< solve_determinant4 >
+double solve_determinant4(double x11, double x12, double x13, double x14,
+                          double x21, double x22, double x23, double x24,
+                          double x31, double x32, double x33, double x34,
+                          double x41, double x42, double x43, double x44);
+
+//                                      #################
+//                                      ##  2D Worlds  ##
+//                                      #################
+
+//----------------------------------------< edge_length_2d >
+double edge_length_2d(double lin0[], double lin1[]);
+
+//----------------------------------------< boundingbox_triangle_2d >
+void boundingbox_triangle_2d(double tri0[], double tri1[], double tri2[],
+			     double min_corner[], double max_corner[]);
+
+//----------------------------------------< centroid_of_box_2d >
+void centroid_of_box_2d(double min_corner[], double max_corner[], double c[]);
+
+//----------------------------------------< centroid_of_triangle_2d >
+void centroid_of_triangle_2d(double tri0[], double tri1[], double tri2[], double c[]);
+
+//----------------------------------------< point_in_triangle_2d >
+bool point_in_triangle_2d(double p[], double a[], double b[], double c[]);
+
+//----------------------------------------< point_in_triangle_generous_2d >
+bool point_in_triangle_generous_2d(double p[], double a[], double b[], double c[]);
+
+//----------------------------------------< point_in_box_2d >
+bool point_in_box_2d(double p[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< point_in_box_generous_2d >
+bool point_in_box_generous_2d(double p[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< intersection_line_line_2d >
+//tests whether the line segment defined by end points 'lin0' and 'lin1' intersects the connection
+//between lamp and new_dof. If the line segment is intersected in one of its vertices the index of that
+//vertex (0 or 1) is returned in hit_vertex otherwise hit_vertex is set to -1.
+bool intersection_line_line_2d(double lin0[], double lin1[],
+                               double lamp[], double new_dof[], long &hit_vertex);
+
+//----------------------------------------< intersection_line_triangle_2d >
+bool intersection_line_triangle_2d(double lin0[], double lin1[],
+                                   double tri0[], double tri1[], double tri2[]);
+
+//----------------------------------------< intersection_line_box_2d >
+bool intersection_line_box_2d(double lin0[], double lin1[],
+			      double min_corner[], double max_corner[]);
+
+//----------------------------------------< intersection_box_box_2d >
+bool intersection_box_box_2d(double min_corner0[], double max_corner0[],
+			     double min_corner1[], double max_corner1[]);
+
+//----------------------------------------< intersection_triangle_box_2d >
+bool intersection_triangle_box_2d(double tri0[], double tri1[], double tri2[],
+				  double min_corner[], double max_corner[]);
+
+//----------------------------------------< distance_point_line_2d >
+//calculates the distance between a given point and the line segment between 'lin0' and 'lin1'.
+double distance_point_line_2d(double point[], double lin0[], double lin1[]);
+
+//----------------------------------------< distance_point_line_with_intersection_2d >
+//calculates the distance between a given point and the line-segment between 'lin0' and 'lin1'.
+//This version also returns the intersection-point of the perpendicular with the given line-segment.
+double distance_point_line_with_intersection_2d(double point[], double lin0[], double lin1[],
+                                                                           double intersection[]);
+
+//----------------------------------------< distance_point_box_2d >
+double distance_point_box_2d(double point[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< distance_point_triangle_2d >
+double distance_point_triangle_2d(double point[], double tri0[], double tri1[], double tri2[]);
+
+bool point_in_polygon(double point[], const std::vector<AMDiS::WorldVector<double> > &vertices);
+
+//                                      #################
+//                                      ##  3D Worlds  ##
+//                                      #################
+
+//----------------------------------------< points_identical_3d >
+bool points_identical_3d(double p1[], double p2[]);
+
+//----------------------------------------< normal_vector_3d >
+void normal_vector_3d(double tri0[], double tri1[], double tri2[], double normal[]);
+
+//----------------------------------------< triangle_area_3d >
+double triangle_area_3d(double tri0[], double tri1[], double tri2[]);
+
+//----------------------------------------< edge_length_3d >
+double edge_length_3d(double lin0[], double lin1[]);
+
+//----------------------------------------< triangle_max_edge_length_3d >
+double triangle_max_edge_length_3d(double tri0[], double tri1[], double tri2[]);
+
+//----------------------------------------< unit_normal_vector_3d >
+void unit_normal_vector_3d(double tri0[], double tri1[], double tri2[], double normal[]);
+
+//----------------------------------------< degenerate_triangle_3d >
+bool degenerate_triangle_3d(double tri0[], double tri1[], double tri2[]);
+
+
+//----------------------------------------< boundingbox_triangle_3d >
+void boundingbox_triangle_3d(double tri0[], double tri1[], double tri2[],
+			     double min_corner[], double max_corner[]);
+
+//----------------------------------------< centroid_of_box_3d >
+void centroid_of_box_3d(double min_corner[], double max_corner[], double c[]);
+
+//----------------------------------------< centroid_of_triangle_3d >
+void centroid_of_triangle_3d(double tri0[], double tri1[], double tri2[], double c[]);
+
+//----------------------------------------< point_in_box_3d >
+bool point_in_box_3d(double p[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< point_in_box_generous_3d >
+bool point_in_box_generous_3d(double p[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< point_in_tetrahedron_3d >
+bool point_in_tetrahedron_3d(double p[], double a[], double b[], double c[], double d[]);
+
+//----------------------------------------< intersection_line_line_3d >
+bool intersection_line_line_3d(double p1[], double p2[], double p3[], double p4[]);
+
+//----------------------------------------< intersection_line_line_with_intersection_3d >
+bool intersection_line_line_with_intersection_3d(double p1[], double p2[], double p3[], double p4[],
+                                                                               double intersection[]);
+
+//----------------------------------------< intersection_line_triangle_3d_chirkov >
+//ATTENTION: function does not work for lines almost in the plane of the triangle!
+//calculates the intersection of a line segment and a triangle if it exists. The intersection-point is not
+//calculated, the last argument "sol" remains unchanged.
+//    input:  a line segment (lin0, lin1), and a triangle (tri0, tri1, tri2)
+//    return: 0      disjoint
+//            1      intersection inside triangle
+//            2,3,4  intersection in edge of triangle (edge_index is 0, 1, 2 respectively)
+//this algorithm is based on an implementation by Nick Chirkov (journal of graphics tools 10(3):13-18, 2005).
+int intersection_line_triangle_3d(double tri0[], double tri1[], double tri2[],
+                                            double lin0[], double lin1[], double sol[]);
+
+//----------------------------------------< global variables >
+// int (*intersection_line_triangle_3d)(double tri0[], double tri1[], double tri2[],
+//                  double lin0[], double lin1[], double sol[]) = intersection_line_triangle_3d_chirkov;
+
+//----------------------------------------< intersection_line_triangle_3d_softsurfer >
+// Copyright 2001, softSurfer (www.softsurfer.com)
+// This code may be freely used and modified for any purpose
+// providing that this copyright notice is included with it.
+// SoftSurfer makes no warranty for this code, and cannot be held
+// liable for any real or imagined damage resulting from its use.
+// Users of this code must verify correctness for their application.
+
+//calculates the intersection point of a line segment and a triangle if it exists
+//    input:  a line segment (lin0, lin1), and a triangle (tri0, tri1, tri2)
+//    output: sol = intersection point (if it exists)
+//    return: 0      disjoint
+//            1      intersection inside triangle
+//            2,3,4  intersection in edge of triangle (edge_index is 0, 1, 2 respectively)
+int intersection_line_triangle_3d_softsurfer(double tri0[], double tri1[], double tri2[],
+                                    double lin0[], double lin1[], double sol[]);
+
+//----------------------------------------< intersection_line_tetrahedron_3d >
+bool intersection_line_tetrahedron_3d(double lin0[], double lin1[], double tet0[], double tet1[],
+                                                                     double tet2[], double tet3[]);
+
+//----------------------------------------< intersection_triangle_tetrahedron_3d >
+bool intersection_triangle_tetrahedron_3d(double tri0[], double tri1[], double tri2[],
+                                          double tet0[], double tet1[], double tet2[], double tet3[]);
+
+//----------------------------------------< intersection_box_box_3d >
+bool intersection_box_box_3d(double min_corner0[], double max_corner0[],
+			     double min_corner1[], double max_corner1[]);
+
+//----------------------------------------< intersection_triangle_box_3d >
+bool intersection_triangle_box_3d(double tri0[], double tri1[], double tri2[],
+				  double min_corner[], double max_corner[]);
+
+//----------------------------------------< distance_point_line_3d >
+//calculates the distance between a given point and the line segment between 'lin0' and 'lin1'.
+double distance_point_line_3d(double point[], double lin0[], double lin1[]);
+
+
+//----------------------------------------< distance_point_box_3d >
+double distance_point_box_3d(double point[], double min_corner[], double max_corner[]);
+
+//----------------------------------------< distance_point_triangle_3d >
+//calculates the distance between a given 'point' and the triangle given by 'tri0', 'tri1', 'tri2'.
+double distance_point_triangle_3d(double point[], double tri0[], double tri1[], double tri2[]);
+
+
+template<int dow>
+void coordinate_transform(double x[], double shift[], double scale[], double alpha=0.0, double beta=0.0)
+{
+  mtl::dense2D<double> Rx(dow,dow),Ry(dow,dow),T(dow,dow),S(dow,dow);
+  Rx = 1.0;
+  Ry = 1.0;
+  S = 1.0;
+  if (dow == 3) {
+    Rx(1,1) = cos(alpha);  Rx(1,2) = -sin(alpha);
+    Rx(2,1) = sin(alpha);  Rx(2,2) = cos(alpha);
+
+    Ry(0,0) = cos(beta);  Ry(0,2) = sin(beta);
+    Ry(2,0) = -sin(beta); Ry(2,2) = cos(beta);
+
+    S(0,0) = scale[0];  S(1,1) = scale[1];  S(2,2) = scale[2];
+  } else if (dow == 2) {
+    Rx(0,0) = cos(alpha);  Rx(0,1) = -sin(alpha);
+    Rx(1,0) = sin(alpha);  Rx(1,1) = cos(alpha);
+
+    Ry = 1.0;
+
+    S(0,0) = scale[0];  S(1,1) = scale[1];
+  } else {
+    S(0,0) = scale[0];
+  }
+
+  T = Ry*Rx*S;
+
+  mtl::dense_vector<double> coords(dow);
+  for (int i = 0; i < dow; i++)
+    coords[i] = x[i];
+
+  coords = T*coords;
+
+  for (int i = 0; i < dow; i++)
+    x[i] = coords[i]+shift[i];
+}
+
+}
+
+#endif // GEOMETRY_TOOLBOX_H
diff --git a/extensions/Helpers.cc b/extensions/Helpers.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d4069348c82e023355328b36e89d6a7ff6a356d8
--- /dev/null
+++ b/extensions/Helpers.cc
@@ -0,0 +1,524 @@
+#include "Helpers.h"
+
+using namespace AMDiS;
+
+
+void Helpers::copyDOF(std::vector<DOFVector<double>*> dof1, std::vector<DOFVector<double>*> dof2, WorldVector<double> shift, double fillValue)
+{ FUNCNAME("Helpers::copyDOF()");
+
+  TEST_EXIT(dof1.size() == dof2.size())("number of components to copy must be the same!\n");
+  TEST_EXIT(dof1.size() > 0)("Minimum 1 DOFVector to copy\n");
+
+  const FiniteElemSpace* feSpace1 = dof1[0]->getFeSpace();
+  const FiniteElemSpace* feSpace2 = dof2[0]->getFeSpace();
+
+  Mesh* mesh1 = feSpace1->getMesh();
+  Mesh* mesh2 = feSpace2->getMesh();
+  
+  DOFVector<WorldVector<double> > coords(feSpace2, "coords");
+  mesh2->getDofIndexCoords(feSpace2, coords);
+
+  ElInfo *elInfo = mesh1->createNewElInfo();
+  MacroElement *oldMacro = NULL;
+  DimVec<double> lambda(mesh1->getDim(), NO_INIT);
+
+  std::vector<DegreeOfFreedom> localIndices;	// DOF-indices of all DOFs in trinangle
+  mtl::dense_vector<double> uh; 		// evaluation of DOFVectors at QPs
+
+  localIndices.resize(feSpace1->getBasisFcts()->getNumber());
+  uh.change_dim(mesh1->getDim()+1);
+
+  MSG("map source-DOFVectors to target mesh...\n");
+  for (DegreeOfFreedom i = 0; i < coords.getSize(); i++) {
+    WorldVector<double> x = coords[i]+shift;;
+
+    bool inMesh;
+    if (oldMacro == NULL)
+      inMesh = mesh1->findElInfoAtPoint(x, elInfo, lambda, NULL, NULL, NULL);
+    else
+      inMesh = mesh1->findElInfoAtPoint(x, elInfo, lambda, oldMacro, NULL, NULL);
+
+    // calculate values!
+    for (int j = 0; j < dof1.size(); j++) {
+      double value = fillValue;
+      if (inMesh) {
+	feSpace1->getBasisFcts()->getLocalIndices(elInfo->getElement(), feSpace1->getAdmin(), localIndices);
+	for (int l = 0; l < lambda.size(); l++)
+	  uh[l] = (*dof1[j])[localIndices[l]];
+	value = feSpace1->getBasisFcts()->evalUh(lambda, uh);
+      }
+      (*dof2[j])[i] = value;
+    }
+
+    oldMacro = elInfo->getMacroElement();
+  }
+};
+
+void Helpers::calcMaxOnXAxis(DOFVector<double> *rho, std::vector<std::pair<WorldVector<double>, double> > &maxima)
+{ FUNCNAME("Helpers::calcMaxOnXAxis()");
+
+  std::vector<WorldVector<double> > x;
+  std::vector<double> y;
+
+  double dimX=1.0,dimY=1.0;
+  Parameters::get("mesh->dimension[x]",dimX);
+  Parameters::get("mesh->dimension[y]",dimY);
+
+  interpolOverLine(*rho,-dimX,0.0,dimX,0.0,1000,x,y);
+  if (x.size() != y.size())
+    throw(std::runtime_error("x.size /= y.size! Sollte nicht passieren!"));
+
+  if(x.size()>0) {
+    for(unsigned i=1; i<x.size()-1; ++i) {
+      if(y[i-1]<y[i] && y[i+1]<y[i]) {
+	maxima.push_back(std::make_pair(x[i],y[i]));
+      }
+    }
+  }
+};
+
+void Helpers::calcMaxOnYAxis(DOFVector<double> *rho, std::vector<std::pair<WorldVector<double>, double> > &maxima)
+{ FUNCNAME("Helpers::calcMaxOnYAxis()");
+
+  std::vector<WorldVector<double> > x;
+  std::vector<double> y;
+
+  double dimX,dimY;
+  Parameters::get("mesh->dimension[x]",dimX);
+  Parameters::get("mesh->dimension[y]",dimY);
+
+  interpolOverLine(*rho,0.0,-dimY,0.0,dimY,1000,x,y);
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  if (MPI::COMM_WORLD.Get_rank() == 0)
+  #endif
+  {
+  for(unsigned i=1; i<x.size()-1; ++i) {
+    if(y[i-1]<y[i] && y[i+1]<y[i]) {
+      maxima.push_back(make_pair(x[i],y[i]));
+    }
+  }
+  }
+};
+
+
+void Helpers::transformMesh(Mesh *mesh, WorldVector<double> scale, WorldVector<double> shift, WorldVector<double> rotate)
+{ FUNCNAME("Helpers::scaleMesh()");
+
+  int dow = Global::getGeo(WORLD);
+  mtl::dense2D<double> Rx(dow,dow),Ry(dow,dow),Rz(dow,dow),T_(dow,dow),S(dow,dow);
+  Rx = 1.0;
+  Ry = 1.0;
+  Rz = 1.0;
+  S = 1.0;
+  if (dow == 3) {
+    Rx[1][1] = cos(rotate[0]);  Rx[1][2] = -sin(rotate[0]);
+    Rx[2][1] = sin(rotate[0]);  Rx[2][2] = cos(rotate[0]);
+
+    Ry[0][0] = cos(rotate[1]);  Ry[0][2] = sin(rotate[1]);
+    Ry[2][0] = -sin(rotate[1]); Ry[2][2] = cos(rotate[1]);
+
+    Rz[0][0] = cos(rotate[2]);  Rz[0][1] = -sin(rotate[2]);
+    Rz[1][0] = sin(rotate[2]);  Rz[1][1] = cos(rotate[2]);
+
+    S[0][0] = scale[0];  S[1][1] = scale[1];  S[2][2] = scale[2];
+  } else if (dow == 2) {
+    Rx[0][0] = cos(rotate[0]);  Rx[0][1] = -sin(rotate[0]);
+    Rx[1][0] = sin(rotate[0]);  Rx[1][1] = cos(rotate[0]);
+
+    Ry = 1.0;
+    Rz = 1.0;
+
+    S[0][0] = scale[0];  S[1][1] = scale[1];
+  } else {
+    S[0][0] = scale[0];
+  }
+
+  T_ = Rz*Ry*Rx*S;
+
+  WorldMatrix<double> T;
+  vector_operations::fillMatrix(T,T_);
+
+  FixVec<WorldVector<double>, VERTEX> coords;
+  deque<MacroElement*>::iterator macro;
+
+  for(macro = mesh->firstMacroElement(); macro != mesh->endOfMacroElements(); macro++) {
+    for (int i = 0; i < mesh->getDim()+1; ++i) {
+      WorldVector<double> x = (*macro)->getCoord(i);
+      WorldVector<double> x_temp = x;
+      x.multMatrixVec(T,x_temp);
+      x+= shift;
+      (*macro)->setCoord(i, x);
+    }
+  }
+};
+
+void Helpers::scaleMesh(Mesh *mesh, WorldVector<double> shift, WorldVector<double> scale)
+{ FUNCNAME("Helpers::scaleMesh()");
+
+  deque<MacroElement*>::iterator macro;
+  int dim = Global::getGeo(WORLD);
+
+  for(macro = mesh->firstMacroElement(); macro != mesh->endOfMacroElements(); macro++) {
+    for (int i = 0; i < mesh->getDim()+1; ++i) {
+      WorldVector<double> x = (*macro)->getCoord(i);
+      x *= scale;
+      x += shift;
+      (*macro)->setCoord(i, x);
+    }
+  }
+};
+
+// scale by different values in all directions
+void Helpers::scaleMesh(Mesh *mesh, WorldVector<double> scale)
+{ FUNCNAME("Helpers::scaleMesh()");
+
+  WorldVector<double> shift; shift.set(0.0);
+  scaleMesh(mesh,shift,scale);
+}
+
+// scale by different values in all directions
+void Helpers::scaleMesh(std::vector<Mesh*> meshes, WorldVector<double> scale)
+{ FUNCNAME("Helpers::scaleMesh()");
+
+  WorldVector<double> shift; shift.set(0.0);
+  for (size_t i = 0; i < meshes.size(); i++)
+    scaleMesh(meshes[i],shift,scale);
+}
+
+// scale and shift by the same values in all directions
+void Helpers::scaleMesh(Mesh *mesh, double shift, double scale)
+{ FUNCNAME("Helpers::scaleMesh()");
+
+  WorldVector<double> wShift, wScale;
+  wShift.set(shift);
+  wScale.set(scale);
+  scaleMesh(mesh,wShift,wScale);
+}
+
+void Helpers::read_dof_vector(const std::string file, DOFVector<double> *dofvec, long size)
+{ FUNCNAME("Helpers::read_dof_vector()");
+
+  ifstream in;
+  string buf;
+  long i;
+
+  in.open(file.c_str());
+  if (!in)
+    throw(std::runtime_error("ERROR! Could not read value file."));
+
+  DOFIterator<double> dofIter(dofvec, USED_DOFS);
+
+  getline(in, buf);
+  while(buf.substr(0,14) != "vertex values:") getline(in, buf);
+  for (i = 0, dofIter.reset(); !dofIter.end(); ++i, ++dofIter){
+    in >> buf;
+    (*dofIter) = atof(buf.c_str());
+  }
+  in.close();
+
+  if (i != size)
+    throw(std::runtime_error("#vertices != dofIter.size()"));
+}
+
+WorldVector<double> Helpers::getMeshDimension(Mesh *mesh)
+{ FUNCNAME("Helpers::getMeshDimension()");
+
+  WorldVector<double> dimension; dimension.set(-1.e10);
+
+  TraverseStack stack;
+  ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL | Mesh::FILL_COORDS);
+  while (elInfo) {
+    for (int i = 0; i <= mesh->getDim(); i++) {
+      WorldVector<double> &coords = elInfo->getMacroElement()->getCoord(i);
+      for(int j = 0; j < coords.getSize(); ++j) {
+	dimension[j] = std::max(dimension[j], coords[j]);
+      }
+    }
+    elInfo = stack.traverseNext(elInfo);
+  }
+  return dimension;
+}
+
+void Helpers::getMeshDimension(Mesh *mesh, WorldVector<double> &min_corner, WorldVector<double> &max_corner)
+{ FUNCNAME("Helpers::getMeshDimension()");
+
+  max_corner.set(-1.e10);
+  min_corner.set(1.e10);
+
+  TraverseStack stack;
+  ElInfo *elInfo = stack.traverseFirst(mesh, 0, Mesh::CALL_EL_LEVEL | Mesh::FILL_COORDS);
+  while (elInfo) {
+    for (int i = 0; i <= mesh->getDim(); i++) {
+      WorldVector<double> &coords = elInfo->getMacroElement()->getCoord(i);
+      for(int j = 0; j < coords.getSize(); ++j) {
+	max_corner[j] = std::max(max_corner[j], coords[j]);
+	min_corner[j] = std::min(min_corner[j], coords[j]);
+      }
+    }
+    elInfo = stack.traverseNext(elInfo);
+  }
+}
+
+void Helpers::getNormalsWeighted(FiniteElemSpace *feSpace, DOFVector<WorldVector<double> > *normals)
+{
+  Mesh *mesh = feSpace->getMesh();
+  const BasisFunction *basisFcts = feSpace->getBasisFcts();
+  int nBasisFcts = basisFcts->getNumber();
+  
+  std::vector<DegreeOfFreedom> localIndices(nBasisFcts);
+  
+  DOFVector<double> numNormals(feSpace, "numNormals");
+  numNormals.set(0.0);
+    
+  WorldVector<double> normal; normal.set(0.0);
+  normals->set(normal);
+  TraverseStack stack;
+  ElInfo *elInfo = 
+    stack.traverseFirst(mesh, -1, 
+                        Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+    
+  while (elInfo) {
+    elInfo->getElementNormal(normal);
+    Element *el = elInfo->getElement();
+    double det = elInfo->getDet();
+    if (det <= DBL_TOL)
+      det = elInfo->calcDet();
+    
+    basisFcts->getLocalIndices(el, feSpace->getAdmin(), localIndices);
+    
+    for (int i = 0; i < nBasisFcts; i++) {
+      (*normals)[localIndices[i]] += normal*(1.0/det);
+    }
+
+    elInfo = stack.traverseNext(elInfo);
+  }
+    
+  DOFIterator<WorldVector<double> > normalsIter(normals, USED_DOFS); normalsIter.reset();
+  for (; !normalsIter.end(); normalsIter++)
+  {
+    *normalsIter *= 1.0/norm(*normalsIter);
+  }
+}
+
+void Helpers::getNormals(FiniteElemSpace *feSpace, DOFVector<WorldVector<double> > *normals, DOFVector<WorldMatrix<double> > *gradNormals)
+{
+  using namespace mtl;
+  using namespace itl;
+  
+  Mesh *mesh = feSpace->getMesh();
+  const BasisFunction *basisFcts = feSpace->getBasisFcts();
+  int nBasisFcts = basisFcts->getNumber();
+
+  std::vector<DegreeOfFreedom> localIndices(nBasisFcts);
+  DOFVector<std::set<DegreeOfFreedom> > neighbors(feSpace, "neighbors");
+
+  TraverseStack stack;
+  ElInfo *elInfo =
+    stack.traverseFirst(mesh, -1,
+                        Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+
+  while (elInfo) {
+    basisFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices);
+
+    for (size_t i = 0; i < nBasisFcts; i++) {
+      for (size_t j = 0; j < nBasisFcts; j++) {
+	neighbors[localIndices[i]].insert(localIndices[j]);
+      }
+    }
+    elInfo = stack.traverseNext(elInfo);
+  }
+
+  DOFVector<WorldVector<double> > coordsDOF(feSpace, "coords");
+  mesh->getDofIndexCoords(feSpace, coordsDOF);
+
+  Helpers::getNormalsWeighted(feSpace, normals);
+  VtkWriter::writeFile(normals, "normals_weighted.vtu");
+
+//   DOFVector<WorldMatrix<double> > *grdDOF = gradNormals;
+//   if (grdDOF == NULL)
+//     grdDOF = new DOFVector<WorldMatrix<double> >(feSpace, "grd");
+
+  DOFIterator<WorldVector<double> > normalsIter(normals, USED_DOFS); normalsIter.reset();
+  DOFIterator<WorldVector<double> > coordsIter(&coordsDOF, USED_DOFS); coordsIter.reset();
+/*  DOFIterator<WorldMatrix<double> > grdIter(grdDOF, USED_DOFS); grdIter.reset();*/
+  DOFIterator<std::set<DegreeOfFreedom> > neighborsIter(&neighbors, USED_DOFS); neighborsIter.reset();
+  for (; !neighborsIter.end(); neighborsIter++, normalsIter++, coordsIter++/*, grdIter++*/)
+  {
+    int numPoints = 10; // 6 oder 10
+    std::set<DegreeOfFreedom> idx = *neighborsIter;
+    std::set<DegreeOfFreedom>::iterator it, it2;
+
+    for (int i = 1; i<3 && idx.size() < numPoints; i++) {
+    for (it = idx.begin(); it != idx.end() && idx.size() < numPoints; it++) {
+      for (it2 = (neighbors[*it]).begin(); it2 != (neighbors[*it]).end() && idx.size() < numPoints; it2++) {
+	idx.insert(*it2);
+      }
+    }
+    }
+    TEST_EXIT(idx.size()>=numPoints)("Nicht genügend Stützstellen gefunden!\n");
+    size_t i = 0;
+    mtl::dense2D<double> A(numPoints,6), B(6,6);
+    mtl::dense_vector<double> b(numPoints, 1.0), c(6), y(6, 1.0);
+
+    for (it = idx.begin(); it != idx.end() && i < numPoints; it++, i++) {
+      WorldVector<double> x = coordsDOF[*it];
+      A[i][0] = sqr(x[0]); A[i][1] = sqr(x[1]); A[i][2] = sqr(x[2]);
+      A[i][3] = x[0]*x[1]; A[i][4] = x[0]*x[2]; A[i][5] = x[1]*x[2];
+//       if(numPoints>6)
+// 	A[i][6] = x[0]; A[i][7] = x[1]; A[i][8] = x[2]; A[i][9] = 1.0;
+    }
+    c = trans(A)*b;
+    B = trans(A)*A;
+//     pc::ilu_0<mtl::dense2D<double> > P(B);
+//     basic_iteration<double>          iter(c, 100, 1.e-6);
+
+//     Solve Ax == b with left preconditioner P
+//     bicgstab(B, y, c, P, iter);
+
+    y = mtl::matrix::lu_solve(B,c);
+
+    WorldVector<double> oldNormal = (*normalsIter);
+
+    (*normalsIter)[0] = 2.0*y[0]*(*coordsIter)[0] + y[3]*(*coordsIter)[1] + y[4]*(*coordsIter)[2]/* + (numPoints==10?y[6]:0.0)*/;
+    (*normalsIter)[1] = 2.0*y[1]*(*coordsIter)[1] + y[3]*(*coordsIter)[0] + y[5]*(*coordsIter)[2]/* + (numPoints==10?y[7]:0.0)*/;
+    (*normalsIter)[2] = 2.0*y[2]*(*coordsIter)[2] + y[4]*(*coordsIter)[0] + y[5]*(*coordsIter)[1]/* + (numPoints==10?y[8]:0.0)*/;
+
+    double nrm = norm(*normalsIter);
+    double diff = norm(oldNormal - *normalsIter);
+    double signFactor = 1.0;
+    if (diff > nrm)
+      signFactor = -1.0;
+    *normalsIter *= signFactor/nrm;
+
+//     if(gradNormals != NULL) {
+//       WorldMatrix<double> grad;
+//       grad[0][0] = 2.0*y[0]; grad[0][1] = y[3]; grad[0][2] = y[4];
+//       grad[1][0] = y[3]; grad[1][1] = 2.0*y[1]; grad[1][2] = y[5];
+//       grad[2][0] = y[4]; grad[2][1] = y[5]; grad[2][2] = 2.0*y[2];
+//       grad *= signFactor;
+//       
+//       double trace_ = 0.0;
+//       for (int i=0;i<3;i++)
+// 	trace_ += (grad[i][i]/nrm-sqr((*normalsIter)[i]));
+//       std::cout<<"nrm(n)="<<nrm<<std::endl;
+//       std::cout<<"trace(grad(n))="<<vector_operations::trace(grad)/nrm<<"="<<trace_<<std::endl;
+//       
+//       WorldMatrix<double> NN;
+//       NN.vecProduct(*normalsIter, *normalsIter);
+// 
+//       grad -= NN;
+//       grad *= 1.0/nrm;
+//       
+//       *grdIter = grad;
+// 
+//     }
+  }
+
+//   if(gradNormals == NULL)
+//     delete grdDOF;
+}
+
+void Helpers::getCurvature(DOFVector<WorldVector<double> >* normals,DOFVector<double>* curvature)
+{
+  int dim = normals->getFeSpace()->getMesh()->getDim();
+  int dow = Global::getGeo(WORLD);
+  
+  WorldVector<DOFVector<double>*> normalsVec;
+  WorldVector<DOFVector<WorldVector<double> >*> gradNormals;
+  for (int i = 0; i < dow; i++) {
+    normalsVec[i] = new DOFVector<double>(normals->getFeSpace(), "n_i");
+    gradNormals[i] = new DOFVector<WorldVector<double> >(normals->getFeSpace(), "grad_i");
+  }
+  transform(normals, &normalsVec);
+  for (int i = 0; i < dow; i++)
+    normalsVec[i]->getRecoveryGradient(gradNormals[i]);
+
+  DOFIterator<WorldVector<double> > grd0Iter(gradNormals[0], USED_DOFS); grd0Iter.reset();
+  DOFIterator<WorldVector<double> > grd1Iter(gradNormals[1], USED_DOFS); grd1Iter.reset();
+  DOFIterator<WorldVector<double> > grd2Iter(gradNormals[2], USED_DOFS); grd2Iter.reset();
+  DOFIterator<double> hIter(curvature, USED_DOFS); hIter.reset();
+  
+  for (; !grd0Iter.end(); grd0Iter++,grd1Iter++,grd2Iter++,hIter++)
+  {
+    *hIter = ((*grd0Iter)[0] + (*grd1Iter)[1] + (*grd2Iter)[2])/static_cast<double>(dim);
+  }
+
+  for (int i = 0; i < dow; i++) {
+    delete normalsVec[i];
+    delete gradNormals[i];
+  }
+}
+
+void Helpers::process_mem_usage(double& vm_usage, double& resident_set)
+{
+  using std::ios_base;
+  using std::ifstream;
+  using std::string;
+  
+  vm_usage     = 0.0;
+  resident_set = 0.0;
+  
+  // 'file' stat seems to give the most reliable results
+  //
+  ifstream stat_stream("/proc/self/stat",ios_base::in);
+  
+  // dummy vars for leading entries in stat that we don't care about
+  //
+  string pid, comm, state, ppid, pgrp, session, tty_nr;
+  string tpgid, flags, minflt, cminflt, majflt, cmajflt;
+  string utime, stime, cutime, cstime, priority, nice;
+  string O, itrealvalue, starttime;
+  
+  // the two fields we want
+  //
+  unsigned long vsize;
+  long rss;
+  
+  stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr
+	      >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt
+	      >> utime >> stime >> cutime >> cstime >> priority >> nice
+	      >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest
+  
+  long page_size_kb = sysconf(_SC_PAGE_SIZE) / 1024; // in case x86-64 is configured to use 2MB pages
+  vm_usage     = vsize / 1024.0;
+  resident_set = rss * page_size_kb;
+}
+
+// plots a vector with ascii-code
+void Helpers::plot(std::vector<double> &values, int numRows, int numCols, std::string symbol)
+{
+  unsigned num=values.size();
+  unsigned cols=std::min(numCols,(int)num), rows=std::min(numRows,(int)num);
+  unsigned step=(unsigned)floor(num/(double)cols);
+  cols=(unsigned)ceil(num/(double)step);
+
+  double maxVal=*max_element(values.begin(),values.end());
+  double minVal=*min_element(values.begin(),values.end());
+  std::stringstream ssMax; ssMax.setf(std::ios::fixed,std::ios::floatfield); ssMax.precision(2); ssMax<<maxVal;
+  std::stringstream ssMin; ssMin.setf(std::ios::fixed,std::ios::floatfield); ssMin.precision(2); ssMin<<minVal;
+  unsigned cols0 = std::max(ssMax.str().length(),ssMin.str().length());
+  std::stringstream ssNum; ssNum<<num;
+
+  std::string emptyLine(cols+cols0,' ');emptyLine.replace(cols0-1,1,"|");
+  std::vector<std::string> lines(rows+1,emptyLine);
+
+  double range=maxVal-minVal;
+  
+  for(unsigned i=0;i<cols; i+=1) {
+    int v=(int)round((rows-1)*(values[i*step]-minVal)/range,0);
+    int r=rows-v-1, c=i+cols0;
+    
+    lines[r].replace(c,1,symbol);
+    lines[rows].replace(c,1,"-");
+  }
+
+  lines[0].replace(cols0-ssMax.str().length(),ssMax.str().length(),ssMax.str());
+  lines[rows-1].replace(cols0-ssMin.str().length(),ssMin.str().length(),ssMin.str());
+  lines[rows].replace(cols0-1,2," 0");
+  lines[rows].erase(cols+cols0-1,1);
+  lines[rows].append(ssNum.str());
+
+  for(unsigned i=0;i<lines.size(); ++i)
+    std::cout<<lines[i]<<std::endl;
+}
diff --git a/extensions/Helpers.h b/extensions/Helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..f65b55eff1eb6fa1735d8156f24dc17119ea8a21
--- /dev/null
+++ b/extensions/Helpers.h
@@ -0,0 +1,390 @@
+/** \file Helpers.h */
+
+#ifndef MY_HELPERS_H
+#define MY_HELPERS_H
+
+#include "AMDiS.h"
+
+#if HAVE_PARALLEL_DOMAIN_AMDIS
+#include "parallel/StdMpi.h"
+#endif
+
+#include <unistd.h>
+#include <ios>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/itl/itl.hpp>
+#include "boost/lexical_cast.hpp"
+#include "boost/date_time/posix_time/posix_time.hpp"
+#include <time.h>
+#include <stdarg.h>
+
+#include "VectorOperations.h"
+
+#define TEST_WARNING(test) if ((test));else WARNING
+
+using namespace std;
+using namespace AMDiS; 
+
+static long random_seed_initial_value=0;
+
+class Helpers {
+public:
+
+  /// math routines
+  /// ==============
+  
+  static double cint(double x){
+    double intpart; 
+    if (modf(x,&intpart)>=.5)
+      return x>=0?ceil(x):floor(x);
+    else
+      return x<0?ceil(x):floor(x);
+  }
+  
+  static double round(double r, double places){
+    double off= pow(10.0, places);
+    return cint(r*off)/off;
+  }
+  
+  static bool isNumber(double val) { return !isnan(val) && !isinf(val); };
+  static double signum(double val, double tol=1.e-10) { return (val>tol?1.0:(val<-tol?-1.0:0.0)); }
+  static int signum(int val) { return (val>0?1:(val<0?-1:0)); }
+  static int signum(bool val) { return (val?1:-1); }
+  static int toInt(bool val) { return (val?1:0); }
+
+  /// routines for conversion to string
+  /// =================================
+  
+  template<typename T>
+  static std::string toString(const T &value, ios_base::fmtflags flag= ios_base::scientific)
+  {
+    std::stringstream ss;
+    ss.setf(flag);
+    ss.precision(6);
+    if (!(ss<<value))
+      throw(std::runtime_error("toString() not possible"));
+    return ss.str();
+  };
+  
+  static std::string toString(const int &value)
+  {
+    return boost::lexical_cast<std::string>(value);
+  };
+  
+  template<typename T>
+  static std::string toString(const WorldVector<T> &value, bool brackets= true, ios_base::fmtflags flag= ios_base::scientific)
+  {
+    std::stringstream ss;
+    if (brackets) ss<<"[";
+    ss.setf(flag);
+    ss.precision(6);
+    if (!(ss<<value))
+      throw(std::runtime_error("toString() not possible"));
+    
+    if (brackets) ss<<"]";
+    return ss.str();
+  };
+  
+  template<typename T>
+  static std::string toString(const std::vector<T> &vec, bool brackets= true, ios_base::fmtflags flag= ios_base::scientific)
+  {
+    std::stringstream ss;
+    if (brackets) ss<<"[";
+    ss.setf(flag);
+    ss.precision(6);
+    for (size_t i = 0; i < vec.size(); ++i) {
+      if (!(ss<<(i>0?", ":"")<<vec[i]))
+	throw(std::runtime_error("toString() not possible"));
+    }
+    if (brackets) ss<<"]";
+    return ss.str();
+  };
+  
+  template<class T>
+  static T fromString(const std::string& s)
+  {
+    std::istringstream stream(s);
+    T t;
+    stream >> t;
+    return t;
+  };
+
+  static std::string fillString(int length, char c, int numValues, ...)
+  {
+    va_list values;
+    int value;
+    va_start(values, numValues);
+
+    int len = length;
+    for(int i=0; i<numValues; i++) {
+      value = va_arg(values, int);
+      double tmp = static_cast<double>(value);
+      while (true) {
+	len --;
+	tmp /= 10.0;
+	if (tmp < 1.0 - DBL_TOL)
+	  break;
+      }
+    }
+    va_end(values);
+
+    return std::string(len, c);
+  };
+
+  // process printable string of memory
+  static std::string memoryToString(double mem, int startIdx=0) {
+    int idx = startIdx;
+    double mem_ = mem;
+    while (mem_/1024.0 > 1.0) {
+      mem_ /= 1024.0;
+      idx++;
+    }
+    std::string result = toString(mem_)+" "+(idx==0?"B":(idx==1?"KB":(idx==2?"MB":"GB")));
+    return result;
+  };  
+  
+  
+  /// some mesh routines
+  /// ===========================
+  
+  static void transformMesh(Mesh *mesh, WorldVector<double> scale, WorldVector<double> shift, WorldVector<double> rotate);
+
+  static void scaleMesh(std::vector<Mesh*> meshes, WorldVector<double> scale);
+  // scale and shift by different values in all directions
+  static void scaleMesh(Mesh *mesh, WorldVector<double> shift, WorldVector<double> scale);
+  // scale by different values in all directions
+  static void scaleMesh(Mesh *mesh, WorldVector<double> scale);
+  // scale and shift by the same values in all directions
+  static void scaleMesh(Mesh *mesh, double shift=0.0, double scale=1.0);
+  
+  /// calculate the dimension of a mesh
+  static WorldVector<double> getMeshDimension(Mesh *mesh);
+  static void getMeshDimension(Mesh *mesh, WorldVector<double> &min_corner, WorldVector<double> &max_corner);
+
+  /// read DOFVector from AMDiS .dat-files
+  static void read_dof_vector(const std::string file, DOFVector<double> *dofvec, long size);
+
+  /// copy DOFVectors that live on different meshes
+  static void copyDOF(std::vector<DOFVector<double>*> dof1, std::vector<DOFVector<double>*> dof2, WorldVector<double> shift, double fillValue = 0.0);
+  
+  static void copyDOF(DOFVector<double>* dof1, DOFVector<double>* dof2) {
+    WorldVector<double> shift; shift.set(0.0);
+    std::vector<DOFVector<double>*> dof1Vec; dof1Vec.push_back(dof1);
+    std::vector<DOFVector<double>*> dof2Vec; dof2Vec.push_back(dof2);
+    copyDOF(dof1Vec, dof2Vec, shift);
+  };
+
+  /// some linear algebra methods
+  /// ===========================
+
+  static double determinant(mtl::dense2D<double> &A) // only for 3x3 - matrices
+  {
+    if(num_rows(A)==3 && num_cols(A)==3) {
+      double det = A(0,0)*A(1,1)*A(2,2)+A(0,1)*A(1,2)*A(2,0)+A(0,2)*A(1,0)*A(2,1);
+      return det-(A(0,2)*A(1,1)*A(2,0)+A(0,1)*A(1,0)*A(2,2)+A(0,0)*A(1,2)*A(2,1));
+    }
+    return 1.0;
+  };
+  
+  static double determinant(WorldMatrix<double> &A) // only for 3x3 - matrices
+  {
+    if(A.getNumRows()==3 && A.getNumCols()==3) {
+      double det = A[0][0]*A[1][1]*A[2][2]+A[0][1]*A[1][2]*A[2][0]+A[0][2]*A[1][0]*A[2][1];
+      return det-(A[0][2]*A[1][1]*A[2][0]+A[0][1]*A[1][0]*A[2][2]+A[0][0]*A[1][2]*A[2][1]);
+    }
+    return 1.0;
+  };
+  
+  /// inverse power method to find minimal eigenvalue of matrix A and appropriate eigenvector x, using m iterations
+  template <class LinearSolver, class Matrix, class EigenVector>
+  static double inverse_iteration(LinearSolver& solver, const Matrix& A, EigenVector& x, int m)
+  { FUNCNAME("Helpers::inverse_iteration()");
+
+    EigenVector y( size(x) ), res( size(x) );
+    double lambda = 0.0, lambda_old = 0.0, relErr;
+    mtl::seed<double> seed;
+    random(x, seed);
+    x /= two_norm(x);
+
+    solver.setMultipleRhs(true);
+    for (int i = 0; i < m; ++i) {
+      solver.solveSystem(A, y, x ); // solve Ay=x --> y
+      lambda_old=lambda;
+      lambda = dot(y,x)/dot(y,y);
+      relErr = abs((lambda-lambda_old)/lambda);
+      if(relErr<1.e-5) break;
+      x = y / two_norm(y);
+    }
+    solver.setMultipleRhs(false);
+
+    return lambda ;
+  };
+
+  /// calculate approximation to condition number of matrix A using the OEMSolver solver
+  template <class LinearSolver, class Matrix>
+  static double condition(LinearSolver& solver, const Matrix& A, int m=10)
+  { FUNCNAME("Helpers::condition()");
+
+    mtl::dense_vector<double>   x(num_rows(A)), y(num_rows(A));
+    mtl::seed<double>           seed;
+    random(x, seed);
+
+    double lambda = 0.0, lambda_old = 0.0, relErr, result1;
+    x /= two_norm(x);
+    for (int i = 0; i < m; ++i) {
+      y = A * x;
+      lambda_old=lambda;
+      lambda = mtl::dot(y,x);
+      relErr = abs((lambda-lambda_old)/lambda);
+      if(relErr<1.e-5) break;
+      x = y / two_norm(y) ;
+    }
+    result1 = std::abs(lambda / inverse_iteration(solver, A, x, m));
+    return result1;
+  };
+  
+  /// interpolate values of DOFVector along line from (x1,y1) -> (x2,y1) with nPoints points
+  template<typename Container>
+  static void interpolOverLine(const Container &vec, 
+			       double x1, double y1, double x2, double y2, 
+			       int nPoints,
+			       std::vector<WorldVector<double> > &x, std::vector<double> &y);
+
+  /// calculate maxima of DOFVector along line, using interpolOverLine
+  static void calcMaxOnXAxis(DOFVector<double> *rho, std::vector<std::pair<WorldVector<double>, double> > &maxima);
+  static void calcMaxOnYAxis(DOFVector<double> *rho, std::vector<std::pair<WorldVector<double>, double> > &maxima);
+
+  /// calc normal vectors of surface from element normals by averaging
+  static void getNormalsWeighted(FiniteElemSpace *feSpace, DOFVector<WorldVector<double> > *normals);
+  
+  /// calc normal vectors of surface from element normals by local approximation by quartic
+  static void getNormals(FiniteElemSpace *feSpace, DOFVector<WorldVector<double> > *normals, DOFVector<WorldMatrix<double> > *gradNormals = NULL);
+  
+  /// calc curvature from given normal vectors
+  static void getCurvature(DOFVector<WorldVector<double> >* normals, DOFVector<double>* curvature);
+  
+  /// misc routines
+  /// =============
+  
+  static void plot(std::vector<double> &values, int numRows=7, int numCols=20, std::string symbol="*");
+
+  // process_mem_usage(double &, double &) - takes two doubles by reference,
+  // attempts to read the system-dependent data for a process' virtual memory
+  // size and resident set size, and return the results in KB.
+  //
+  // On failure, returns 0.0, 0.0
+  static void process_mem_usage(double& vm_usage, double& resident_set);
+  
+  static long getMicroTimestamp() {
+    using namespace boost::posix_time;
+    ptime t0(min_date_time);
+    ptime now = microsec_clock::local_time();
+    time_duration td = now-t0;
+    return td.total_microseconds();
+  };
+  
+  static long getRandomSeed(int param=0) {
+    using namespace boost::posix_time;
+    ptime t0(min_date_time);
+    ptime now = microsec_clock::local_time();
+    time_duration td = now-t0;
+    long value0 = td.total_microseconds();
+    long value1 = clock();
+    long value2 = random_seed_initial_value++;
+
+    return value0+value1+value2+param;
+  };
+};
+
+
+
+/** \ingroup DOFAdministration
+  * \brief
+  * Implements a DOFIterator for a DOFIndexed<T> object
+  */
+template<typename T>
+class DOFConstIterator : public DOFIteratorBase
+{
+public:
+  /// Constructs a DOFIterator for cont of type t
+  DOFConstIterator(const DOFIndexed<T> *obj, DOFIteratorType t)
+    : DOFIteratorBase(dynamic_cast<DOFAdmin*>(obj->getFeSpace()->getAdmin()), t),
+      iteratedObject(obj)
+  {}
+
+  /// Constructs a DOFIterator for cont of type t
+  DOFConstIterator(DOFAdmin *admin,
+	      const DOFIndexed<T> *obj,
+	      DOFIteratorType t)
+    : DOFIteratorBase(admin, t),
+      iteratedObject(obj)
+  {}
+
+  /// Dereference operator
+  inline const T& operator*()
+  {
+    return *it;
+  }
+
+  /// Dereference operator
+  inline const T* operator->()
+  {
+    return &(*it);
+  }
+
+  inline bool operator!=(const DOFIterator<T>& rhs)
+  {
+    if (this->iteratedObject != rhs.iteratedObject)
+      return true;
+
+    if (this->it != rhs.it)
+      return true;
+
+    return false;
+  }
+
+  inline bool operator==(const DOFIterator<T>& rhs)
+  {
+    return !(this->operator==(rhs));
+  }
+
+protected:
+  /// Implementation of DOFIteratorBase::goToBeginOfIteratedObject()
+  inline void goToBeginOfIteratedObject()
+  {
+    it = iteratedObject->begin();
+  }
+
+  /// Implementation of DOFIteratorBase::goToEndOfIteratedObject()
+  inline void goToEndOfIteratedObject()
+  {
+    it = iteratedObject->end();
+  }
+
+  /// Implementation of DOFIteratorBase::incObjectIterator()
+  inline void incObjectIterator()
+  {
+    ++it;
+  }
+
+  /// Implementation of DOFIteratorBase::incObjectIterator()
+  inline void decObjectIterator()
+  {
+    --it;
+  }
+
+protected:
+  /// Object that is iterated
+  const DOFIndexed<T> *iteratedObject;
+
+  /// Iterator for \ref iteratedObject
+  typename std::vector<T>::const_iterator it;
+};
+
+#include "Helpers.hh"
+
+
+#endif
diff --git a/extensions/Helpers.hh b/extensions/Helpers.hh
new file mode 100644
index 0000000000000000000000000000000000000000..72a94805b4f1f89bc560e8834716d2e8704b8e37
--- /dev/null
+++ b/extensions/Helpers.hh
@@ -0,0 +1,26 @@
+
+#include "Views.h"
+
+template<typename Container>
+void Helpers::interpolOverLine(const Container &vec, 
+			       double x1, double y1, double x2, double y2, 
+			       int nPoints,
+			       std::vector<WorldVector<double> > &x, std::vector<double> &y)
+{ FUNCNAME("Helpers::interpolOverLine()");
+
+  WorldVector<double> p;
+  bool inside;
+
+  if (nPoints <= 1)
+    throw(std::runtime_error("Zu wenig Punkte fuer eine Interpolation!"));
+  
+  for (int i = 0; i < nPoints; ++i) {
+    double lambda = static_cast<double>(i)/static_cast<double>(nPoints - 1.0);
+    p[0] = lambda*x2 + (1.0-lambda)*x1;
+    p[1] = lambda*y2 + (1.0-lambda)*y1;
+    
+    double value = vec.evalAtPoint(p);
+    x.push_back(p);
+    y.push_back(value);
+  }
+};
diff --git a/extensions/MeshFunction_Level.h b/extensions/MeshFunction_Level.h
new file mode 100644
index 0000000000000000000000000000000000000000..71eb8feb15ab432ddac2afc0d47befd899cb94b2
--- /dev/null
+++ b/extensions/MeshFunction_Level.h
@@ -0,0 +1,326 @@
+/** \file MeshFunction_Level.h */
+
+#ifndef MESH_FUNCTION_LEVEL_H
+#define MESH_FUNCTION_LEVEL_H
+
+using namespace AMDiS;
+
+
+/** \brief
+ * Base-Implementation of a MeshRefinementFunction for refinement of phase-field
+ * interfaces. operator() must be overwritten in subclasses. Class provides
+ * basic parameters for the refinement like refinement-level values on interface
+ * or in the interesting domain and defines the refinement range for the phase-
+ * field variable, i.e. interface is defined in [0.05, 0.95]
+ **/
+template<typename T>
+class PhaseFieldRefinementBase : public MeshRefinementFunction<T, int>
+{
+public:
+
+  PhaseFieldRefinementBase(Mesh *mesh) : 
+    MeshRefinementFunction<T, int>(mesh),
+    lInner(10),
+    lOuter(10),
+    lInterface(14),
+    minPhase(0.05),
+    maxPhase(0.95),
+    minOuterPhase(0.001),
+    maxOuterPhase(0.999)
+  {
+      Parameters::get("mesh->refinement->level in inner domain",lInner);
+      Parameters::get("mesh->refinement->level in outer domain",lOuter);
+      Parameters::get("mesh->refinement->level on interface",lInterface);
+
+      lInterface-= mesh->getMacroElementLevel();
+      lInner-= mesh->getMacroElementLevel();
+      lOuter-= mesh->getMacroElementLevel();
+
+      int local_globalSize = 10;
+      Parameters::get("mesh->refinement->initial level", local_globalSize);
+      MeshRefinementFunction<T, int>::globalSize = local_globalSize;
+
+      Parameters::get("mesh->refinement->min interface value",minPhase);
+      Parameters::get("mesh->refinement->max interface value",maxPhase);
+      Parameters::get("mesh->refinement->min outer interface value",minOuterPhase);
+      Parameters::get("mesh->refinement->max outer interface value",maxOuterPhase);
+  }
+
+  double meshSize() { return levelToH(MeshRefinementFunction<T, int>::globalSize); }
+
+protected:
+
+  int lInner;
+  int lOuter;
+  int lInterface;
+  
+  double minPhase;
+  double maxPhase;
+  double minOuterPhase;
+  double maxOuterPhase;
+};
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the regions for interface refinement and domain refinement, etc.
+ **/
+class PhaseFieldRefinement : public PhaseFieldRefinementBase<double>
+{
+public:
+
+    PhaseFieldRefinement(Mesh* mesh_) : PhaseFieldRefinementBase<double>(mesh_) {};
+    
+    int operator()(const double& phase) const {
+      int result= lOuter;
+      if (minPhase < phase && phase < maxPhase)
+        result= lInterface;         // auf dem Interface
+      else if (phase > minOuterPhase && phase <= minPhase)
+        result= std::max(lOuter, static_cast<int>(floor((lOuter+lInterface)/2.0)));
+      else if (phase < maxOuterPhase && phase >= maxPhase)
+        result= std::max(lInner, static_cast<int>(floor((lInner+lInterface)/2.0)));
+      else if (phase > (minPhase+maxPhase)/2.0)
+        result= lInner;
+      return result;
+    }
+};
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the regions for interface refinement and domain refinement, etc.
+ * Additionally to the phase-field value a list of refinement points can be given
+ * where the mesh should be refined up to the a given level, e.g. in corners of 
+ * the macro-mesh.
+ **/
+class PhaseFieldCoordsRefinement : public PhaseFieldRefinementBase< std::pair<WorldVector<double>, double> >
+{
+public:
+    PhaseFieldCoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_) :
+      PhaseFieldRefinementBase< std::pair<WorldVector<double>, double> >(mesh_),
+      points(points_),
+      radius(radius_),
+      lPoints(14)
+    {
+        Parameters::get("mesh->refinement->level on points",lPoints);
+        lPoints-= mesh->getMacroElementLevel();
+    }
+    
+    int operator()(const std::pair<WorldVector<double>, double>& data) const {
+      double phase = data.second;
+      int result= lOuter;
+      if (minPhase < phase && phase < maxPhase)
+        result = lInterface;         // auf dem Interface
+      else if ((phase > minOuterPhase && phase <= minPhase) || (phase < maxOuterPhase && phase >= maxPhase))
+        result = std::max(lInner, static_cast<int>(floor((lOuter+lInterface)/2.0)));
+      else if (phase > 0.5)
+        result = lInner;
+
+      WorldVector<double> x = data.first;
+      double minDist = 1.e15;
+      for (unsigned i = 0; i < points.size(); ++i) {
+        minDist = std::min(minDist, norm(points[i]-x));
+      }
+      double lambda = std::max(0.0, 1.0 - minDist/radius);
+      result = std::max(result, static_cast<int>(floor(lOuter+lambda*(lPoints-lOuter))));
+
+      return result;
+    }
+    
+private:
+
+    int lPoints;
+
+    std::vector<WorldVector<double> > points;
+
+    double radius;
+};
+
+
+/** \brief
+ * Implementation of MeshRefinementFunction. Provides the method operator()
+ * that defines a list of refinement points where the mesh should be refined 
+ * up to the a given level, e.g. in corners of the macro-mesh.
+ **/
+class CoordsRefinement : public MeshRefinementFunction< WorldVector<double>, int >
+{
+public:
+    CoordsRefinement(Mesh* mesh_, std::vector<WorldVector<double> > points_, double radius_) 
+    :
+    MeshRefinementFunction< WorldVector<double>, int >(mesh_),
+    points(points_),
+    radius(radius_)
+    {
+        lInner= 15; lPoints = 20;
+        Parameters::get("mesh->refinement->level on points",lPoints);
+        Parameters::get("mesh->refinement->level in inner domain",lInner);
+        lPoints-= mesh->getMacroElementLevel();
+        lInner-= mesh->getMacroElementLevel();
+
+        globalSize= lInner;
+    }
+    
+    int operator()(const WorldVector<double>& x) const {
+      double minDist = 1.e15;
+      for (unsigned i = 0; i < points.size(); ++i) {
+        minDist = std::min(minDist, norm(points[i]-x));
+      }
+      int result = lInner;
+      double lambda = std::max(0.0, 1.0 - minDist/radius);
+      result = std::max(result, static_cast<int>(floor(lInner+lambda*(lPoints-lInner))));
+
+      return result;
+    }
+    double meshSize() { return levelToH(lInner); }
+    
+private:
+    int lInner, lPoints;
+    std::vector<WorldVector<double> > points;
+    double radius;
+};
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the level of refinement depending on a list of phase-fields, e.g.
+ * a diffuse-domain representation and a Cahn-Hilliard field.
+ **/
+class PhaseFieldChRefinement : public PhaseFieldRefinementBase< std::vector<double> >
+{
+public:
+  PhaseFieldChRefinement(Mesh* mesh_) 
+  :
+  PhaseFieldRefinementBase< std::vector<double> >(mesh_),
+  lInterfaceDomain(14)
+  {
+    Parameters::get("mesh->refinement->level on domain interface",lInterfaceDomain);
+    lInterfaceDomain-= mesh->getMacroElementLevel();
+    
+    Parameters::get("mesh->refinement->initial level", globalSize);
+  }
+  
+  int operator()(const std::vector<double>& phases) const 
+  {
+    int result= lOuter;
+    for (unsigned i = 0; i < phases.size(); ++i) {
+      int localResult= lOuter;
+      if (minPhase < phases[i] && phases[i] < maxPhase
+        && (i < 1 || phases[i-1] > 0.5))
+        localResult= (i==0 ? lInterfaceDomain : lInterface);         // auf dem Interface
+      else if (phases[i] > 0.5
+        && (i < 1 || phases[i-1] > 0.5))
+        localResult= lInner;            // im Innern des Gebietes
+      if (((phases[i] > minOuterPhase && phases[i] <= minPhase) || (phases[i] < maxOuterPhase && phases[i] >= maxPhase))
+        && (i < 1 || phases[i-1] > 0.5))
+        localResult= static_cast<int>(floor((lInner + lInterface) / 2.0));
+      result= std::max(result, localResult);
+    }
+    return result;
+  }
+    
+private:
+
+  int lInterfaceDomain;
+};
+
+
+/** \brief
+ * Base-Implementation of a MeshRefinementFunction for refinement of phase-field
+ * interfaces. operator() must be overwritten in subclasses. Class provides
+ * basic parameters for the refinement like refinement-level values on interface
+ * or in the interesting domain and defines the refinement range for the phase-
+ * field variable, i.e. interface is defined in [0.05, 0.95]
+ **/
+template<typename T>
+class SignedDistRefinementBase : public MeshRefinementFunction<T, int>
+{
+public:
+
+  SignedDistRefinementBase(Mesh *mesh) :
+    MeshRefinementFunction<T, int>(mesh),
+    lInner(10),
+    lOuter(10),
+    lInterface(14),
+    interfaceWidth(0.2),
+    fadeOutWidth(0.0),
+    signInInnerDomain(-1.0)
+  {
+      Parameters::get("mesh->refinement->level in inner domain",lInner);
+      Parameters::get("mesh->refinement->level in outer domain",lOuter);
+      Parameters::get("mesh->refinement->level on interface",lInterface);
+
+      lInterface-= mesh->getMacroElementLevel();
+      lInner-= mesh->getMacroElementLevel();
+      lOuter-= mesh->getMacroElementLevel();
+
+      int local_globalSize = 10;
+      Parameters::get("mesh->refinement->initial level", local_globalSize);
+      MeshRefinementFunction<T, int>::globalSize = local_globalSize;
+
+      Parameters::get("mesh->refinement->interface width",interfaceWidth);
+      Parameters::get("mesh->refinement->fade out width",fadeOutWidth);
+      Parameters::get("mesh->refinement->sign in inner domain",signInInnerDomain);
+  }
+
+  double meshSize() { return levelToH(MeshRefinementFunction<T, int>::globalSize); }
+
+protected:
+
+  int lInner;
+  int lOuter;
+  int lInterface;
+
+  double interfaceWidth;
+  double fadeOutWidth;
+  double signInInnerDomain;
+};
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the regions for interface refinement and domain refinement, etc.
+ **/
+class SignedDistRefinement : public SignedDistRefinementBase<double>
+{
+public:
+
+    SignedDistRefinement(Mesh* mesh_) : SignedDistRefinementBase<double>(mesh_) {};
+
+    int operator()(const double& dist) const {
+      int result= lOuter;
+      if (abs(dist) < interfaceWidth)
+        result= lInterface;         // auf dem Interface
+      else if (abs(dist) < fadeOutWidth+interfaceWidth && signInInnerDomain*dist < 0.0) {
+	double lambda = abs(dist)/fadeOutWidth - interfaceWidth/fadeOutWidth;
+        result= static_cast<int>(floor(lambda*lInner+(1.0-lambda)*lInterface));
+      } else if (abs(dist) < fadeOutWidth+interfaceWidth && signInInnerDomain*dist > 0.0) {
+	double lambda = abs(dist)/fadeOutWidth - interfaceWidth/fadeOutWidth;
+        result= static_cast<int>(floor(lambda*lOuter+(1.0-lambda)*lInterface));
+      } else if (signInInnerDomain*dist < 0.0)
+        result= lInner;
+      return result;
+    }
+};
+
+class ESIndicator : public MeshRefinementFunction< std::vector<double>, int >
+{
+public:
+  ESIndicator(Mesh* mesh_) 
+  :
+  MeshRefinementFunction< std::vector<double>, int >(mesh_)
+  {
+    Parameters::get("mesh->refinement->initial level", globalSize);
+  }
+  
+  int operator()(const std::vector<double>& means) const 
+  {
+    double tol = means[0];
+    return (abs(means[1]-means[2]) > tol ? 0 : -1);
+  }
+    
+  double indicator(const std::vector<double>& means) const 
+  {
+    return abs(means[1]-means[2]);
+  }
+};
+#endif // MESH_FUNCTION_LEVEL
diff --git a/extensions/MeshIndicator.h b/extensions/MeshIndicator.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b3e86522c3111bf50329bdafeb2ac10171b534d
--- /dev/null
+++ b/extensions/MeshIndicator.h
@@ -0,0 +1,369 @@
+/** \file MeshIndicator.h */
+
+#ifndef MESH_INDICATOR_H
+#define MESH_INDICATOR_H
+
+#include "AMDiS.h"
+
+using namespace AMDiS;
+
+namespace tools {
+
+  struct MeshIndicator
+  {
+    MeshIndicator(WorldVector<double> dimension_) : boundary_index(0), dimension(dimension_) { }
+
+    MeshIndicator(Mesh* mesh) : boundary_index(0)
+    {
+      dimension = Helpers::getMeshDimension(mesh);
+    }
+
+    virtual bool operator()(const WorldVector<double>& x) const
+    {
+      return true;
+    }
+
+    virtual bool operator()(const ElInfo* elInfo) const
+    {
+      bool result = true;
+      for (int i = 0; i < elInfo->getMesh()->getDim()+1; i++) {
+	result = result && operator()(elInfo->getCoord(i));
+	if (!result)
+	  break;
+      }
+      return true;
+    }
+
+    void set_boundary_index(int boundary_index_)
+    {
+      boundary_index = boundary_index_;
+    }
+
+  protected:
+
+    bool on_boundary()
+    {
+      return boundary_index != 0;
+    }
+
+  protected:
+
+    int boundary_index;
+    WorldVector<double> dimension;
+  };
+
+
+  template<typename T>
+  T integrate(const DOFVector<T> &vec, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrate(MeshIndicator)");
+
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    int deg = 2 * vec.getFeSpace()->getBasisFcts()->getDegree();
+    Quadrature* quad =
+      Quadrature::provideQuadrature(vec.getFeSpace()->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(vec.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
+
+    mtl::dense_vector<T> qp(fastQuad->getNumPoints());
+
+    T value; nullify(value);
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(vec.getFeSpace()->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
+	T tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  tmp += fastQuad->getWeight(iq) * qp[iq];
+	}
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+
+  template<typename TOut>
+  TOut integrate_Coords(const FiniteElemSpace* feSpace,
+		    AbstractFunction<TOut, WorldVector<double> > *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrate_Coords()");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    int deg = std::max(fct->getDegree(), feSpace->getBasisFcts()->getDegree());
+    Quadrature* quad =
+      Quadrature::provideQuadrature(feSpace->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *quad, INIT_PHI);
+
+    WorldVector<double> coords;
+
+    TOut value; nullify(value);
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  elInfo->coordToWorld(fastQuad->getLambda(iq), coords);
+	  tmp += fastQuad->getWeight(iq) * (*fct)(coords);
+	}
+
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+  template<typename TOut, typename T>
+  TOut integrate_Vec(const DOFVector<T> &vec, AbstractFunction<TOut, T> *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrate(MeshIndicator)");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    int deg = std::max(fct->getDegree(),
+			2 * vec.getFeSpace()->getBasisFcts()->getDegree());
+
+    Quadrature* quad =
+      Quadrature::provideQuadrature(vec.getFeSpace()->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(vec.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
+
+    mtl::dense_vector<T> qp(fastQuad->getNumPoints());
+
+    TOut value; nullify(value);
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(vec.getFeSpace()->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  tmp += fastQuad->getWeight(iq) * (*fct)(qp[iq]);
+	}
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+
+  template<typename TOut, typename T1, typename T2>
+  TOut integrate_Vec2(const DOFVector<T1> &vec1,
+		    const DOFVector<T2> &vec2,
+		    BinaryAbstractFunction<TOut, T1, T2> *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("intDualmesh()");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    int deg = std::max(fct->getDegree(),
+			2 * vec1.getFeSpace()->getBasisFcts()->getDegree());
+    Quadrature* quad =
+      Quadrature::provideQuadrature(vec1.getFeSpace()->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(vec1.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
+
+    mtl::dense_vector<T1> qp1(fastQuad->getNumPoints());
+    mtl::dense_vector<T2> qp2(fastQuad->getNumPoints());
+
+    TOut value; nullify(value);
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(vec1.getFeSpace()->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	vec1.getVecAtQPs(elInfo, quad, fastQuad, qp1);
+	vec2.getVecAtQPs(elInfo, quad, fastQuad, qp2);
+
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++)
+	  tmp += fastQuad->getWeight(iq) * (*fct)(qp1[iq], qp2[iq]);
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+
+  template<typename T1, typename T2>
+  typename ProductType<T1,T2>::type integrate_VecTimesCoords(const DOFVector<T1> &vec,
+		    AbstractFunction<T2, WorldVector<double> > *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrate_VecTimesCoords()");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    typedef typename ProductType<T1,T2>::type TOut;
+
+    const FiniteElemSpace *feSpace = vec.getFeSpace();
+    Mesh *mesh = feSpace->getMesh();
+
+    int deg = std::max(fct->getDegree(), 2 * feSpace->getBasisFcts()->getDegree());
+    Quadrature* quad = Quadrature::provideQuadrature(mesh->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(feSpace->getBasisFcts(), *quad, INIT_PHI);
+
+    mtl::dense_vector<T1> qp(fastQuad->getNumPoints());
+    WorldVector<double> coords;
+
+    TOut value; nullify(value);
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
+
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  elInfo->coordToWorld(fastQuad->getLambda(iq), coords);
+	  tmp += fastQuad->getWeight(iq) * (qp[iq] * (*fct)(coords));
+	}
+
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+
+  template<typename TOut, typename T>
+  TOut integrate_VecAndCoords(const DOFVector<T> &vec,
+			    BinaryAbstractFunction<TOut, T, WorldVector<double> > *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrate_VecAndCoords()");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(meshIndicator)("No MeshIndicator defined!\n");
+
+    int deg = std::max(fct->getDegree(),
+			2 * vec.getFeSpace()->getBasisFcts()->getDegree());
+    Quadrature* quad =
+      Quadrature::provideQuadrature(vec.getFeSpace()->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(vec.getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
+
+    mtl::dense_vector<T> qp(fastQuad->getNumPoints());
+    WorldVector<double> coordsAtQP;
+
+    TOut value; nullify(value);
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(vec.getFeSpace()->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	vec.getVecAtQPs(elInfo, quad, fastQuad, qp);
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  elInfo->coordToWorld(fastQuad->getLambda(iq), coordsAtQP);
+	  tmp += fastQuad->getWeight(iq) * (*fct)(qp[iq], coordsAtQP);
+	}
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+  #endif
+
+    return value;
+  }
+
+
+  template<typename TOut, typename T>
+  TOut integrateGeneral(const std::vector<DOFVector<T>*> &vecs,
+		       AbstractFunction<TOut, std::vector<T> > *fct, MeshIndicator *meshIndicator)
+  {
+    FUNCNAME("integrateGeneral()");
+
+    TEST_EXIT(fct)("No function defined!\n");
+    TEST_EXIT(vecs.size()>0)("No DOFVectors provided!\n");
+
+    int deg = std::max(fct->getDegree(),
+		       2 * vecs[0]->getFeSpace()->getBasisFcts()->getDegree());
+    Quadrature* quad =
+      Quadrature::provideQuadrature(vecs[0]->getFeSpace()->getMesh()->getDim(), deg);
+    FastQuadrature *fastQuad =
+      FastQuadrature::provideFastQuadrature(vecs[0]->getFeSpace()->getBasisFcts(), *quad, INIT_PHI);
+
+    std::vector<mtl::dense_vector<T> > qp(vecs.size());
+    std::vector<T> qp_local(vecs.size());
+    for (size_t i = 0; i < vecs.size(); i++)
+      qp[i].change_dim(fastQuad->getNumPoints());
+
+    TOut value; nullify(value);
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS | Mesh::FILL_DET;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(vecs[0]->getFeSpace()->getMesh(), -1, traverseFlag);
+    while (elInfo) {
+      if ((*meshIndicator)(elInfo)) {
+	for (size_t i = 0; i < vecs.size(); i++)
+	  vecs[i]->getVecAtQPs(elInfo, quad, fastQuad, qp[i]);
+
+	TOut tmp; nullify(tmp);
+	for (int iq = 0; iq < fastQuad->getNumPoints(); iq++) {
+	  for (size_t i = 0; i < vecs.size(); i++)
+	    qp_local[i] = qp[i][iq];
+	  tmp += fastQuad->getWeight(iq) * (*fct)(qp_local);
+	}
+	value += tmp * elInfo->getDet();
+      }
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+    #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+    mpi::globalAdd(value);
+    #endif
+
+    return value;
+  }
+  
+} // namespace tools
+
+#endif // MESH_INDICATOR_H
diff --git a/extensions/MetaTools.h b/extensions/MetaTools.h
new file mode 100644
index 0000000000000000000000000000000000000000..d2f946427687b58440c98778971189c89761b8fc
--- /dev/null
+++ b/extensions/MetaTools.h
@@ -0,0 +1,518 @@
+/** \file MetaTools.h */
+
+#ifndef META_TOOLS_H
+#define META_TOOLS_H
+
+// #include "AMDiS.h"
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/arithmetic.hpp>
+#include <boost/mpl/comparison.hpp>
+#include <boost/mpl/logical.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#define GET_LOOP_INDEX(VAR, SEQ, IDX) static const long VAR = boost::mpl::at_c<SEQ,IDX>::type::value;
+
+// namespace boost {
+//   namespace fusion {
+//     template<int I> inline double at_c(WorldVector<double> &x) { return x[I]; }
+//   }
+// }
+
+namespace tools {
+    
+  /// binomial coefficients
+  /// _______________________________________________________________________________
+  
+  namespace details {
+
+    template <int N, int K, bool N_pos = true, bool K_pos = true>
+    struct Binomial
+    {
+      BOOST_STATIC_CONSTANT(int, value = (details::Binomial<N-1, K-1, (N-1>0), (K-1>0) >::value
+					+ details::Binomial<N-1, K,   (N-1>0), (K>0)   >::value) );
+    };
+    
+    template <int N, bool N_pos>
+    struct Binomial<N, N, N_pos, true> // K > 0, N > 0, K==N
+    {
+      BOOST_STATIC_CONSTANT(int, value = 1);
+    };
+    
+    template <int N, int K, bool N_pos>
+    struct Binomial<N, K, N_pos, false> // K <= 0
+    {
+      BOOST_STATIC_CONSTANT(int, value = 1);
+    };
+    
+    template <int N, int K>
+    struct Binomial<N, K, false, true> // K > 0, N <= 0
+    {
+      BOOST_STATIC_CONSTANT(int, value = 0);
+    };
+  }
+  
+  // interface to calc binomial coefficients (N, K) at compile-time for N,K >= 0
+  template <int N, int K>
+  struct Binomial
+  {
+    BOOST_STATIC_CONSTANT(int, value = (details::Binomial<N, K, (N>0), (K>0)>::value) );
+  };
+
+  /// some mathematical basics
+  /// ____________________________________________________________________________
+  
+  // check divisibility
+  template <int u, int v>
+  struct Divisible
+  {
+    BOOST_STATIC_CONSTANT(bool, value = u % v == 0 ? true : false );
+  };
+    
+  // check divide by zero condition
+  template <int u>
+  struct Divisible<u, 0>
+  {
+    BOOST_STATIC_CONSTANT(bool, value = false ); // better: static assert
+  };
+  
+  // check number is even or not
+  template <int u>
+  struct IsEven
+  {
+    BOOST_STATIC_CONSTANT(bool, value = (Divisible<u, 2>::value) );
+  };
+    
+  // check number is odd or not
+  template <int u>
+  struct IsOdd
+  {
+    BOOST_STATIC_CONSTANT(bool, value = (-Divisible<u, 2>::value) );
+  };
+  
+  template <int N>
+  struct Abs
+  {
+    BOOST_STATIC_CONSTANT(bool, value = (N >= 0) ? N : -N );
+  };
+  
+  // greatest common devisor and least common multiple
+  // ________________________________________________________________________
+
+  // calculate gcd
+  template <int u, int v>
+  struct Gcd
+  {
+    BOOST_STATIC_CONSTANT(int, value = (Gcd<v, u % v>::value) );
+  };
+    
+  template <int u>
+  struct Gcd<u, 0>
+  {
+    BOOST_STATIC_CONSTANT(int, value = u );
+  };
+    
+  template <>
+  struct Gcd<0, 0>
+  {
+    BOOST_STATIC_CONSTANT(int, value = -1 );
+  };
+  
+  // calculate lcm
+  template <int u, int v>
+  struct Lcm
+  {
+    BOOST_STATIC_CONSTANT(int, value = (Abs<u * v>::value / Gcd<u, v>::value) );
+  };
+  
+  
+  // powers of values
+  // _______________________________________________________________________________
+  
+  // to calculate the power
+  template <int a, int p>
+  struct Pow
+  {
+    BOOST_STATIC_CONSTANT(int, value = (a * Pow<a, p-1>::value) );
+  };
+  
+  template <int a>
+  struct Pow<a, 1>
+  {
+    BOOST_STATIC_CONSTANT(int, value = a );
+  };
+  
+  template <int a>
+  struct Pow<a, 0>
+  {
+    BOOST_STATIC_CONSTANT(int, value = 1 );
+  };
+  
+  template <int n>
+  struct Sqr
+  {
+    BOOST_STATIC_CONSTANT(int, value = (Pow<n, 2>::value) );
+  };
+  
+  // roots of values
+  // _______________________________________________________________________________
+  
+  // template to compute sqrt(N) via iteration
+  template <int a, int I=1>
+  struct Sqrt {
+      // instantiate next step or result type as branch
+      typedef typename boost::mpl::if_c< (I*I < a),
+					Sqrt<a, I+1>,
+					boost::mpl::int_<I>
+				      >::type impl;
+
+      // use the result of branch type
+      BOOST_STATIC_CONSTANT(int, value = impl::value );
+  };
+  
+  // partial specialization to end the iteration
+  template<int a>
+  struct Sqrt<a, a> {
+    BOOST_STATIC_CONSTANT(int, value = a );
+  };
+  template<int I>
+  struct Sqrt<0, I> {
+    BOOST_STATIC_CONSTANT(int, value = 0 );
+  };
+  
+  // template to compute sqrt(N) via iteration
+  template <int a, int N, int I=1>
+  struct Root {
+    // instantiate next step or result type as branch
+    typedef typename boost::mpl::if_c<Pow<I, N>::value < a,
+				      Root<a, N, I+1>,
+				      boost::mpl::int_<I>
+				    >::type impl;
+
+    // use the result of branch type
+    BOOST_STATIC_CONSTANT(int, value = impl::value );
+  };
+  
+  // partial specialization to end the iteration
+  template<int a, int N>
+  struct Root<a, N, a> {
+    BOOST_STATIC_CONSTANT(int, value = a );
+  };
+  template<int N, int I>
+  struct Root<0, N, I> {
+    BOOST_STATIC_CONSTANT(int, value = 0 );
+  };
+  
+  
+  /// monomials and polynomials
+  /// _______________________________________________________________________________
+
+  template<int N>
+  struct Monomial {
+    typedef double result_type;
+    result_type operator()(double x) { return x*Monomial<N-1>()(x); }
+  };
+  
+  template<>
+  struct Monomial<1> {
+    typedef double result_type;
+    result_type operator()(double x) { return x; }
+  };
+  
+  template<>
+  struct Monomial<0> {
+    typedef double result_type;
+    result_type operator()(double x) { return 1.0; }
+  };
+
+  template<typename Coefficients, int I, int N>
+  struct Horner {
+    typedef double result_type;
+    Horner(Coefficients& coefficients_) : coefficients(coefficients_) {}
+    result_type operator()(double x) {
+      return boost::fusion::at_c<I>(coefficients) + x*(Horner<Coefficients, I+1, N>(coefficients)(x));
+    }
+  private:
+    Coefficients& coefficients;
+  };
+
+  template<typename Coefficients, int N>
+  struct Horner<Coefficients, N, N> {
+    typedef double result_type;
+    Horner(Coefficients& coefficients_) : coefficients(coefficients_) {}
+    result_type operator()(double x) {
+      return boost::fusion::at_c<N>(coefficients);
+    }
+  private:
+    Coefficients& coefficients;
+  };
+
+  template<typename Coefficients>
+  struct Polynomial {
+    typedef double result_type;
+    Polynomial(Coefficients& coefficients_) : coefficients(coefficients_) {}
+    result_type operator()(double x) {
+      return Horner<Coefficients, 0, boost::fusion::result_of::size<Coefficients>::value - 1>(coefficients)(x);
+    }
+  private:
+    Coefficients& coefficients;
+  };
+  
+  /// Bernstein polynomials and Bezier-Surfaces
+  /// ____________________________________________________________________________
+  
+  template<int I, int order>
+  struct BernsteinPolynomial 
+  {
+    static inline double value(double x) {
+      return Binomial<order, I>::value
+	      * std::pow(x, I) * std::pow(1.0 - x, order - I);
+    }
+  };
+  
+  template<int I, int order, bool valid = true>
+  struct BernsteinPolynomial_
+  {
+    static inline double value(double x) {
+      return (1.0 - x) * BernsteinPolynomial_<I, order - 1, I >= 0 && I <= (order-1)>::value(x)
+	+ x * BernsteinPolynomial_<I - 1, order - 1, (I-1) >= 0 && (I-1) <= (order-1)>::value(x);
+    }
+  };
+  
+  template<>
+  struct BernsteinPolynomial_<0, 0, true>
+  {
+    static inline double value(double x) {
+      return 1.0;
+    }
+  };
+  
+  template<int I, int order>
+  struct BernsteinPolynomial_<I, order, false>
+  {
+    static inline double value(double x) {
+      return 0.0;
+    }
+  };
+  
+  template<int I, int J, int order>
+  struct BernsteinPolynomial2
+  {
+    static inline double value(double x, double y) {
+      return BernsteinPolynomial<I, order>::value(x) * BernsteinPolynomial<J, order>::value(x);
+    }
+  };
+  
+  template<int I, int J, int K, int order>
+  struct BernsteinPolynomial3
+  {
+    static inline double value(double x, double y, double z) {
+      return BernsteinPolynomial<I, order>::value(x) * BernsteinPolynomial<J, order>::value(x) * BernsteinPolynomial<K, order>::value(z);
+    }
+  };
+  
+  // Bezier-Polynomial
+  //________________________________________________________________________
+  
+  namespace details {
+    
+    // sum_{I=0}^N B_I^N(x)*c_I
+    template<int I, int N>
+    struct BezierPolynomial
+    {
+      template<typename Coefficients>
+      static double value(Coefficients& coefficients, double x) {
+	return boost::fusion::at_c<I>(coefficients)*BernsteinPolynomial<I, N>::value(x) + details::BezierPolynomial<I+1, N>::value(coefficients, x);
+      }
+    };
+    
+    template<int N>
+    struct BezierPolynomial<N, N>
+    {
+      template<typename Coefficients>
+      static double value(Coefficients& coefficients, double x) {
+	return boost::fusion::at_c<N>(coefficients)*BernsteinPolynomial<N,N>::value(x);
+      }
+    };
+  }
+  
+  template<typename Coefficients, int DOW=1>
+  struct BezierPolynomial
+  {
+    BOOST_STATIC_CONSTANT(int, N = (boost::mpl::minus< boost::mpl::int_< Root< boost::fusion::result_of::size<Coefficients>::value, 
+									       DOW >::value >, 
+						      boost::mpl::int_<1> >::type::value) ); // N = rootN(coeff.size, DOW)-1
+    
+    BezierPolynomial(Coefficients& coefficients_) : coefficients(coefficients_) {}
+    double value(double x) {
+      return details::BezierPolynomial<0, N>::value(coefficients, x);
+    }
+  private:
+    Coefficients& coefficients;
+  };
+
+  // Bezier-Polynomial 2d
+  //________________________________________________________________________
+  
+  namespace details {
+    
+    template<int IJ, int N, bool finished=false> // IJ = I + J*N, max(IJ) = N*N - 2
+    struct BezierPolynomial2
+    {
+      template<typename Coefficients>
+      static double value(Coefficients& coefficients, double x, double y) {
+	return boost::fusion::at_c<N>(coefficients) * BernsteinPolynomial2<IJ%N, IJ/N, N>::value(x, y)
+	  + details::BezierPolynomial2<IJ + 1, N, IJ == (N+1)*(N+1)>::value(coefficients, x, y);
+      }
+    };
+    
+    template<int IJ, int N>
+    struct BezierPolynomial2<IJ, N, true>
+    {
+      template<typename Coefficients>
+      static double value(Coefficients& coefficients, double x, double y) {
+	return 0.0;
+      }
+    };
+  }
+    
+  // interface for bezier-surfaces of order (N,N)
+  template<typename Coefficients>
+  struct BezierPolynomial2
+  {
+    BOOST_STATIC_CONSTANT(int, N = (boost::mpl::minus< 
+				      boost::mpl::int_<
+					Root<
+					  boost::fusion::result_of::size<Coefficients>::value, 
+					  2
+					>::value
+				      >, 
+				      boost::mpl::int_<1>
+				    >::type::value) ); // N = rootN(coeff.size, 2)-1
+    
+    BezierPolynomial2(Coefficients& coefficients_) : coefficients(coefficients_) {} 
+    double value(double x, double y) {
+      return details::BezierPolynomial2<0, N, N == 0>::value(coefficients, x, y);
+    }
+  private:
+    Coefficients& coefficients; // p in points is element of result_type
+  };
+  
+  
+  /// for loops: for<i, n [,{incr,decr}]>, for<mpl::range_c>, for<mpl::vector_c>
+  ///____________________________________________________________________________
+
+  template<int I> struct incr { BOOST_STATIC_CONSTANT(int, value = I+1); };
+  template<int I> struct decr { BOOST_STATIC_CONSTANT(int, value = I-1); };
+
+  template<int I, int N, template<int> class op, bool finished, template<int> class F>
+  struct FOR_LOOP {
+    static void loop() {
+      F<I>::eval(); // your implementation here
+      FOR_LOOP<op<I>::value, N, op, op<I>::value == N, F>::loop();
+    }
+  };
+
+  // initial/break condition for 'for-loop': e.g. I==N
+  template<int I, int N, template<int> class op, template<int> class F> 
+  struct FOR_LOOP<I, N, op, true, F> 
+  {
+    static void loop() {}
+  };
+
+  // 'for-loop', for I<N
+  template<int I, int N, bool plus, bool finished, template<int> class F> 
+  struct FOR_LOOP_CHECK 
+  {
+    static void loop() { FOR_LOOP<I, N, incr, finished, F>::loop(); }
+  };
+
+  // 'for-loop', for I>N
+  template<int I, int N, bool finished, template<int> class F> 
+  struct FOR_LOOP_CHECK<I,N,false,finished, F> 
+  {
+    static void loop() { FOR_LOOP<I, N, decr, finished, F>::loop(); }
+  };
+
+  // interface for classical for loop: for j=I..N
+  // the index will be incremented, if I<N and decremented otherwise
+  template<int I, int N, template<int> class F> 
+  struct FOR 
+  { 
+    static void loop() { FOR_LOOP_CHECK<I, N, I < N, I == N, F>::loop(); } 
+  };
+
+  // 'for-loop' over sequence of values
+  template<typename Seq, long I, long N, template<int> class F>
+  struct FOR_SUBSEQ
+  {
+    static void loop() {
+      GET_LOOP_INDEX (i, Seq, I);
+      F<i>::eval(); // your implementation here
+      FOR_SUBSEQ<Seq, I+1, N, F>::loop();
+    }
+  };
+
+  // initial/break condition for 'for-loop' over sequences: I==N
+  template<typename Seq, long N, template<int> class F> 
+  struct FOR_SUBSEQ<Seq,N,N,F> 
+  { 
+    static void loop() {} 
+  };
+
+  // interface for loop over sequence of values
+  // for i in {seq[0]..seq[end]}
+  template<typename Seq, template<int> class F> 
+  struct FOR_SEQ 
+  { 
+    static void loop() { FOR_SUBSEQ<Seq, 0, boost::mpl::size<Seq>::value, F>::loop(); } 
+  };
+
+
+  /// for-each loops
+  ///____________________________________________________________________________
+
+  template<int I> struct for_each
+  {
+    template<typename Container1, typename Container2, typename Binary_Functor>
+    static void eval(Container1& vec1, Container2& vec2, Binary_Functor& f);
+    
+    template<typename Container1, typename Container2, typename T, typename Tertiary_Functor>
+    static void accumulate(Container1& vec1, Container2& vec2, T& value, Tertiary_Functor& f);
+  };
+
+  template<> struct for_each<0>
+  {
+    template<typename Container1, typename Container2, typename Binary_Functor>
+    static void eval(Container1& vec1, Container2& vec2, Binary_Functor& f);
+
+    template<typename Container1, typename Container2, typename T, typename Tertiary_Functor>
+    static void accumulate(Container1& vec1, Container2& vec2, T& value, Tertiary_Functor& f);
+  };
+
+  template<int I>
+  template<typename Container1, typename Container2, typename Binary_Functor>
+  void for_each<I>::eval(Container1& vec1, Container2& vec2, Binary_Functor& f) {
+    f(boost::fusion::at_c<I>(vec1), boost::fusion::at_c<I>(vec2));
+    for_each<I-1>::eval(vec1,vec2,f);
+  };
+
+  template<int I>
+  template<typename Container1, typename Container2, typename T, typename Tertiary_Functor>
+  void for_each<I>::accumulate(Container1& vec1, Container2& vec2, T& value, Tertiary_Functor& f) {
+    f(boost::fusion::at_c<I>(vec1), boost::fusion::at_c<I>(vec2), value);
+    for_each<I-1>::accumulate(vec1,vec2,value,f);
+  };
+
+  template<typename Container1, typename Container2, typename Binary_Functor>
+  void for_each<0>::eval(Container1& vec1, Container2& vec2, Binary_Functor& f) {
+    f(boost::fusion::at_c<0>(vec1), boost::fusion::at_c<0>(vec2));
+  };
+
+  template<typename Container1, typename Container2, typename T, typename Tertiary_Functor>
+  void for_each<0>::accumulate(Container1& vec1, Container2& vec2, T& value, Tertiary_Functor& f) {
+    f(boost::fusion::at_c<0>(vec1), boost::fusion::at_c<0>(vec2),value);
+  };
+  
+} // namespace tools
+
+#endif // META_TOOLS_H
diff --git a/extensions/NewtonCotesQuad.h b/extensions/NewtonCotesQuad.h
new file mode 100644
index 0000000000000000000000000000000000000000..878689d6a388871863299aeaf386affea53f99fd
--- /dev/null
+++ b/extensions/NewtonCotesQuad.h
@@ -0,0 +1,138 @@
+/** \file NewtonCotesQuad.h */
+
+#ifndef NEWTON_COTES_QUAD_H
+#define NEWTON_COTES_QUAD_H
+
+#include <boost/array.hpp>
+#include "Tools.h"
+
+namespace tools {
+  
+  template<int deg>
+  struct NewtonCotesQuad
+  {
+    typedef boost::array<double,1> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      ERROR("ERROR: no, or unknown degree, for quadrature rule given!\n");
+      static Container xi = {{0.0}};
+      static Container ci = {{1.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<1>
+  {
+    typedef boost::array<double,1> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{0.5}};
+      static Container ci = {{1.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<2>
+  {
+    typedef boost::array<double,2> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-0.5/sqrt(3.0)+0.5, 0.5/sqrt(3.0)+0.5}};
+      static Container ci = {{0.5, 0.5}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<3>
+  {
+    typedef boost::array<double,2> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-0.5/sqrt(3.0)+0.5, 0.5/sqrt(3.0)+0.5}};
+      static Container ci = {{0.5, 0.5}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<4>
+  {
+    typedef boost::array<double,3> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-sqrt(3.0/5.0)/2.0+0.5, 0.5, sqrt(3.0/5.0)/2.0+0.5}};
+      static Container ci = {{5.0/18.0, 8.0/18.0, 5.0/18.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<5>
+  {
+    typedef boost::array<double,3> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-sqrt(3.0/5.0)/2.0+0.5, 0.5, sqrt(3.0/5.0)/2.0+0.5}};
+      static Container ci = {{5.0/18.0, 8.0/18.0, 5.0/18.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<6>
+  {
+    typedef boost::array<double,4> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      -sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5}};
+      static Container ci = {{(18.0-sqrt(30.0))/72.0,
+			      (18.0+sqrt(30.0))/72.0,
+			      (18.0+sqrt(30.0))/72.0,
+			      (18.0-sqrt(30.0))/72.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+  template<>
+  struct NewtonCotesQuad<7>
+  {
+    typedef boost::array<double,4> Container;
+    typedef GeneralQuad<Container> type;
+
+    static type& provide()
+    {
+      static Container xi = {{-sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      -sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      sqrt(3.0/7.0 - 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5,
+			      sqrt(3.0/7.0 + 2.0/7.0 * sqrt(6.0/5.0))/2.0 + 0.5}};
+      static Container ci = {{(18.0-sqrt(30.0))/72.0,
+			      (18.0+sqrt(30.0))/72.0,
+			      (18.0+sqrt(30.0))/72.0,
+			      (18.0-sqrt(30.0))/72.0}};
+      return *(new type(xi,ci));
+    }
+  };
+
+} // end namespace
+
+#endif // NEWTON_COTES_QUAD_H
diff --git a/extensions/POperators.cc b/extensions/POperators.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0023fa8bf55d503fee12cab258316f5cd630eaec
--- /dev/null
+++ b/extensions/POperators.cc
@@ -0,0 +1,2286 @@
+#include "POperators.h"
+#include "Helpers.h"
+
+using namespace std;
+using namespace AMDiS;
+
+Phase_SOT::Phase_SOT(DOFVectorBase<double>* phaseDV_,double fac_) :
+	SecondOrderTerm(6), phaseDV(phaseDV_), fac(fac_)
+{
+	TEST_EXIT(phaseDV_)("no vector phase!\n");
+	auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void Phase_SOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) {
+	getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void Phase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad) {
+	getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void Phase_SOT::getLALt(const ElInfo *elInfo,
+			vector<mtl::dense2D<double> > &LALt) const
+{
+	const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+	for (int iq = 0; iq < nPoints; iq++)
+		l1lt(Lambda, LALt[iq], f(iq) * phase[iq] * fac);
+};
+void Phase_SOT::eval(int nPoints,
+			const mtl::dense_vector<double>& uhAtQP,
+			const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			mtl::dense_vector<double>& result,
+			double opFactor)
+{	
+	if (num_rows(D2UhAtQP) > 0) {
+		for (int iq = 0; iq < nPoints; iq++) {
+			double feval = f(iq) * phase[iq] * opFactor * fac;
+			double resultQP = 0.0;
+			for (int i = 0; i < dimOfWorld; i++)
+				resultQP += D2UhAtQP[iq][i][i];	
+			result[iq] += feval * resultQP;
+		}
+	}
+};
+void Phase_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+			std::vector<WorldVector<double> > &result)
+{
+	int nPoints = grdUhAtQP.size();
+	for (int iq = 0; iq < nPoints; iq++) {
+		double factor = f(iq) * phase[iq] * fac;
+		axpy(factor, grdUhAtQP[iq], result[iq]);
+	}
+};
+double Phase_SOT::f(const int iq) const
+{
+	return 1.0;
+};
+
+/* ----------------------------------------------------------- */
+
+Phase_FOT::Phase_FOT(DOFVectorBase<double>* phaseDV_,double fac_) :
+  FirstOrderTerm(6), phaseDV(phaseDV_), fac(fac_)
+{
+  TEST_EXIT(phaseDV_)("no vector phase!\n");
+  auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void Phase_FOT::initElement(const ElInfo* elInfo, 
+      SubAssembler* subAssembler,
+      Quadrature *quad) {
+  getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void Phase_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+      SubAssembler* subAssembler,
+      Quadrature *quad) {
+  getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void Phase_FOT::getLb(const ElInfo *elInfo, 
+            vector<mtl::dense_vector<double> >& result) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+    
+    for (int iq = 0; iq < nPoints; iq++) {
+        lb(Lambda, f(iq), result[iq], phase[iq]*fac);
+    }
+};
+void Phase_FOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    double factor = fac * opFactor;
+    for (int iq = 0; iq < nPoints; iq++) {
+        double resultQP = grdUhAtQP[iq] * f(iq);
+        result[iq] += phase[iq] * factor * resultQP;
+    }
+};
+WorldVector<double> Phase_FOT::f(const int iq) const
+{
+  WorldVector<double> result;
+  result.set(1.0);
+  return result;
+};
+
+/* ----------------------------------------------------------- */
+
+Phase_ZOT::Phase_ZOT(DOFVectorBase<double>* phaseDV_, double fac_) : ZeroOrderTerm(6),
+	phaseDV(phaseDV_), fac(fac_)
+{	
+	TEST_EXIT(phaseDV_)("No vector Phase!\n");
+	
+	auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void Phase_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void Phase_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void Phase_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += f(iq) * phase[iq] * fac;
+};
+void Phase_ZOT::eval(int nPoints,
+	const mtl::dense_vector<double>& uhAtQP,
+	const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+	const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+	mtl::dense_vector<double>& result,
+	double opFactor)
+{
+	double factor = opFactor * fac;
+	for (int iq = 0; iq < nPoints; iq++)
+		result[iq] += factor * f(iq) * phase[iq] * uhAtQP[iq];
+};
+double Phase_ZOT::f(const int iq) const
+{
+	return 1.0;
+};
+
+/* ----------------------------------------------------------- */
+
+PhaseInverse_ZOT::PhaseInverse_ZOT(DOFVectorBase<double>* phaseDV_, double fac_) : ZeroOrderTerm(6),
+	phaseDV(phaseDV_), fac(fac_), component(0)
+{	
+	TEST_EXIT(phaseDV_)("No vector Phase!\n");
+	facVec = new WorldVector<double>();
+	facVec->set(1.0);
+
+	auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+PhaseInverse_ZOT::PhaseInverse_ZOT(DOFVectorBase<double>* phaseDV_, double fac_, WorldVector<double> *facVec_, int component_) : ZeroOrderTerm(6),
+	phaseDV(phaseDV_), fac(fac_), component(component_), facVec(facVec_)
+{	
+	TEST_EXIT(phaseDV_)("No vector Phase!\n");
+	
+	auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void PhaseInverse_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void PhaseInverse_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void PhaseInverse_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{ 
+	double factor = fac * (*facVec)[component];
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += f(iq) * factor;
+};
+void PhaseInverse_ZOT::eval(int nPoints,
+				const mtl::dense_vector<double>& uhAtQP,
+				const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+				const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+				mtl::dense_vector<double>& result,
+				double opFactor) 
+{
+	double factor = opFactor * fac * (*facVec)[component];
+	for (int iq = 0; iq < nPoints; iq++)
+		result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double PhaseInverse_ZOT::f(const int iq) const
+{
+	return std::max(0.0, std::min( 1.0, (1.0-phase[iq]) ) );
+};
+
+/* ----------------------------------------------------------- */
+
+Pow3_ZOT::Pow3_ZOT(DOFVectorBase<double> *rhoDV_, double fac_) :
+	ZeroOrderTerm(3), rhoDV(rhoDV_), fac(fac_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void Pow3_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void Pow3_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void Pow3_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += f(iq) * fac;
+};
+void Pow3_ZOT::eval(int nPoints,
+	const mtl::dense_vector<double>& uhAtQP,
+	const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+	const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+	mtl::dense_vector<double>& result,
+	double opFactor)
+{
+	double factor = opFactor * fac;
+	for (int iq = 0; iq < nPoints; iq++)
+		result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double Pow3_ZOT::f(const int iq) const
+{
+	return rho[iq]*sqr(rho[iq]);
+};
+
+/* ----------------------------------------------------------- */
+
+Pow3Phase_ZOT::Pow3Phase_ZOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double> *rhoDV_, double fac_) :
+	Phase_ZOT(phaseDV, fac_), rhoDV(rhoDV_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void Pow3Phase_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	Phase_ZOT::initElement(elInfo,subAssembler,quad);
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void Pow3Phase_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	Phase_ZOT::initElement(largeElInfo,smallElInfo,subAssembler,quad);
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+double Pow3Phase_ZOT::f(const int iq) const
+{
+	return rho[iq]*sqr(rho[iq]);
+};
+
+/* ----------------------------------------------------------- */
+
+Pow2_ZOT::Pow2_ZOT(DOFVectorBase<double> *rhoDV_, double fac_) :
+	ZeroOrderTerm(2), rhoDV(rhoDV_), fac(fac_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void Pow2_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void Pow2_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void Pow2_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += f(iq) * fac;
+};
+void Pow2_ZOT::eval(int nPoints,
+	const mtl::dense_vector<double>& uhAtQP,
+	const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+	const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+	mtl::dense_vector<double>& result,
+	double opFactor)
+{
+	double factor = opFactor * fac;
+	for (int iq = 0; iq < nPoints; iq++)
+		result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double Pow2_ZOT::f(const int iq) const
+{
+	return sqr(rho[iq]);
+};
+
+/* ----------------------------------------------------------- */
+
+Pow2Phase_ZOT::Pow2Phase_ZOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double> *rhoDV_, double fac_) :
+	Phase_ZOT(phaseDV, fac_), rhoDV(rhoDV_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void Pow2Phase_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	Phase_ZOT::initElement(elInfo,subAssembler,quad);
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void Pow2Phase_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	Phase_ZOT::initElement(largeElInfo,smallElInfo,subAssembler,quad);
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+double Pow2Phase_ZOT::f(const int iq) const
+{
+	return sqr(rho[iq]);
+};
+/* ----------------------------------------------------------- 
+   1/(rho+0.9)
+*/
+
+ConstrainedFrac_ZOT::ConstrainedFrac_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double fac_) :
+	Phase_ZOT(phaseDV_,fac_), rhoDV(rhoDV_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void ConstrainedFrac_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	Phase_ZOT::initElement(elInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void ConstrainedFrac_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	Phase_ZOT::initElement(largeElInfo, smallElInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+double ConstrainedFrac_ZOT::f(const int iq) const
+{
+	return 1.0/std::max(1.e-6, rho[iq]+0.9);
+};
+
+/* ----------------------------------------------------------- 
+   -1/(rho+0.9)^2
+*/
+
+ConstrainedFracSqr_ZOT::ConstrainedFracSqr_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double factor_) :
+	Phase_ZOT(phaseDV_,factor_), rhoDV(rhoDV_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void ConstrainedFracSqr_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	Phase_ZOT::initElement(elInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void ConstrainedFracSqr_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	Phase_ZOT::initElement(largeElInfo, smallElInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+double ConstrainedFracSqr_ZOT::f(const int iq) const
+{
+	return -1.0/std::max(1.e-6, sqr(rho[iq]+0.9));
+};
+
+
+ConstrainedPowImpl_ZOT::ConstrainedPowImpl_ZOT(DOFVectorBase<double> *rhoDV_, double p_, double rhoMin_, double fac_) :
+    ZeroOrderTerm(2), rhoDV(rhoDV_), p(p_), rhoMin(rhoMin_), fac(fac_)
+{
+    TEST_EXIT(rhoDV_)("No vector rho!\n");
+    auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void ConstrainedPowImpl_ZOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) 
+{
+    getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void ConstrainedPowImpl_ZOT::initElement(const ElInfo* largeElInfo,
+            const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad)
+{
+    getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void ConstrainedPowImpl_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+    for (int iq = 0; iq < nPoints; iq++)
+        C[iq] += f(iq)*fac;
+};
+void ConstrainedPowImpl_ZOT::eval(int nPoints,
+    const mtl::dense_vector<double>& uhAtQP,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor)
+{
+    double factor = opFactor*fac;
+    for (int iq = 0; iq < nPoints; iq++)
+        result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double ConstrainedPowImpl_ZOT::f(const int iq) const
+{
+    return 2.0*p*Helpers::toInt(0.0<=rhoMin-rho[iq]);
+};
+
+
+ConstrainedPowExpl_ZOT::ConstrainedPowExpl_ZOT(DOFVectorBase<double> *rhoDV_, double p_, double rhoMin_, double fac_) :
+    ZeroOrderTerm(2), rhoDV(rhoDV_), p(p_), rhoMin(rhoMin_), fac(fac_)
+{
+    TEST_EXIT(rhoDV_)("No vector rho!\n");
+    auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void ConstrainedPowExpl_ZOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) 
+{
+    getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void ConstrainedPowExpl_ZOT::initElement(const ElInfo* largeElInfo,
+            const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad)
+{
+    getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void ConstrainedPowExpl_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+    for (int iq = 0; iq < nPoints; iq++)
+        C[iq] += f(iq)*fac;
+};
+void ConstrainedPowExpl_ZOT::eval(int nPoints,
+    const mtl::dense_vector<double>& uhAtQP,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor)
+{
+    double factor = opFactor*fac;
+    for (int iq = 0; iq < nPoints; iq++)
+        result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double ConstrainedPowExpl_ZOT::f(const int iq) const
+{
+    return -2.0*p*std::max(0.0, rhoMin-rho[iq]);
+};
+
+ConstrainedPow_ZOT::ConstrainedPow_ZOT(DOFVectorBase<double> *rhoDV_, double p_, double rhoMin_, double fac_) :
+    ZeroOrderTerm(2), rhoDV(rhoDV_), p(p_), rhoMin(rhoMin_), fac(fac_)
+{
+    TEST_EXIT(rhoDV_)("No vector rho!\n");
+    auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void ConstrainedPow_ZOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) 
+{
+    getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void ConstrainedPow_ZOT::initElement(const ElInfo* largeElInfo,
+            const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad)
+{
+    getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void ConstrainedPow_ZOT::getC(const ElInfo *elInfo, int nPoints, ElementVector &C)
+{ 
+    for (int iq = 0; iq < nPoints; iq++)
+        C[iq] += f(iq)*fac;
+};
+void ConstrainedPow_ZOT::eval(int nPoints,
+    const mtl::dense_vector<double>& uhAtQP,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor)
+{
+    double factor = opFactor*fac;
+    for (int iq = 0; iq < nPoints; iq++)
+        result[iq] += factor * f(iq) * uhAtQP[iq];
+};
+double ConstrainedPow_ZOT::f(const int iq) const
+{
+    return -2.0*p*std::max(0.0, rhoMin-rho[iq]);
+};
+
+/* -----------------------------------------------------------
+   phi*rho
+   --------- */
+
+FactorPhase_ZOT::FactorPhase_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double fac_) :
+	Phase_ZOT(phaseDV_,fac_), rhoDV(rhoDV_)
+{
+	TEST_EXIT(rhoDV_)("No vector rho!\n");
+	auxFeSpaces.insert(rhoDV_->getFeSpace());
+};
+
+void FactorPhase_ZOT::initElement(const ElInfo* elInfo, 
+			SubAssembler* subAssembler,
+			Quadrature *quad) 
+{
+	Phase_ZOT::initElement(elInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void FactorPhase_ZOT::initElement(const ElInfo* largeElInfo,
+			const ElInfo* smallElInfo,
+			SubAssembler* subAssembler,
+			Quadrature *quad)
+{
+	Phase_ZOT::initElement(largeElInfo, smallElInfo, subAssembler,quad);
+	getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+double FactorPhase_ZOT::f(const int iq) const
+{
+	return rho[iq];
+};
+
+/* ----------------------------------------------------------- */
+
+WorldVecAndVecFct_FOT::WorldVecAndVecFct_FOT(WorldVector<DOFVectorBase<double>*> vecs_, DOFVectorBase<double> *phaseDV_, double fac_)
+	: FirstOrderTerm(2), phaseDV(phaseDV_), fac(fac_)
+{
+	numVecs=vecs_.size();
+	TEST_EXIT(numVecs==2 || numVecs==3)("Only Dim=2 or Dim=3 possible\n");
+	
+	TEST_EXIT(phaseDV_)("phaseDV is NULL!\n");
+	for (int i = 0; i < numVecs; i++) {
+		TEST_EXIT(vecs_[i])("One vector is NULL!\n");
+	
+		auxFeSpaces.insert(vecs_[i]->getFeSpace());
+	}
+	
+	vec0DV=vecs_[0];
+	vec1DV=vecs_[1];
+	if(numVecs>=3) vec2DV=vecs_[2];
+};
+void WorldVecAndVecFct_FOT::initElement(const ElInfo* elInfo, 
+					SubAssembler* subAssembler,
+					Quadrature *quad) 
+{
+	getVectorAtQPs(vec0DV, elInfo, subAssembler, quad, vec0);
+	getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+	if(numVecs>=3) getVectorAtQPs(vec2DV, elInfo, subAssembler, quad, vec2);
+	getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void WorldVecAndVecFct_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad) 
+{
+	getVectorAtQPs(vec0DV, smallElInfo, largeElInfo, subAssembler, quad, vec0);
+	getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+	if(numVecs>=3) getVectorAtQPs(vec2DV, smallElInfo, largeElInfo, subAssembler, quad, vec2);
+	getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void WorldVecAndVecFct_FOT::getLb(const ElInfo *elInfo, 
+			vector<mtl::dense_vector<double> >& result) const
+{
+	const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+	
+	for (int iq = 0; iq < nPoints; iq++) {		
+		WorldVector<double> vec;
+		vec[0]=vec0[iq];
+		vec[1]=vec1[iq];
+		if(numVecs>=3) vec[2]=vec2[iq];
+		lb(Lambda, vec, result[iq], phase[iq]*fac);
+	}
+};
+void WorldVecAndVecFct_FOT::eval(int nPoints,
+			const mtl::dense_vector<double>& uhAtQP,
+			const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			mtl::dense_vector<double>& result,
+			double opFactor)
+{	
+	double factor = fac * opFactor;
+	for (int iq = 0; iq < nPoints; iq++) {
+		double resultQP = 0.0;
+				
+		resultQP += grdUhAtQP[iq][0] * vec0[iq];
+		resultQP += grdUhAtQP[iq][1] * vec1[iq];
+		if(numVecs>=3) resultQP += grdUhAtQP[iq][2] * vec2[iq];
+		
+		result[iq] += phase[iq] * factor * resultQP;
+	}
+};
+
+/* ----------------------------------------------------------- */
+
+WorldVec_FOT::WorldVec_FOT(WorldVector<DOFVector<double>*> vecs_, double fac_)
+	: FirstOrderTerm(2), fac(fac_)
+{
+	numVecs=vecs_.size();
+	TEST_EXIT(numVecs==2 || numVecs==3)("Only Dim=2 or Dim=3 possible\n");
+	
+	for (int i = 0; i < numVecs; i++) {
+		TEST_EXIT(vecs_[i])("One vector is NULL!\n");	
+		auxFeSpaces.insert(vecs_[i]->getFeSpace());
+	}
+	
+	vec0DV=vecs_[0];
+	vec1DV=vecs_[1];
+	if(numVecs>=3) vec2DV=vecs_[2];
+};
+void WorldVec_FOT::initElement(const ElInfo* elInfo, 
+					SubAssembler* subAssembler,
+					Quadrature *quad) 
+{
+	getVectorAtQPs(vec0DV, elInfo, subAssembler, quad, vec0);
+	getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+	if(numVecs>=3) getVectorAtQPs(vec2DV, elInfo, subAssembler, quad, vec2);
+};
+void WorldVec_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad) 
+{
+	getVectorAtQPs(vec0DV, smallElInfo, largeElInfo, subAssembler, quad, vec0);
+	getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+	if(numVecs>=3) getVectorAtQPs(vec2DV, smallElInfo, largeElInfo, subAssembler, quad, vec2);
+};
+void WorldVec_FOT::getLb(const ElInfo *elInfo, 
+			vector<mtl::dense_vector<double> >& result) const
+{
+	const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+	
+	for (int iq = 0; iq < nPoints; iq++) {
+		WorldVector<double> vec;
+		vec[0]=vec0[iq];
+		vec[1]=vec1[iq];
+		if(numVecs>=3) vec[2]=vec2[iq];
+		lb(Lambda, vec, result[iq], fac);
+	}
+};
+void WorldVec_FOT::eval(int nPoints,
+			const mtl::dense_vector<double>& uhAtQP,
+			const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			mtl::dense_vector<double>& result,
+			double opFactor)
+{	
+	double factor = fac * opFactor;
+	for (int iq = 0; iq < nPoints; iq++) {
+		double resultQP = 0.0;
+				
+		resultQP += grdUhAtQP[iq][0] * vec0[iq];
+		resultQP += grdUhAtQP[iq][1] * vec1[iq];
+		if(numVecs>=3) resultQP += grdUhAtQP[iq][2] * vec2[iq];
+		
+		result[iq] += factor * resultQP;
+	}
+};
+
+/* ----------------------------------------------------------- */
+
+WorldVector_FOT::WorldVector_FOT(DOFVector<WorldVector<double> >* dv, double fac_)
+: FirstOrderTerm(1),
+  vec(dv),
+  fac(fac_)
+{
+  TEST_EXIT(dv)("No vector!\n");
+
+  auxFeSpaces.insert(dv->getFeSpace());
+}
+
+
+void WorldVector_FOT::initElement(const ElInfo* elInfo,
+				  SubAssembler* subAssembler,
+				  Quadrature *quad)
+{
+  getVectorAtQPs(vec, elInfo, subAssembler, quad, vecAtQPs);
+}
+
+
+void WorldVector_FOT::initElement(const ElInfo* largeElInfo,
+				  const ElInfo* smallElInfo,
+				  SubAssembler* subAssembler,
+				  Quadrature *quad)
+{
+  getVectorAtQPs(vec, smallElInfo, largeElInfo, subAssembler, quad, vecAtQPs);
+}
+
+
+void WorldVector_FOT::getLb(const ElInfo *elInfo,
+			    vector<mtl::dense_vector<double> >& Lb) const
+{
+  const DimVec<WorldVector<double> > &grdLambda = elInfo->getGrdLambda();
+  const int nPoints = static_cast<int>(Lb.size());
+
+  for (int iq = 0; iq < nPoints; iq++)
+    lb(grdLambda, vecAtQPs[iq], Lb[iq], fac);
+}
+
+
+void WorldVector_FOT::eval(int nPoints,
+			   const mtl::dense_vector<double>&,
+			   const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			   const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			   mtl::dense_vector<double>& result,
+		 	   double opFactor)
+{
+  if (num_rows(grdUhAtQP) > 0) {
+    double fac_ = fac * opFactor;
+    for (int iq = 0; iq < nPoints; iq++)
+      result[iq] += (vecAtQPs[iq] * grdUhAtQP[iq]) * fac_;
+  }
+}
+
+/* ----------------------------------------------------------- */
+
+WorldVecPhase_FOT::WorldVecPhase_FOT(DOFVectorBase<double> *phaseDV_, WorldVector<DOFVector<double>*> vecs_,double fac_)
+    : FirstOrderTerm(2), phaseDV(phaseDV_), fac(fac_)
+{
+    numVecs=vecs_.size();
+    TEST_EXIT(numVecs==2 || numVecs==3)("Only Dim=2 or Dim=3 possible\n");
+    
+    TEST_EXIT(phaseDV_)("phaseDV is NULL!\n");
+    for (int i = 0; i < numVecs; i++) {
+        TEST_EXIT(vecs_[i])("One vector is NULL!\n");
+    
+        auxFeSpaces.insert(vecs_[i]->getFeSpace());
+    }
+    auxFeSpaces.insert(phaseDV_->getFeSpace());
+    
+    vec0DV=vecs_[0];
+    vec1DV=vecs_[1];
+    if(numVecs>=3) vec2DV=vecs_[2];
+};
+void WorldVecPhase_FOT::initElement(const ElInfo* elInfo, 
+                    SubAssembler* subAssembler,
+                    Quadrature *quad) 
+{
+    getVectorAtQPs(vec0DV, elInfo, subAssembler, quad, vec0);
+    getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+    if(numVecs>=3) getVectorAtQPs(vec2DV, elInfo, subAssembler, quad, vec2);
+    getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void WorldVecPhase_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+                    SubAssembler* subAssembler,
+                    Quadrature *quad) 
+{
+    getVectorAtQPs(vec0DV, smallElInfo, largeElInfo, subAssembler, quad, vec0);
+    getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+    if(numVecs>=3) getVectorAtQPs(vec2DV, smallElInfo, largeElInfo, subAssembler, quad, vec2);
+    getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void WorldVecPhase_FOT::getLb(const ElInfo *elInfo, 
+            vector<mtl::dense_vector<double> >& result) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+    
+    for (int iq = 0; iq < nPoints; iq++) {      
+        WorldVector<double> vec;
+        vec[0]=vec0[iq];
+        vec[1]=vec1[iq];
+        if(numVecs>=3) vec[2]=vec2[iq];
+        lb(Lambda, vec, result[iq], phase[iq]*fac);
+    }
+};
+void WorldVecPhase_FOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    double factor = fac * opFactor;
+    for (int iq = 0; iq < nPoints; iq++) {
+        double resultQP = 0.0;
+                
+        resultQP += grdUhAtQP[iq][0] * vec0[iq];
+        resultQP += grdUhAtQP[iq][1] * vec1[iq];
+        if(numVecs>=3) resultQP += grdUhAtQP[iq][2] * vec2[iq];
+        
+        result[iq] += phase[iq] * factor * resultQP;
+    }
+};
+
+/* ----------------------------------------------------------- */
+
+// vec1*vec2*d/dxi(...)
+VecAndPartialDerivative_FOT::VecAndPartialDerivative_FOT(DOFVectorBase<double> *dv1,
+      int component_, double fac_)
+: FirstOrderTerm(3), vec1DV(dv1), fac(fac_), component(component_)
+{
+  auxFeSpaces.insert(vec1DV->getFeSpace());
+
+  setB(component);
+}
+
+void VecAndPartialDerivative_FOT::initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad) 
+{ 
+  getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+};
+void VecAndPartialDerivative_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+  SubAssembler* subAssembler,
+  Quadrature *quad)
+{ 
+  getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+};
+void VecAndPartialDerivative_FOT::getLb(const ElInfo *elInfo,
+      vector<mtl::dense_vector<double> >& result) const
+{
+  const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+    
+  for(int iq = 0; iq < nPoints; iq++) {
+    lb_one(Lambda, result[iq], vec1[iq] * fac);
+  }
+};
+void VecAndPartialDerivative_FOT::eval(int nPoints,
+      const mtl::dense_vector<double>& uhAtQP,
+      const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+      const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+      mtl::dense_vector<double>& result,
+      double opFactor)
+{
+  for(int iq = 0; iq < nPoints; iq++) 
+    result[iq] += opFactor * vec1[iq] * grdUhAtQP[iq][component] * fac;
+};
+
+/* ----------------------------------------------------------- */
+
+// vec1*vec2*d/dxi(...)
+PhaseAndViscosityPartialDerivativeBoundary_FOT::PhaseAndViscosityPartialDerivativeBoundary_FOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *chDV_,
+      int component_, int normalComponent_, double viscosity1_, double viscosity2_)
+: FirstOrderTerm(3), phaseDV(phaseDV_), chDV(chDV_), component(component_), normalComponent(normalComponent_), v1(viscosity1_), v2(viscosity2_)
+{
+  auxFeSpaces.insert(phaseDV->getFeSpace());
+  auxFeSpaces.insert(chDV->getFeSpace());
+
+  setB(component);
+}
+
+void PhaseAndViscosityPartialDerivativeBoundary_FOT::initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad) 
+{ 
+  getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+  getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+
+  WorldVector<double> normal;
+  int side= -1;
+  for (int i= 0; i < elInfo->getMesh()->getDim()+1; ++i) {
+    if(elInfo->getBoundary(i) > 2) {
+      side= i;
+      break;
+    }
+  }
+//   elInfo->getNormal(side, normal);
+  normalJ = 1.0; //normal[normalComponent];
+};
+void PhaseAndViscosityPartialDerivativeBoundary_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+  SubAssembler* subAssembler,
+  Quadrature *quad)
+{ 
+  getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+  getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+
+  WorldVector<double> normal;
+  int side= -1;
+  for (int i= 0; i < largeElInfo->getMesh()->getDim()+1; ++i) {
+    if(largeElInfo->getBoundary(i) > 2) {
+      side= i;
+      break;
+    }
+  }
+//   largeElInfo->getNormal(side, normal);
+  normalJ = 1.0; //normal[normalComponent];
+};
+void PhaseAndViscosityPartialDerivativeBoundary_FOT::getLb(const ElInfo *elInfo,
+      vector<mtl::dense_vector<double> >& result) const
+{
+  const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+  const int nPoints = static_cast<int>(result.size());
+    
+  for(int iq = 0; iq < nPoints; iq++) {
+    lb_one(Lambda, result[iq], phase[iq] * normalJ * f(iq));
+  }
+};
+void PhaseAndViscosityPartialDerivativeBoundary_FOT::eval(int nPoints,
+      const mtl::dense_vector<double>& uhAtQP,
+      const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+      const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+      mtl::dense_vector<double>& result,
+      double opFactor)
+{
+  for(int iq = 0; iq < nPoints; iq++) 
+    result[iq] += opFactor * phase[iq] * grdUhAtQP[iq][component] * normalJ * f(iq);
+};
+
+double PhaseAndViscosityPartialDerivativeBoundary_FOT::f(const int iq) const
+{
+    double ph= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(ph+1.0)-v2*0.5*(ph-1.0);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+// vec1*vec2*d/dxi(...)
+ViscosityPartialDerivativeBoundary_FOT::ViscosityPartialDerivativeBoundary_FOT(DOFVectorBase<double> *chDV_,
+      int component_, int normalComponent_, double viscosity1_, double viscosity2_)
+: FirstOrderTerm(3), chDV(chDV_), component(component_), normalComponent(normalComponent_), v1(viscosity1_), v2(viscosity2_)
+{
+  auxFeSpaces.insert(chDV->getFeSpace());
+
+  setB(component);
+}
+
+void ViscosityPartialDerivativeBoundary_FOT::initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad) 
+{ 
+  getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+
+  WorldVector<double> normal;
+  int side= -1;
+  for (int i= 0; i < elInfo->getMesh()->getDim()+1; ++i) {
+    if(elInfo->getBoundary(i) > 2) {
+      side= i;
+      break;
+    }
+  }
+//   elInfo->getNormal(side, normal);
+  normalJ = 1.0; //normal[normalComponent];
+};
+void ViscosityPartialDerivativeBoundary_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+  SubAssembler* subAssembler,
+  Quadrature *quad)
+{ 
+  getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+
+  WorldVector<double> normal;
+  int side= -1;
+  for (int i= 0; i < largeElInfo->getMesh()->getDim()+1; ++i) {
+    if(largeElInfo->getBoundary(i) > 2) {
+      side= i;
+      break;
+    }
+  }
+//   largeElInfo->getNormal(side, normal);
+  normalJ = 1.0; //normal[normalComponent];
+};
+void ViscosityPartialDerivativeBoundary_FOT::getLb(const ElInfo *elInfo,
+      vector<mtl::dense_vector<double> >& result) const
+{
+  const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+  const int nPoints = static_cast<int>(result.size());
+    
+  for(int iq = 0; iq < nPoints; iq++) {
+    lb_one(Lambda, result[iq], normalJ * f(iq));
+  }
+};
+void ViscosityPartialDerivativeBoundary_FOT::eval(int nPoints,
+      const mtl::dense_vector<double>& uhAtQP,
+      const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+      const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+      mtl::dense_vector<double>& result,
+      double opFactor)
+{
+  for(int iq = 0; iq < nPoints; iq++) 
+    result[iq] += opFactor * grdUhAtQP[iq][component] * normalJ * f(iq);
+};
+
+double ViscosityPartialDerivativeBoundary_FOT::f(const int iq) const
+{
+    double ph= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(ph+1.0)-v2*0.5*(ph-1.0);
+    return viscosity;
+};
+/* ----------------------------------------------------------- */
+
+// vec1*vec2*d/dxi(...)
+Vec2ProductPartial_FOT::Vec2ProductPartial_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2,
+			int component_, double fac_)
+: FirstOrderTerm(3), vec1DV(dv1), vec2DV(dv2), fac(fac_), component(component_)
+{
+	auxFeSpaces.insert(vec1DV->getFeSpace());
+	auxFeSpaces.insert(vec2DV->getFeSpace());
+
+	setB(component);
+}
+
+void Vec2ProductPartial_FOT::initElement(const ElInfo* elInfo, 
+				SubAssembler* subAssembler,
+				Quadrature *quad) 
+{ 
+	getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+	getVectorAtQPs(vec2DV, elInfo, subAssembler, quad, vec2);
+};
+void Vec2ProductPartial_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler* subAssembler,
+	Quadrature *quad)
+{ 
+	getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+	getVectorAtQPs(vec2DV, smallElInfo, largeElInfo, subAssembler, quad, vec2);
+};
+void Vec2ProductPartial_FOT::getLb(const ElInfo *elInfo,
+			vector<mtl::dense_vector<double> >& result) const
+{
+	const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+    
+	for(int iq = 0; iq < nPoints; iq++) {
+		lb_one(Lambda, result[iq], vec1[iq] * vec2[iq] * fac);
+	}
+};
+void Vec2ProductPartial_FOT::eval(int nPoints,
+			const mtl::dense_vector<double>& uhAtQP,
+			const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			mtl::dense_vector<double>& result,
+			double opFactor)
+{
+	for(int iq = 0; iq < nPoints; iq++) 
+		result[iq] += opFactor * vec1[iq] * vec2[iq] * grdUhAtQP[iq][component] * fac;
+};
+
+/* ----------------------------------------------------------- */
+
+PartialDerivative_FOT::PartialDerivative_FOT(int component_, double fac_)
+	: FirstOrderTerm(1), component(component_), fac(fac_)
+{
+	setB(component);
+};
+void PartialDerivative_FOT::initElement(const ElInfo* elInfo, 
+					SubAssembler* subAssembler,
+					Quadrature *quad) {};
+void PartialDerivative_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad) {};
+void PartialDerivative_FOT::getLb(const ElInfo *elInfo, 
+			vector<mtl::dense_vector<double> >& result) const
+{
+	const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+	
+	for (int iq = 0; iq < nPoints; iq++) {	
+		lb_one(Lambda, result[iq], fac);
+	}
+};
+void PartialDerivative_FOT::eval(int nPoints,
+			const mtl::dense_vector<double>& uhAtQP,
+			const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+			const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+			mtl::dense_vector<double>& result,
+			double opFactor)
+{	
+	for (int iq = 0; iq < nPoints; iq++) {		
+		result[iq] += opFactor * grdUhAtQP[iq][component] * fac;
+	}
+};
+
+/* ----------------------------------------------------------- */
+
+PartialDerivative_ZOT::PartialDerivative_ZOT(DOFVectorBase<double> *vecDV_, int component_, double fac_)
+	: ZeroOrderTerm(1), vecDV(vecDV_), fac(fac_), component(component_)
+{
+	TEST_EXIT(vecDV_)("No first vector!\n");
+	auxFeSpaces.insert(vecDV_->getFeSpace());
+
+	facVec = new WorldVector<double>(); facVec->set(1.0);
+	component2 = 0;
+};
+PartialDerivative_ZOT::PartialDerivative_ZOT(DOFVectorBase<double> *vecDV_, int component_, double fac_, WorldVector<double> *facVec_, int component2_)
+	: ZeroOrderTerm(1), vecDV(vecDV_), fac(fac_), facVec(facVec_), component(component_), component2(component2_)
+{
+	TEST_EXIT(vecDV_)("No first vector!\n");
+	auxFeSpaces.insert(vecDV_->getFeSpace());
+};
+void PartialDerivative_ZOT::initElement(const ElInfo* elInfo, 
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+  getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, grad);
+};
+void PartialDerivative_ZOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+  getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, grad);
+};
+void PartialDerivative_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{ 	
+	double factor = fac * (*facVec)[component2];
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += grad[iq][component]*factor;
+};
+void PartialDerivative_ZOT::eval(int nPoints,
+				const mtl::dense_vector<double>& uhAtQP,
+				const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+				const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+				mtl::dense_vector<double>& result,
+				double opFactor)
+{	
+	double factor = opFactor * fac * (*facVec)[component2];
+	for (int iq = 0; iq < nPoints; iq++) {		
+		result[iq] += grad[iq][component] * uhAtQP[iq] * factor;
+	}
+};
+
+
+/* ----------------------------------------------------------- */
+
+VecAndPartialDerivative_ZOT::VecAndPartialDerivative_ZOT(DOFVectorBase<double> *vecDV_, DOFVectorBase<double> *gradDV_, int component_,  double fac_)
+: ZeroOrderTerm(2),
+  vecDV(vecDV_),
+  gradDV(gradDV_),
+  component(component_),
+  fac(fac_)
+{
+  TEST_EXIT(vecDV_)("No value vector!\n");
+  TEST_EXIT(gradDV_)("No gradient vector!\n");
+
+  auxFeSpaces.insert(vecDV_->getFeSpace());
+  auxFeSpaces.insert(gradDV_->getFeSpace());
+}
+
+
+void VecAndPartialDerivative_ZOT::initElement(const ElInfo* elInfo,
+					      SubAssembler* subAssembler,
+					      Quadrature *quad)
+{
+  getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec);
+  getGradientsAtQPs(gradDV, elInfo, subAssembler, quad, grad);
+}
+
+
+void VecAndPartialDerivative_ZOT::initElement(const ElInfo* largeElInfo,
+					      const ElInfo* smallElInfo,
+					      SubAssembler* subAssembler,
+					      Quadrature *quad)
+{
+  getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec);
+  getGradientsAtQPs(gradDV, smallElInfo, largeElInfo, subAssembler, quad, grad);
+}
+
+
+void VecAndPartialDerivative_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{
+  for (int iq = 0; iq < nPoints; iq++)
+    C[iq] += vec[iq] * grad[iq][component] * fac;
+}
+
+
+void VecAndPartialDerivative_ZOT::eval(int nPoints,
+				       const mtl::dense_vector<double>& uhAtQP,
+				       const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+				       const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+				       mtl::dense_vector<double>& result,
+				       double opFactor)
+{
+  double fac_ = fac * opFactor;
+  for (int iq = 0; iq < nPoints; iq++)
+    result[iq] += vec[iq] * grad[iq][component] * uhAtQP[iq] * fac_;
+}
+
+/* ----------------------------------------------------------- */
+
+Vec2AndPartialDerivative_ZOT::Vec2AndPartialDerivative_ZOT(DOFVectorBase<double> *vec1DV_, DOFVectorBase<double> *vec2DV_, DOFVectorBase<double> *gradDV_,int component_,  double fac_)
+	: ZeroOrderTerm(3), vec1DV(vec1DV_), vec2DV(vec2DV_), gradDV(gradDV_), fac(fac_), component(component_)
+{
+	TEST_EXIT(vec1DV_)("No first vector!\n");
+	TEST_EXIT(vec2DV_)("No second vector!\n");
+	TEST_EXIT(gradDV_)("No gradient vector!\n");
+	auxFeSpaces.insert(vec1DV_->getFeSpace());
+	auxFeSpaces.insert(vec2DV_->getFeSpace());
+	auxFeSpaces.insert(gradDV_->getFeSpace());
+};
+void Vec2AndPartialDerivative_ZOT::initElement(const ElInfo* elInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+	getVectorAtQPs(vec1DV, elInfo, subAssembler, quad, vec1);
+	getVectorAtQPs(vec2DV, elInfo, subAssembler, quad, vec2);
+	getGradientsAtQPs(gradDV, elInfo, subAssembler, quad, grad);
+};
+void Vec2AndPartialDerivative_ZOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+	getVectorAtQPs(vec1DV, smallElInfo, largeElInfo, subAssembler, quad, vec1);
+	getVectorAtQPs(vec2DV, smallElInfo, largeElInfo, subAssembler, quad, vec2);
+	getGradientsAtQPs(gradDV, smallElInfo, largeElInfo, subAssembler, quad, grad);
+};
+void Vec2AndPartialDerivative_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += vec1[iq]*vec2[iq]*grad[iq][component]*fac;
+};
+void Vec2AndPartialDerivative_ZOT::eval(int nPoints,
+				const mtl::dense_vector<double>& uhAtQP,
+				const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+				const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+				mtl::dense_vector<double>& result,
+				double opFactor)
+{
+	for (int iq = 0; iq < nPoints; iq++) {
+		result[iq] += (vec1[iq] * vec2[iq]) * grad[iq][component] * uhAtQP[iq] * opFactor * fac;
+	}
+};
+
+/* ----------------------------------------------------------- */
+
+Mobility_SOT::Mobility_SOT(DOFVectorBase<double> *rhoDV_, double factor_)
+    : SecondOrderTerm(6), rhoDV(rhoDV_), factor(factor_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(rhoDV)("No vector!\n");
+    auxFeSpaces.insert(rhoDV->getFeSpace());
+    eps= 1.e-5;
+    
+    rho0= 1.0;
+    density= -0.3;
+    Parameters::get("pfc->rho0",rho0, 1);
+    Parameters::get("pfc->density",density, 1);
+};
+void Mobility_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(rhoDV, elInfo, subAssembler, quad, rho);
+};
+void Mobility_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(rhoDV, smallElInfo, largeElInfo, subAssembler, quad, rho);
+};
+void Mobility_SOT::getLALt(const ElInfo *elInfo,
+            std::vector<mtl::dense2D<double> > &LALt) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+    for (int iq = 0; iq < nPoints; iq++)
+        l1lt(Lambda, LALt[iq], f(iq) * factor);
+};
+void Mobility_SOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            double feval = f(iq) * opFactor * factor;
+            double resultQP = 0.0;
+            for (int i = 0; i < dimOfWorld; i++)
+                resultQP += D2UhAtQP[iq][i][i]; 
+            result[iq] += feval * resultQP;
+        }
+    }
+};
+void Mobility_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+            std::vector<WorldVector<double> > &result)
+{
+    int nPoints = grdUhAtQP.size();
+    for (int iq = 0; iq < nPoints; iq++) {
+        double fac = f(iq) * factor;
+        axpy(fac, grdUhAtQP[iq], result[iq]);
+    }
+};
+double Mobility_SOT::f(const int iq) const
+{
+    double mobility= 0.5*(3.0-rho[iq]/density)*rho0;
+//     double phase = 0.5*(1.0-tanh(3.0*(eps-mobility)/0.1));
+    return std::max(mobility, eps);
+};
+
+/* ----------------------------------------------------------- */
+
+MobilityCH_SOT::MobilityCH_SOT(DOFVectorBase<double> *chDV_, double factor_)
+    : SecondOrderTerm(4), chDV(chDV_), factor(factor_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+    delta = 1.e-6;
+};
+void MobilityCH_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MobilityCH_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void MobilityCH_SOT::getLALt(const ElInfo *elInfo,
+            std::vector<mtl::dense2D<double> > &LALt) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+    for (int iq = 0; iq < nPoints; iq++)
+        l1lt(Lambda, LALt[iq], f(iq) * factor);
+};
+void MobilityCH_SOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            double feval = f(iq) * opFactor * factor;
+            double resultQP = 0.0;
+            for (int i = 0; i < dimOfWorld; i++)
+                resultQP += D2UhAtQP[iq][i][i]; 
+            result[iq] += feval * resultQP;
+        }
+    }
+};
+void MobilityCH_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+            std::vector<WorldVector<double> > &result)
+{
+    int nPoints = grdUhAtQP.size();
+    for (int iq = 0; iq < nPoints; iq++) {
+        double fac = f(iq) * factor;
+        axpy(fac, grdUhAtQP[iq], result[iq]);
+    }
+};
+double MobilityCH_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double mobility= 0.25*sqr(sqr(phase)-1.0);
+      return std::max(mobility, delta);
+};
+
+
+/* ----------------------------------------------------------- */
+
+MobilityCH2_SOT::MobilityCH2_SOT(DOFVectorBase<double> *chDV_, double factor_)
+    : SecondOrderTerm(4), chDV(chDV_), factor(factor_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+    delta = 1.e-6;
+};
+void MobilityCH2_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MobilityCH2_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void MobilityCH2_SOT::getLALt(const ElInfo *elInfo,
+            std::vector<mtl::dense2D<double> > &LALt) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+    for (int iq = 0; iq < nPoints; iq++)
+        l1lt(Lambda, LALt[iq], f(iq) * factor);
+};
+void MobilityCH2_SOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            double feval = f(iq) * opFactor * factor;
+            double resultQP = 0.0;
+            for (int i = 0; i < dimOfWorld; i++)
+                resultQP += D2UhAtQP[iq][i][i]; 
+            result[iq] += feval * resultQP;
+        }
+    }
+};
+void MobilityCH2_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+            std::vector<WorldVector<double> > &result)
+{
+    int nPoints = grdUhAtQP.size();
+    for (int iq = 0; iq < nPoints; iq++) {
+        double fac = f(iq) * factor;
+        axpy(fac, grdUhAtQP[iq], result[iq]);
+    }
+};
+double MobilityCH2_SOT::f(const int iq) const
+{
+    double phase= std::max(0.0,std::min(1.0,ch[iq]));
+  
+    double mobility= 0.25*sqr(phase)*sqr(phase-1.0);
+    return std::max(mobility, delta);
+};
+
+/* ----------------------------------------------------------- */
+
+MobilityCHPhase_SOT::MobilityCHPhase_SOT(DOFVectorBase<double>* phaseDV_, DOFVectorBase<double> *chDV_, double factor_)
+    : Phase_SOT(phaseDV_, factor_), chDV(chDV_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+    delta = 1.e-6;
+};
+void MobilityCHPhase_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+	Phase_SOT::initElement(elInfo,subAssembler,quad);
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MobilityCHPhase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+	Phase_SOT::initElement(largeElInfo, smallElInfo,subAssembler,quad);
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+double MobilityCHPhase_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double mobility= 0.25*sqr(sqr(phase)-1.0);
+  
+    return std::max(mobility, delta);
+};
+
+
+/* ----------------------------------------------------------- */
+
+Mobility2CHPhase_FOT::Mobility2CHPhase_FOT(
+  DOFVectorBase<double>* phaseDV_, 
+  DOFVectorBase<double> *chDV_, 
+  DOFVectorBase<double> *muDV_, 
+  double factor_)
+    : Phase_FOT(phaseDV_, factor_), chDV(chDV_), muDV(muDV_)
+{  
+  TEST_EXIT(chDV)("No vector!\n");
+  auxFeSpaces.insert(chDV->getFeSpace());
+  auxFeSpaces.insert(muDV->getFeSpace());
+  delta = 1.e-6;
+};
+void Mobility2CHPhase_FOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+  Phase_FOT::initElement(elInfo,subAssembler,quad);
+  getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+  getGradientsAtQPs(muDV, elInfo, subAssembler, quad, grdMu);
+};
+void Mobility2CHPhase_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+  Phase_FOT::initElement(largeElInfo, smallElInfo,subAssembler,quad);
+  getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+  getGradientsAtQPs(muDV, smallElInfo, largeElInfo, subAssembler, quad, grdMu);
+};
+WorldVector<double> Mobility2CHPhase_FOT::f(const int iq) const
+{
+    double mobility= sqr(ch[iq])*ch[iq]-ch[iq];
+    return mobility*grdMu[iq];
+};
+
+/* ----------------------------------------------------------- */
+
+
+MatrixPhase_SOT::MatrixPhase_SOT(DOFVectorBase<double>* phaseDV_, int comp_, double fac_) :
+    SecondOrderTerm(6), phaseDV(phaseDV_), comp(comp_), fac(fac_), symmetric(true)
+{
+    TEST_EXIT(phaseDV_)("no vector phase!\n");
+    auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void MatrixPhase_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void MatrixPhase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+
+/// Evaluation of \f$ \Lambda \cdot A \cdot \Lambda^t\f$ for A equal to the diagonal matrix.
+void MatrixPhase_SOT::lDlt(const DimVec<WorldVector<double> >& Lambda, 
+            const WorldVector<double>& vec,
+            mtl::dense2D<double>& LALt,
+            double factor) const
+{
+    const int dim = num_rows(LALt);
+    
+    for (int i = 0; i < dim; i++) {
+        double val = 0.0;
+        for (int k = 0; k < dimOfWorld; k++)
+            val += vec[k] * Lambda[i][k] * Lambda[i][k];
+        val *= factor;
+        LALt[i][i] += val;
+        for (int j = i + 1; j < dim; j++) {
+            val = 0.0;
+            for (int k = 0; k < dimOfWorld; k++)
+                val += vec[k] * Lambda[i][k] * Lambda[j][k];
+            val *= factor;
+            LALt[i][j] += val;
+            LALt[j][i] += val;
+        }    
+    }      
+};
+void MatrixPhase_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lDlt(Lambda, f(iq), LALt[iq], phase[iq] * fac);
+    }
+};
+void MatrixPhase_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        double factor = opFactor * fac;
+        for (int iq = 0; iq < nPoints; iq++) {
+            WorldVector<double> D = f(iq);
+            double resultQP = 0.0;
+                    
+            for (int i = 0; i < dimOfWorld; i++) {
+                double resultI= 0.0;
+                for (int j = 0; j < dimOfWorld; j++) {
+                    resultI += D2UhAtQP[iq][j][i];
+                }
+                resultQP+= D[i] * resultI;
+            }
+            result[iq] += resultQP * factor * phase[iq];
+        }
+    }
+};
+void MatrixPhase_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) {
+        WorldVector<double> multVec = f(iq);
+        for (int i = 0; i < grdUhAtQP[iq].getSize(); ++i)
+            multVec[i]*= grdUhAtQP[iq][i];
+        result[iq] += multVec * (phase[iq] * fac);
+    }
+};
+WorldVector<double> MatrixPhase_SOT::f(const int iq) const
+{
+    WorldVector<double> result;
+    result[1-comp]=1.0;
+    result[comp]=2.0;
+    return result;
+};
+
+
+/* ----------------------------------------------------------- */
+
+
+MatrixIJ_SOT::MatrixIJ_SOT(int row_, int col_, double fac_) :
+    SecondOrderTerm(1), row(row_), col(col_), fac(fac_), symmetric(true)
+{
+};
+void MatrixIJ_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lalt_kl(Lambda, row, col, LALt[iq], fac);
+    }
+};
+void MatrixIJ_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    double factor = opFactor * fac;
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            result[iq] += D2UhAtQP[iq][row][col] * factor;
+        }
+    }
+};
+void MatrixIJ_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) { 
+        result[iq][row] += grdUhAtQP[iq][col] * fac;      
+    }
+};
+
+/* ----------------------------------------------------------- */
+
+
+MatrixIJPhase_SOT::MatrixIJPhase_SOT(DOFVectorBase<double>* phaseDV_, int row_, int col_, double fac_) :
+    SecondOrderTerm(6), phaseDV(phaseDV_), row(row_), col(col_), fac(fac_), symmetric(true)
+{
+    TEST_EXIT(phaseDV_)("no vector phase!\n");
+    auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void MatrixIJPhase_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+};
+void MatrixIJPhase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+};
+void MatrixIJPhase_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lalt_kl(Lambda, row, col, LALt[iq], phase[iq] * fac);
+    }
+};
+void MatrixIJPhase_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    double factor = opFactor * fac;
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            result[iq] += D2UhAtQP[iq][row][col] * factor;
+        }
+    }
+};
+void MatrixIJPhase_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) { 
+        result[iq][row] += grdUhAtQP[iq][col] * fac;      
+    }
+};
+
+/* ----------------------------------------------------------- */
+
+MatrixIJViscosityPhase_SOT::MatrixIJViscosityPhase_SOT(DOFVectorBase<double>* phaseDV_, DOFVectorBase<double>* chDV_, int row_, int col_, double v1_, double v2_, double fac_) :
+    SecondOrderTerm(6), phaseDV(phaseDV_), chDV(chDV_), row(row_), col(col_), v1(v1_), v2(v2_), fac(fac_), symmetric(true)
+{
+    TEST_EXIT(phaseDV_)("no vector phase!\n");
+    auxFeSpaces.insert(phaseDV_->getFeSpace());
+    auxFeSpaces.insert(chDV_->getFeSpace());
+};
+void MatrixIJViscosityPhase_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosityPhase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosityPhase_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lalt_kl(Lambda, row, col, LALt[iq], phase[iq] * f(iq) * fac);
+    }
+};
+void MatrixIJViscosityPhase_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    double factor = opFactor * fac;
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            result[iq] += D2UhAtQP[iq][row][col] * phase[iq] * f(iq) * factor;
+        }
+    }
+};
+void MatrixIJViscosityPhase_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) { 
+        result[iq][row] += grdUhAtQP[iq][col] * phase[iq] * f(iq) * fac;      
+    }
+};
+double MatrixIJViscosityPhase_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(phase+1.0)-v2*0.5*(phase-1.0);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+MatrixIJViscosity_SOT::MatrixIJViscosity_SOT(DOFVectorBase<double>* chDV_, int row_, int col_, double v1_, double v2_, double fac_) :
+    SecondOrderTerm(6), chDV(chDV_), row(row_), col(col_), v1(v1_), v2(v2_), fac(fac_), symmetric(true)
+{
+    TEST_EXIT(chDV_)("no vector phase!\n");
+    auxFeSpaces.insert(chDV_->getFeSpace());
+};
+void MatrixIJViscosity_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosity_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosity_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lalt_kl(Lambda, row, col, LALt[iq], f(iq) * fac);
+    }
+};
+void MatrixIJViscosity_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    double factor = opFactor * fac;
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            result[iq] += D2UhAtQP[iq][row][col] * f(iq) * factor;
+        }
+    }
+};
+void MatrixIJViscosity_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) { 
+        result[iq][row] += grdUhAtQP[iq][col] * f(iq) * fac;      
+    }
+};
+double MatrixIJViscosity_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(phase+1.0)-v2*0.5*(phase-1.0);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+
+MatrixIJViscosityPhase2_SOT::MatrixIJViscosityPhase2_SOT(DOFVectorBase<double>* phaseDV_, DOFVectorBase<double>* chDV_, int row_, int col_, double v1_, double v2_, double fac_) :
+    SecondOrderTerm(6), phaseDV(phaseDV_), chDV(chDV_), row(row_), col(col_), v1(v1_), v2(v2_), fac(fac_), symmetric(true)
+{
+    TEST_EXIT(phaseDV_)("no vector phase!\n");
+    auxFeSpaces.insert(phaseDV_->getFeSpace());
+    auxFeSpaces.insert(chDV_->getFeSpace());
+};
+void MatrixIJViscosityPhase2_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, elInfo, subAssembler, quad, phase);
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosityPhase2_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature *quad) {
+    getVectorAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, phase);
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void MatrixIJViscosityPhase2_SOT::getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const  
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+
+    for (int iq = 0; iq < nPoints; iq++) {
+        lalt_kl(Lambda, row, col, LALt[iq], phase[iq] * f(iq) * fac);
+    }
+};
+void MatrixIJViscosityPhase2_SOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{   
+    double factor = opFactor * fac;
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            result[iq] += D2UhAtQP[iq][row][col] * phase[iq] * f(iq) * factor;
+        }
+    }
+};
+void MatrixIJViscosityPhase2_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result)
+{
+    const int nPoints = static_cast<int>(grdUhAtQP.size());
+    for (int iq = 0; iq < nPoints; iq++) { 
+        result[iq][row] += grdUhAtQP[iq][col] * phase[iq] * f(iq) * fac;      
+    }
+};
+double MatrixIJViscosityPhase2_SOT::f(const int iq) const
+{
+    double phase= std::max(0.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*phase+v2*(1.0-phase);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+WettingAngle_ZOT::WettingAngle_ZOT(DOFVectorBase<double> *vecDV_, DOFVectorBase<double> *gradDV_, double fac_)
+	: ZeroOrderTerm(1), vecDV(vecDV_), gradDV(gradDV_), fac(fac_)
+{
+	TEST_EXIT(vecDV_)("No first vector!\n");
+	auxFeSpaces.insert(vecDV_->getFeSpace());
+	auxFeSpaces.insert(gradDV_->getFeSpace());
+};
+void WettingAngle_ZOT::initElement(const ElInfo* elInfo, 
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+// 	getVectorAtQPs(vecDV, elInfo, subAssembler, quad, vec);
+        getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, gradC);
+	getGradientsAtQPs(gradDV, elInfo, subAssembler, quad, grad);
+};
+void WettingAngle_ZOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+					SubAssembler* subAssembler,
+					Quadrature *quad)
+{
+// 	getVectorAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, vec);
+        getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, gradC);
+	getGradientsAtQPs(gradDV, smallElInfo, largeElInfo, subAssembler, quad, grad);
+};
+void WettingAngle_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{ 	
+	for (int iq = 0; iq < nPoints; iq++)
+		C[iq] += f(iq)*fac;
+};
+void WettingAngle_ZOT::eval(int nPoints,
+				const mtl::dense_vector<double>& uhAtQP,
+				const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+				const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+				mtl::dense_vector<double>& result,
+				double opFactor)
+{	
+	for (int iq = 0; iq < nPoints; iq++) {		
+		result[iq] += f(iq) * uhAtQP[iq] * opFactor * fac;
+	}
+};
+double WettingAngle_ZOT::f(const int iq) const
+{
+//     double c= std::max(-1.0, std::min(1.0, vec[iq]) );
+    return norm(gradC[iq])*norm(grad[iq]);
+};
+
+/* ----------------------------------------------------------- */
+
+WettingAngleExpl_ZOT::WettingAngleExpl_ZOT(DOFVectorBase<double> *vecDV_, DOFVectorBase<double> *gradDV_, double fac_)
+	: WettingAngle_ZOT(vecDV_,gradDV_,fac_)
+{
+  ERROR("Not implementet!\n");
+};
+double WettingAngleExpl_ZOT::f(const int iq) const
+{
+//     double c= std::max(-1.0, std::min(1.0, vec[iq]) );
+    return 1.0*norm(grad[iq]);
+};
+
+/* ----------------------------------------------------------- */
+
+WettingAngleImpl_ZOT::WettingAngleImpl_ZOT(DOFVectorBase<double> *vecDV_, DOFVectorBase<double> *gradDV_, double fac_)
+	: WettingAngle_ZOT(vecDV_,gradDV_,fac_)
+{
+  ERROR("Not implementet!\n");
+};
+double WettingAngleImpl_ZOT::f(const int iq) const
+{
+//     double c= std::max(-1.0, std::min(1.0, vec[iq]) );
+    return 2.0*norm(grad[iq]);
+};
+
+
+/* ----------------------------------------------------------- */
+
+WettingAngleImpl_FOT::WettingAngleImpl_FOT(DOFVectorBase<double>* chDV_,DOFVectorBase<double>* phaseDV_,double fac_) :
+        FirstOrderTerm(2), chDV(chDV_), phaseDV(phaseDV_), fac(fac_)
+{
+        TEST_EXIT(phaseDV_)("no vector phase!\n");
+        auxFeSpaces.insert(chDV_->getFeSpace());
+        auxFeSpaces.insert(phaseDV_->getFeSpace());
+};
+void WettingAngleImpl_FOT::initElement(const ElInfo* elInfo, 
+                        SubAssembler* subAssembler,
+                        Quadrature *quad) {
+  getGradientsAtQPs(chDV, elInfo, subAssembler, quad, gradCh);
+  getGradientsAtQPs(phaseDV, elInfo, subAssembler, quad, gradPhase);
+};
+void WettingAngleImpl_FOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+                        SubAssembler* subAssembler,
+                        Quadrature *quad) {
+  getGradientsAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, gradCh);
+  getGradientsAtQPs(phaseDV, smallElInfo, largeElInfo, subAssembler, quad, gradPhase);
+};
+void WettingAngleImpl_FOT::getLb(const ElInfo *elInfo, 
+            vector<mtl::dense_vector<double> >& result) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(result.size());
+    
+    for (int iq = 0; iq < nPoints; iq++) {
+        lb(Lambda, f(iq), result[iq], fac);
+    }
+};
+void WettingAngleImpl_FOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    double factor = fac * opFactor;
+    for (int iq = 0; iq < nPoints; iq++) {
+        double resultQP = grdUhAtQP[iq] * f(iq);
+        result[iq] += factor * resultQP;
+    }
+};
+
+WorldVector<double> WettingAngleImpl_FOT::f(const int iq) const
+{
+    WorldVector<double> result; result.set(0.0);
+    double nrmGradCh = norm(gradCh[iq]);
+    if (nrmGradCh > DBL_TOL) {
+      result = (2.0 * norm(gradPhase[iq]) / nrmGradCh) * gradCh[iq];
+    }
+    return result;
+};
+
+/* ----------------------------------------------------------- */
+/* ----------------------------------------------------------- */
+
+WettingAngle_Sharp_ZOT::WettingAngle_Sharp_ZOT(DOFVectorBase<double> *vecDV_, double fac_)
+  : ZeroOrderTerm(1), vecDV(vecDV_), fac(fac_)
+{
+  TEST_EXIT(vecDV_)("No first vector!\n");
+  auxFeSpaces.insert(vecDV_->getFeSpace());
+};
+void WettingAngle_Sharp_ZOT::initElement(const ElInfo* elInfo, 
+          SubAssembler* subAssembler,
+          Quadrature *quad)
+{
+  getGradientsAtQPs(vecDV, elInfo, subAssembler, quad, grad);
+};
+void WettingAngle_Sharp_ZOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+          SubAssembler* subAssembler,
+          Quadrature *quad)
+{
+  getGradientsAtQPs(vecDV, smallElInfo, largeElInfo, subAssembler, quad, grad);
+};
+void WettingAngle_Sharp_ZOT::getC(const ElInfo *, int nPoints, ElementVector &C)
+{   
+  for (int iq = 0; iq < nPoints; iq++)
+    C[iq] += f(iq)*fac;
+};
+void WettingAngle_Sharp_ZOT::eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor)
+{ 
+  for (int iq = 0; iq < nPoints; iq++) {    
+    result[iq] += f(iq) * uhAtQP[iq] * opFactor * fac;
+  }
+};
+double WettingAngle_Sharp_ZOT::f(const int iq) const
+{
+    double c= norm(grad[iq]);
+    return c;
+};
+
+/* ----------------------------------------------------------- */
+
+WettingAngleExpl_Sharp_ZOT::WettingAngleExpl_Sharp_ZOT(DOFVectorBase<double> *vecDV_, double fac_)
+  : WettingAngle_Sharp_ZOT(vecDV_,fac_)
+{
+  ERROR("Not implementet!\n");
+};
+double WettingAngleExpl_Sharp_ZOT::f(const int iq) const
+{
+//     double c= std::max(-1.0, std::min(1.0, vec[iq]) );
+    return 1.0;
+};
+
+/* ----------------------------------------------------------- */
+
+WettingAngleImpl_Sharp_ZOT::WettingAngleImpl_Sharp_ZOT(DOFVectorBase<double> *vecDV_, double fac_)
+  : WettingAngle_Sharp_ZOT(vecDV_,fac_)
+{
+  ERROR("Not implementet!\n");
+};
+double WettingAngleImpl_Sharp_ZOT::f(const int iq) const
+{
+//     double c= std::max(-1.0, std::min(1.0, vec[iq]) );
+    return 2.0;
+};
+
+
+/* ----------------------------------------------------------- */
+
+ViscosityPhase_SOT::ViscosityPhase_SOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *chDV_, double v1_, double v2_, double factor_)
+    : Phase_SOT(phaseDV_,factor_), chDV(chDV_), v1(v1_), v2(v2_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+};
+void ViscosityPhase_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+	Phase_SOT::initElement(elInfo, subAssembler, quad);
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void ViscosityPhase_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+	Phase_SOT::initElement(smallElInfo, largeElInfo, subAssembler, quad);
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+double ViscosityPhase_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(phase+1.0)-v2*0.5*(phase-1.0);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+Viscosity_SOT::Viscosity_SOT(DOFVectorBase<double> *chDV_, double v1_, double v2_, double factor_)
+    : SecondOrderTerm(1), chDV(chDV_), v1(v1_), v2(v2_), factor(factor_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+};
+void Viscosity_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void Viscosity_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void Viscosity_SOT::getLALt(const ElInfo *elInfo,
+            std::vector<mtl::dense2D<double> > &LALt) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+    for (int iq = 0; iq < nPoints; iq++)
+        l1lt(Lambda, LALt[iq], f(iq) * factor);
+};
+void Viscosity_SOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            double feval = f(iq) * opFactor * factor;
+            double resultQP = 0.0;
+            for (int i = 0; i < dimOfWorld; i++)
+                resultQP += D2UhAtQP[iq][i][i]; 
+            result[iq] += feval * resultQP;
+        }
+    }
+};
+void Viscosity_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+            std::vector<WorldVector<double> > &result)
+{
+    int nPoints = grdUhAtQP.size();
+    for (int iq = 0; iq < nPoints; iq++) {
+        double fac = f(iq) * factor;
+        axpy(fac, grdUhAtQP[iq], result[iq]);
+    }
+};
+double Viscosity_SOT::f(const int iq) const
+{
+    double phase= std::max(-1.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*0.5*(phase+1.0)-v2*0.5*(phase-1.0);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+/* ----------------------------------------------------------- */
+
+ViscosityPhase2_SOT::ViscosityPhase2_SOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *chDV_, double v1_, double v2_, double factor_)
+    : Phase_SOT(phaseDV_,factor_), chDV(chDV_), v1(v1_), v2(v2_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+};
+void ViscosityPhase2_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+  Phase_SOT::initElement(elInfo, subAssembler, quad);
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void ViscosityPhase2_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+  Phase_SOT::initElement(smallElInfo, largeElInfo, subAssembler, quad);
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+double ViscosityPhase2_SOT::f(const int iq) const
+{
+    double phase= std::max(0.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*phase+v2*(1.0-phase);
+    return viscosity;
+};
+
+/* ----------------------------------------------------------- */
+
+Viscosity2_SOT::Viscosity2_SOT(DOFVectorBase<double> *chDV_, double v1_, double v2_, double factor_)
+    : SecondOrderTerm(1), chDV(chDV_), v1(v1_), v2(v2_), factor(factor_)
+{
+    setSymmetric(true);
+    
+    TEST_EXIT(chDV)("No vector!\n");
+    auxFeSpaces.insert(chDV->getFeSpace());
+};
+void Viscosity2_SOT::initElement(const ElInfo* elInfo, 
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, elInfo, subAssembler, quad, ch);
+};
+void Viscosity2_SOT::initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+            SubAssembler* subAssembler,
+            Quadrature* quad) 
+{
+    getVectorAtQPs(chDV, smallElInfo, largeElInfo, subAssembler, quad, ch);
+};
+void Viscosity2_SOT::getLALt(const ElInfo *elInfo,
+            std::vector<mtl::dense2D<double> > &LALt) const
+{
+    const DimVec<WorldVector<double> > &Lambda = elInfo->getGrdLambda();
+    const int nPoints = static_cast<int>(LALt.size());
+    
+    for (int iq = 0; iq < nPoints; iq++)
+        l1lt(Lambda, LALt[iq], f(iq) * factor);
+};
+void Viscosity2_SOT::eval(int nPoints,
+            const mtl::dense_vector<double>& uhAtQP,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor)
+{   
+    if (num_rows(D2UhAtQP) > 0) {
+        for (int iq = 0; iq < nPoints; iq++) {
+            double feval = f(iq) * opFactor * factor;
+            double resultQP = 0.0;
+            for (int i = 0; i < dimOfWorld; i++)
+                resultQP += D2UhAtQP[iq][i][i]; 
+            result[iq] += feval * resultQP;
+        }
+    }
+};
+void Viscosity2_SOT::weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+            std::vector<WorldVector<double> > &result)
+{
+    int nPoints = grdUhAtQP.size();
+    for (int iq = 0; iq < nPoints; iq++) {
+        double fac = f(iq) * factor;
+        axpy(fac, grdUhAtQP[iq], result[iq]);
+    }
+};
+double Viscosity2_SOT::f(const int iq) const
+{
+    double phase= std::max(0.0,std::min(1.0,ch[iq]));
+    double viscosity= v1*phase+v2*(1.0-phase);
+    return viscosity;
+};
diff --git a/extensions/POperators.h b/extensions/POperators.h
new file mode 100644
index 0000000000000000000000000000000000000000..c134970536a7ab0087d3988c31f91dc6b189b6aa
--- /dev/null
+++ b/extensions/POperators.h
@@ -0,0 +1,10 @@
+/** \file POperators.h */
+
+#ifndef P_OPERATORS_H
+#define P_OPERATORS_H
+
+#include "POperators_ZOT.h"
+#include "POperators_FOT.h"
+#include "POperators_SOT.h"
+
+#endif // P_OPERATORS_H
diff --git a/extensions/POperators_FOT.h b/extensions/POperators_FOT.h
new file mode 100644
index 0000000000000000000000000000000000000000..af232352f38032ed3e175b2fdc75a649eb9a7659
--- /dev/null
+++ b/extensions/POperators_FOT.h
@@ -0,0 +1,422 @@
+/** \file POperators_FOT.h */
+
+#ifndef P_OPERATORS_FOT_H
+#define P_OPERATORS_FOT_H
+
+#include "AMDiS.h"
+
+using namespace std;
+using namespace AMDiS;
+
+
+/// < factor*phase*grad(u) , grad(psi) >
+class Phase_FOT : public FirstOrderTerm 
+{
+public:
+/// Constructor.
+Phase_FOT(DOFVectorBase<double>* phaseDV, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+    Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+    SubAssembler* subAssembler,
+    Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+    vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+    const mtl::dense_vector<double>&,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor);
+
+virtual WorldVector<double> f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+double fac;
+};
+
+/// < phase*(vecs*grad(u)) , psi > or < phase*vecs*u , grad(psi) > where vecs in R^n
+class WorldVecAndVecFct_FOT : public FirstOrderTerm
+{
+public:
+WorldVecAndVecFct_FOT(WorldVector<DOFVectorBase<double>*> vecs,
+	DOFVectorBase<double>* phaseDV_, double fac=1.0);
+
+void initElement(const ElInfo*, 
+	SubAssembler* ,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+		vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+DOFVectorBase<double> *vec0DV, *vec1DV, *vec2DV, *phaseDV;
+mtl::dense_vector<double> phase, vec0, vec1, vec2;
+double fac;
+int numVecs;
+};
+
+
+
+/* -------------------------------------------------------------- */
+
+/// < vecs*grad(u) , psi > or < vecs*u , grad(psi) > where vecs in R^n
+class WorldVec_FOT : public FirstOrderTerm
+{
+public:
+WorldVec_FOT(WorldVector<DOFVector<double>*> vecs,double fac=1.0);
+
+void initElement(const ElInfo*, 
+	SubAssembler* ,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+		vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+DOFVectorBase<double> *vec0DV, *vec1DV, *vec2DV;
+mtl::dense_vector<double> vec0, vec1, vec2;
+double fac;
+int numVecs;
+};
+
+/* -------------------------------------------------------------- */
+
+/// First order term: \f$ < \vec{v}(\vec{x}) \cdot \nabla u(\vec{x}) , \theta > or < \vec{v}(\vec{x}) \cdot u(\vec{x}) , \nabla \theta >\f$.
+class WorldVector_FOT : public FirstOrderTerm
+{
+public:
+  /// Constructor.
+  WorldVector_FOT(DOFVector<WorldVector<double> > *dv, double fac_=1.0);
+
+  /// Implementation of \ref OperatorTerm::initElement().
+  void initElement(const ElInfo* elInfo,
+		   SubAssembler* subAssembler,
+		   Quadrature *quad = NULL);
+  
+  void initElement(const ElInfo* largeElInfo,
+		   const ElInfo* smallElInfo,
+		   SubAssembler* subAssembler,
+		   Quadrature *quad = NULL);
+
+  /// Implements FirstOrderTerm::getLb().
+  void getLb(const ElInfo *elInfo,
+	     vector<mtl::dense_vector<double> >& Lb) const;
+
+  /// Implements FirstOrderTerm::eval().
+  void eval(int nPoints,
+	    const mtl::dense_vector<double>&,
+	    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+	    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+	    mtl::dense_vector<double>& result,
+	    double factor);
+
+protected:
+  DOFVector<WorldVector<double> >* vec;
+
+  /// Gradient of v at quadrature points.
+  mtl::dense_vector<WorldVector<double> > vecAtQPs;
+
+  double fac;
+};
+
+/// < phase*(vecs*grad(u)) , psi > or < phase*vecs*u , grad(psi) > where vecs in R^n
+class WorldVecPhase_FOT : public FirstOrderTerm
+{
+public:
+WorldVecPhase_FOT(DOFVectorBase<double>* phaseDV_, WorldVector<DOFVector<double>*> vecs,
+    double fac=1.0);
+
+void initElement(const ElInfo*, 
+    SubAssembler* ,
+    Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+    SubAssembler*,
+    Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+        vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>&,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+protected:
+DOFVectorBase<double> *vec0DV, *vec1DV, *vec2DV, *phaseDV;
+mtl::dense_vector<double> phase, vec0, vec1, vec2;
+double fac;
+int numVecs;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*d_i(u) , psi > or < factor*u , d_i(psi) >
+class PartialDerivative_FOT : public FirstOrderTerm
+{
+public:
+PartialDerivative_FOT(int component_, double fac_=1.0);
+
+void initElement(const ElInfo*, 
+	SubAssembler*,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+		vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+int component;
+double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v1*d_i(u) , psi > or < factor*v1*u , d_i(psi) >
+class VecAndPartialDerivative_FOT : public FirstOrderTerm
+{
+public:
+
+VecAndPartialDerivative_FOT(DOFVectorBase<double> *dv1, int component_, 
+  double fac_=1.0);
+
+void initElement(const ElInfo* elInfo,
+  SubAssembler* subAssembler,
+  Quadrature *quad = NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+  SubAssembler* subAssembler,
+  Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo, vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+  const mtl::dense_vector<double>&,
+  const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+  const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+  mtl::dense_vector<double>& result,
+  double opFactor);
+
+protected:
+DOFVectorBase<double>* vec1DV;
+mtl::dense_vector<double> vec1;
+double fac;
+int component;
+};
+/* -------------------------------------------------------------- */
+
+
+/// < phase*d_i(u) * n_j , psi > or < phase*u*n_j , d_i(psi) > where vecs in R^n
+class PhaseAndViscosityPartialDerivativeBoundary_FOT : public FirstOrderTerm
+{
+public:
+PhaseAndViscosityPartialDerivativeBoundary_FOT(DOFVectorBase<double>* phaseDV_, DOFVectorBase<double>* chDV_, int component, int normalComponent, double viscosity1=1.0, double viscosity2=1.0);
+
+void initElement(const ElInfo*, 
+        SubAssembler* ,
+        Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler*,
+        Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+                vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+                const mtl::dense_vector<double>&,
+                const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+                const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+                mtl::dense_vector<double>& result,
+                double opFactor);
+
+double f(const int iq) const;
+protected:
+DOFVectorBase<double> *phaseDV, *chDV;
+mtl::dense_vector<double> phase, ch;
+double v1, v2, normalJ;
+int component, normalComponent;
+};
+
+/* -------------------------------------------------------------- */
+
+
+/// < d_i(u) * n_j , psi > or < u*n_j , d_i(psi) > where vecs in R^n
+class ViscosityPartialDerivativeBoundary_FOT : public FirstOrderTerm
+{
+public:
+ViscosityPartialDerivativeBoundary_FOT(DOFVectorBase<double>* chDV_, int component, int normalComponent, double viscosity1=1.0, double viscosity2=1.0);
+
+void initElement(const ElInfo*, 
+        SubAssembler* ,
+        Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler*,
+        Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo,
+                vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+                const mtl::dense_vector<double>&,
+                const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+                const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+                mtl::dense_vector<double>& result,
+                double opFactor);
+double f(const int iq) const;
+protected:
+DOFVectorBase<double> *chDV;
+mtl::dense_vector<double> ch;
+double v1, v2, normalJ;
+int component, normalComponent;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v1*v2*d_i(u) , psi > or < factor*v1*v2*u , d_i(psi) >
+class Vec2ProductPartial_FOT : public FirstOrderTerm
+{
+public:
+
+Vec2ProductPartial_FOT(DOFVectorBase<double> *dv1, DOFVectorBase<double> *dv2,
+	int component_, double fac_=1.0);
+
+void initElement(const ElInfo* elInfo,
+	SubAssembler* subAssembler,
+	Quadrature *quad = NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler* subAssembler,
+	Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo, vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+	const mtl::dense_vector<double>&,
+	const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+	const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+	mtl::dense_vector<double>& result,
+	double opFactor);
+
+protected:
+DOFVectorBase<double>* vec1DV;
+DOFVectorBase<double>* vec2DV;
+mtl::dense_vector<double> vec1,vec2;
+double fac;
+int component;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*grad(u) , grad(psi) >
+class WettingAngleImpl_FOT : public FirstOrderTerm 
+{
+public:
+/// Constructor.
+WettingAngleImpl_FOT(DOFVectorBase<double>* chDV, DOFVectorBase<double>* phaseDV, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+                Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+                SubAssembler* subAssembler,
+                Quadrature *quad = NULL);
+
+void getLb(const ElInfo *elInfo, vector<mtl::dense_vector<double> >& result) const;
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>&,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+inline WorldVector<double> f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV, *chDV;
+
+mtl::dense_vector<WorldVector<double> > gradPhase, gradCh;
+double fac;
+};
+/* -------------------------------------------------------------- */
+
+class Mobility2CHPhase_FOT : public Phase_FOT
+{
+public:
+/// Constructor.
+Mobility2CHPhase_FOT(
+  DOFVectorBase<double>* phaseDV, 
+  DOFVectorBase<double> *chDV_, 
+  DOFVectorBase<double> *muDV_, 
+  double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+inline WorldVector<double> f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+DOFVectorBase<double>* muDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+mtl::dense_vector<WorldVector<double> > grdMu;
+double delta;
+
+};
+
+#endif // P_OPERATORS_FOT_H
diff --git a/extensions/POperators_SOT.h b/extensions/POperators_SOT.h
new file mode 100644
index 0000000000000000000000000000000000000000..aea50850b1f666ead10e83e072c818314eaf67cf
--- /dev/null
+++ b/extensions/POperators_SOT.h
@@ -0,0 +1,625 @@
+/** \file POperators_SOT.h */
+
+#ifndef P_OPERATORS_SOT_H
+#define P_OPERATORS_SOT_H
+
+#include "AMDiS.h"
+
+using namespace std;
+using namespace AMDiS;
+
+/// < factor*phase*grad(u) , grad(psi) >
+class Phase_SOT : public SecondOrderTerm 
+{
+public:
+/// Constructor.
+Phase_SOT(DOFVectorBase<double>* phaseDV, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+
+/// Implements SecondOrderTerm::getLALt().
+inline void getLALt(const ElInfo *elInfo, std::vector<mtl::dense2D<double> > &LALt) const;    
+
+/// Implenetation of SecondOrderTerm::eval().
+inline void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+/// Implenetation of SecondOrderTerm::weakEval().
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+		std::vector<WorldVector<double> > &result);
+
+virtual double f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+class Mobility_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor.
+Mobility_SOT(DOFVectorBase<double> *rhoDV_, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* rhoDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> rho;
+double factor, eps, rho0, density, mobilityDerivative;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class MobilityCH_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor.
+MobilityCH_SOT(DOFVectorBase<double> *chDV_, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double factor, delta;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class MobilityCHPhase_SOT : public Phase_SOT
+{
+public:
+/// Constructor.
+MobilityCHPhase_SOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double> *chDV_, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double delta;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class MobilityCH2_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor.
+MobilityCH2_SOT(DOFVectorBase<double> *chDV_, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double factor, delta;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class ViscosityPhase_SOT : public Phase_SOT
+{
+public:
+/// Constructor.
+ViscosityPhase_SOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *chDV_, double v1_=1.0, double v2_=1.0, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double v1,v2;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class ViscosityPhase2_SOT : public Phase_SOT
+{
+public:
+/// Constructor.
+ViscosityPhase2_SOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *chDV_, double v1_=1.0, double v2_=1.0, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double v1,v2;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class Viscosity_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor.
+Viscosity_SOT(DOFVectorBase<double> *chDV_, double v1_=1.0, double v2_=1.0, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double v1,v2;
+double factor;
+
+};
+
+/* -------------------------------------------------------------- */
+
+class Viscosity2_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor.
+Viscosity2_SOT(DOFVectorBase<double> *chDV_, double v1_=1.0, double v2_=1.0, double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+double v1,v2;
+double factor;
+
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*A*grad(u) , grad(psi) > ... 'I' kann ueberladen werden
+class MatrixPhase_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixPhase_SOT(DOFVectorBase<double>* phaseDV, int comp, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+inline void lDlt(const DimVec<WorldVector<double> >& Lambda, 
+            const WorldVector<double>& vec,
+            mtl::dense2D<double>& LALt,
+            double factor) const;
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+
+inline WorldVector<double> f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+int comp;
+double fac;
+bool symmetric;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*()_ij*grad(u) , grad(psi) >
+class MatrixIJ_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixIJ_SOT(int row, int col, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL) {}
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL) {}
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+int row,col;
+double fac;
+bool symmetric;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*A*grad(u) , grad(psi) > ... 'I' kann ueberladen werden
+class MatrixIJPhase_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixIJPhase_SOT(DOFVectorBase<double>* phaseDV, int row, int col, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+int row,col;
+double fac;
+bool symmetric;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*A*grad(u) , grad(psi) > ... 'I' kann ueberladen werden
+class MatrixIJViscosityPhase_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixIJViscosityPhase_SOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double>* chDV, int row, int col, double v1_, double v2_, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+void setFactor(const double fac_) { fac=fac_; }
+inline double f(const int iq) const;
+
+protected:
+DOFVectorBase<double> *phaseDV;
+DOFVectorBase<double>* chDV;
+
+mtl::dense_vector<double> ch;
+mtl::dense_vector<double> phase;
+int row,col;
+double v1,v2;
+double fac;
+bool symmetric;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*A*grad(u) , grad(psi) > ... 'I' kann ueberladen werden
+class MatrixIJViscosity_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixIJViscosity_SOT(DOFVectorBase<double>* chDV, int row, int col, double v1_, double v2_, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+void setFactor(const double fac_) { fac=fac_; }
+inline double f(const int iq) const;
+
+protected:
+DOFVectorBase<double>* chDV;
+
+mtl::dense_vector<double> ch;
+int row,col;
+double v1,v2;
+double fac;
+bool symmetric;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*A*grad(u) , grad(psi) > ... 'I' kann ueberladen werden
+class MatrixIJViscosityPhase2_SOT : public SecondOrderTerm
+{
+public:
+/// Constructor
+MatrixIJViscosityPhase2_SOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double>* chDV, int row, int col, double v1_, double v2_, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad=NULL);
+void getLALt(const ElInfo *elInfo,
+        std::vector<mtl::dense2D<double> > &LALt) const; 
+void eval(int nPoints,
+        const mtl::dense_vector<double>& uhAtQP,
+        const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+        const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+        mtl::dense_vector<double>& result,
+        double opFactor);
+void weakEval(const std::vector<WorldVector<double> > &grdUhAtQP,
+        std::vector<WorldVector<double> > &result);
+void setFactor(const double fac_) { fac=fac_; }
+inline double f(const int iq) const;
+
+protected:
+DOFVectorBase<double> *phaseDV;
+DOFVectorBase<double>* chDV;
+
+mtl::dense_vector<double> ch;
+mtl::dense_vector<double> phase;
+int row,col;
+double v1,v2;
+double fac;
+bool symmetric;
+};
+
+#endif // P_OPERATORS_SOT_H
diff --git a/extensions/POperators_ZOT.h b/extensions/POperators_ZOT.h
new file mode 100644
index 0000000000000000000000000000000000000000..6671c8133f2004da8d44219755efa33f5e040b2d
--- /dev/null
+++ b/extensions/POperators_ZOT.h
@@ -0,0 +1,560 @@
+/** \file POperators_ZOT.h */
+
+#ifndef P_OPERATORS_ZOT_H
+#define P_OPERATORS_ZOT_H
+
+#include "AMDiS.h"
+
+using namespace std;
+using namespace AMDiS;
+
+/// < factor*phase*u , psi >
+class Phase_ZOT : public ZeroOrderTerm 
+{ 
+public: 
+Phase_ZOT(DOFVectorBase<double>* phaseDV, double fac=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+		SubAssembler* subAssembler,
+		Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad=NULL);
+
+inline void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+inline void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+virtual double f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+double fac;
+}; 
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*v*u , psi >
+class FactorPhase_ZOT : public Phase_ZOT
+{
+public:
+	FactorPhase_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*(1-phase)*u , psi > or < factor*v[i]*(1-phase)*u , psi > where v in R^n
+class PhaseInverse_ZOT : public ZeroOrderTerm 
+{ 
+public: 
+PhaseInverse_ZOT(DOFVectorBase<double>* phaseDV, double fac=1.0);
+PhaseInverse_ZOT(DOFVectorBase<double>* phaseDV, double fac, WorldVector<double>* facVec, int component);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, 
+		SubAssembler* subAssembler,
+		Quadrature *quad=NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad=NULL);
+
+inline void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+inline void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+inline double f(const int iq) const;
+void setFactor(const double fac_) { fac=fac_; }
+
+protected:
+DOFVectorBase<double> *phaseDV;
+mtl::dense_vector<double> phase;
+double fac;
+int component;
+WorldVector<double>* facVec;
+}; 
+
+/* -------------------------------------------------------------- */
+
+/// < factor*(v^3)*u , psi >
+class Pow3_ZOT : public ZeroOrderTerm
+{
+public:
+	Pow3_ZOT(DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+inline void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+inline void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+	double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*(v^3)*phi*u , psi >
+class Pow3Phase_ZOT : public Phase_ZOT
+{
+public:
+	Pow3Phase_ZOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+};
+/* -------------------------------------------------------------- */
+
+/// < factor*(v^2)*u , psi >
+class Pow2_ZOT : public ZeroOrderTerm
+{
+public:
+	Pow2_ZOT(DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+inline void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+inline void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+	double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*(v^2)*phi*u , psi >
+class Pow2Phase_ZOT : public Phase_ZOT
+{
+public:
+	Pow2Phase_ZOT(DOFVectorBase<double>* phaseDV, DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*phase*(-1/max(1e-6, sqr(v+0.9)))*u , psi >
+class ConstrainedFracSqr_ZOT : public Phase_ZOT
+{
+public:
+	ConstrainedFracSqr_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+};
+
+/// < factor*phase*(1/max(1e-6, v+0.9))*u , psi >
+class ConstrainedFrac_ZOT : public Phase_ZOT
+{
+public:
+	ConstrainedFrac_ZOT(DOFVectorBase<double> *phaseDV_, DOFVectorBase<double> *rhoDV_, double fac_=1.0);
+	void initElement(const ElInfo* elInfo,
+		SubAssembler* subAssembler,
+		Quadrature *quad = NULL);
+	void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+		SubAssembler*,
+		Quadrature *quad = NULL);
+	inline double f(const int iq) const;
+protected:
+	DOFVectorBase<double> *rhoDV;
+	mtl::dense_vector<double> rho;
+};
+
+/// < (...)*u , psi >
+class ConstrainedPowImpl_ZOT : public ZeroOrderTerm
+{
+public:
+    ConstrainedPowImpl_ZOT(DOFVectorBase<double> *rhoDV_, double p_=20.0, double rhoMin_=-0.9, double fac_=1.0);
+    void initElement(const ElInfo* elInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+    void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler*,
+        Quadrature *quad = NULL);
+    void getC(const ElInfo *, int nPoints, ElementVector &C);
+    void eval(int nPoints,
+            const mtl::dense_vector<double>&,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor);
+    inline double f(const int iq) const;
+protected:
+    DOFVectorBase<double> *rhoDV;
+    mtl::dense_vector<double> rho;
+    double p,rhoMin,fac;
+};
+
+/// < (...)*u , psi >
+class ConstrainedPowExpl_ZOT : public ZeroOrderTerm
+{
+public:
+    ConstrainedPowExpl_ZOT(DOFVectorBase<double> *rhoDV_, double p_=20.0, double rhoMin_=-0.9, double fac_=1.0);
+    void initElement(const ElInfo* elInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+    void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler*,
+        Quadrature *quad = NULL);
+    void getC(const ElInfo *, int nPoints, ElementVector &C);
+    void eval(int nPoints,
+            const mtl::dense_vector<double>&,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor);
+    inline double f(const int iq) const;
+protected:
+    DOFVectorBase<double> *rhoDV;
+    mtl::dense_vector<double> rho;
+    double p,rhoMin,fac;
+};
+
+/// < (...)*u , psi >
+class ConstrainedPow_ZOT : public ZeroOrderTerm
+{
+public:
+    ConstrainedPow_ZOT(DOFVectorBase<double> *rhoDV_, double p_=20.0, double rhoMin_=-0.9, double fac_=1.0);
+    void initElement(const ElInfo* elInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+    void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler*,
+        Quadrature *quad = NULL);
+    void getC(const ElInfo *, int nPoints, ElementVector &C);
+    void eval(int nPoints,
+            const mtl::dense_vector<double>&,
+            const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+            const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+            mtl::dense_vector<double>& result,
+            double opFactor);
+    inline double f(const int iq) const;
+protected:
+    DOFVectorBase<double> *rhoDV;
+    mtl::dense_vector<double> rho;
+    double p,rhoMin,fac;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*d_i(v)*u , psi > or < factor*b[j]*d_i(v)*u , psi >
+class PartialDerivative_ZOT : public ZeroOrderTerm
+{
+public:
+PartialDerivative_ZOT(DOFVectorBase<double>* vecDV_, int component_, double fac_=1.0);
+PartialDerivative_ZOT(DOFVectorBase<double>* vecDV_, int component_, double fac_, WorldVector<double>* vec, int component2_);
+
+void initElement(const ElInfo*, 
+	SubAssembler*,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+DOFVectorBase<double> *vecDV;
+mtl::dense_vector<WorldVector<double> > grad;
+double fac;
+WorldVector<double>* facVec;
+int component, component2;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class VecAndPartialDerivative_ZOT : public ZeroOrderTerm
+{
+public:
+VecAndPartialDerivative_ZOT(DOFVectorBase<double>* vecDV_, DOFVectorBase<double>* gradDV_, int component_, double fac_=1.0);
+
+void initElement(const ElInfo*, 
+	SubAssembler*,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+DOFVectorBase<double> *vecDV, *gradDV;
+mtl::dense_vector<double> vec;
+double fac;
+mtl::dense_vector<WorldVector<double> > grad;
+int component;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v1*v2*d_i(w)*u , psi >
+class Vec2AndPartialDerivative_ZOT : public ZeroOrderTerm
+{
+public:
+Vec2AndPartialDerivative_ZOT(DOFVectorBase<double>* vec1DV_, DOFVectorBase<double>* vec2DV_, DOFVectorBase<double>* gradDV_, int component_, double fac_=1.0);
+
+void initElement(const ElInfo*,
+	SubAssembler*,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+
+protected:
+DOFVectorBase<double> *vec1DV, *vec2DV, *gradDV;
+mtl::dense_vector<double> vec1, vec2;
+double fac;
+mtl::dense_vector<WorldVector<double> > grad;
+int component;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngle_ZOT : public ZeroOrderTerm
+{
+public:
+WettingAngle_ZOT(DOFVectorBase<double>* vecDV_, DOFVectorBase<double>* gradDV_, double fac_=1.0);
+
+void initElement(const ElInfo*, 
+	SubAssembler*,
+	Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+	SubAssembler*,
+	Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+		const mtl::dense_vector<double>&,
+		const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+		const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+		mtl::dense_vector<double>& result,
+		double opFactor);
+inline double f(const int iq) const;
+
+protected:
+DOFVectorBase<double> *vecDV, *gradDV;
+// mtl::dense_vector<double> vec;
+double fac;
+mtl::dense_vector<WorldVector<double> > grad;
+mtl::dense_vector<WorldVector<double> > gradC;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngleExpl_ZOT : public WettingAngle_ZOT
+{
+public:
+WettingAngleExpl_ZOT(DOFVectorBase<double>* vecDV_, DOFVectorBase<double>* gradDV_, double fac_=1.0);
+
+inline double f(const int iq) const;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngleImpl_ZOT : public WettingAngle_ZOT
+{
+public:
+WettingAngleImpl_ZOT(DOFVectorBase<double>* vecDV_, DOFVectorBase<double>* gradDV_, double fac_=1.0);
+
+inline double f(const int iq) const;
+};
+
+/* -------------------------------------------------------------- */
+
+class WettingAngleLowerOrder_ZOT : public ZeroOrderTerm
+{
+public:
+/// Constructor.
+WettingAngleLowerOrder_ZOT(
+  DOFVectorBase<double> *chDV_, 
+  DOFVectorBase<double>* phaseDV, 
+  double factor_=1.0);
+
+/// Implementation of \ref OperatorTerm::initElement().
+void initElement(const ElInfo* elInfo, SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+/// Implementation of \ref OperatorTerm::initElement() for multilpe meshes.
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+        SubAssembler* subAssembler,
+        Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+    const mtl::dense_vector<double>&,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor);
+inline double f(const int iq) const;
+
+protected:
+
+/** \brief
+* DOFVector to be evaluated at quadrature points.
+*/
+DOFVectorBase<double>* chDV;
+DOFVectorBase<double>* phaseDV;
+
+/** \brief
+* Vector v at quadrature points.
+*/
+mtl::dense_vector<double> ch;
+mtl::dense_vector<double> phase;
+mtl::dense_vector<WorldVector<double> > grdCh;
+mtl::dense_vector<WorldVector<double> > grdPhase;
+
+double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngle_Sharp_ZOT : public ZeroOrderTerm
+{
+public:
+WettingAngle_Sharp_ZOT(DOFVectorBase<double>* vecDV_, double fac_=1.0);
+
+void initElement(const ElInfo*, 
+  SubAssembler*,
+  Quadrature *quad= NULL);
+void initElement(const ElInfo* largeElInfo, const ElInfo* smallElInfo,
+  SubAssembler*,
+  Quadrature *quad = NULL);
+
+void getC(const ElInfo *, int nPoints, ElementVector &C);
+
+void eval(int nPoints,
+    const mtl::dense_vector<double>&,
+    const mtl::dense_vector<WorldVector<double> >& grdUhAtQP,
+    const mtl::dense_vector<WorldMatrix<double> >& D2UhAtQP,
+    mtl::dense_vector<double>& result,
+    double opFactor);
+inline double f(const int iq) const;
+
+protected:
+DOFVectorBase<double> *vecDV;
+mtl::dense_vector<WorldVector<double> > grad;
+double fac;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngleExpl_Sharp_ZOT : public WettingAngle_Sharp_ZOT
+{
+public:
+WettingAngleExpl_Sharp_ZOT(DOFVectorBase<double>* vecDV_, double fac_=1.0);
+
+inline double f(const int iq) const;
+};
+
+/* -------------------------------------------------------------- */
+
+/// < factor*v*d_i(w)*u , psi >
+class WettingAngleImpl_Sharp_ZOT : public WettingAngle_Sharp_ZOT
+{
+public:
+WettingAngleImpl_Sharp_ZOT(DOFVectorBase<double>* vecDV_, double fac_=1.0);
+
+inline double f(const int iq) const;
+};
+
+#endif // P_OPERATORS_ZOT_H
diff --git a/extensions/PhaseFieldConvert.h b/extensions/PhaseFieldConvert.h
new file mode 100644
index 0000000000000000000000000000000000000000..4dddd39cf579d65ca98e95234fb406ea24a3fedd
--- /dev/null
+++ b/extensions/PhaseFieldConvert.h
@@ -0,0 +1,174 @@
+/** \file PhaseFieldConvert.h */
+
+#ifndef PHASE_FIELD_CONVERT_H
+#define PHASE_FIELD_CONVERT_H
+
+using namespace AMDiS;
+
+struct SignedDistFctToPhaseField : AbstractFunction<double, WorldVector<double> >
+{
+  SignedDistFctToPhaseField(double epsilon_, 
+			    AbstractFunction<double,WorldVector<double> > *dist_, 
+			    double scalingFactor_ = 1.0/sqrt(2.0))
+  : AbstractFunction<double, WorldVector<double> >(6), 
+    epsilon(epsilon_), 
+    dist(dist_),
+    scalingFactor(scalingFactor_) {};
+
+  double operator()(const WorldVector<double> &x) const
+  {
+    return 0.5 * (1.0 - tanh(scalingFactor * (*dist)(x) / epsilon));
+  }
+        
+private:
+
+  double epsilon;
+  AbstractFunction<double,WorldVector<double> > *dist;
+  double scalingFactor;
+};
+
+struct SignedDistFctListToPhaseField : AbstractFunction<double, WorldVector<double> >
+{
+  SignedDistFctListToPhaseField(double epsilon_, 
+				std::vector<AbstractFunction<double,WorldVector<double> >*> dist_, 
+				double scalingFactor_ = 1.0/sqrt(2.0))
+  : AbstractFunction<double, WorldVector<double> >(6), 
+    epsilon(epsilon_), 
+    dist(dist_),
+    scalingFactor(scalingFactor_) {};
+
+  double operator()(const WorldVector<double> &x) const
+  {
+    double d = 1.e12;
+    for (size_t i = 0; i < dist.size(); ++i) {
+      d = std::min((*(dist[i]))(x), d);
+    }
+    return 0.5 * (1.0 - tanh(scalingFactor * d / epsilon));
+  }
+        
+private:
+
+  double epsilon;
+  std::vector<AbstractFunction<double,WorldVector<double> >*> dist;
+  double scalingFactor;
+};
+
+
+struct SignedDistList : AbstractFunction<double, WorldVector<double> >
+{
+  SignedDistList(std::vector<AbstractFunction<double,WorldVector<double> >*> dist_)
+  : AbstractFunction<double, WorldVector<double> >(1), 
+    dist(dist_) {};
+
+  double operator()(const WorldVector<double> &x) const
+  {
+    d.setX(x);
+    return std::for_each(dist.begin(), dist.end(), d);
+  }
+
+private:  
+  struct MyMax {
+    mutable double val;
+    mutable WorldVector< double > x;
+    MyMax()
+    : val(-1.0e12) {}
+    
+    void operator()(const AbstractFunction<double,WorldVector<double> >* v) const
+    {
+      val = max((*v)(x), val);
+    }
+    
+    void setX(const WorldVector<double> &x_) const
+    {
+      x= x_;
+    }
+    
+    inline operator double() { return val; }
+  } d;
+  
+  std::vector<AbstractFunction<double,WorldVector<double> >*> dist;
+};
+
+struct PhaseFieldToSignedDist : AbstractFunction<double, double>
+{
+  PhaseFieldToSignedDist(double epsilon_= -1.0, double scalingFactor_ = 1.0/sqrt(2.0))
+  : AbstractFunction<double, double>(6), 
+    epsilon(epsilon_),
+    scalingFactor(scalingFactor_)
+  {
+    if (epsilon < 0.0)
+      Parameters::get("mesh->refinement->epsilon", epsilon);
+  }
+  
+  double operator()(const double &phi) const
+  {
+    double z = std::max(-1.0 + 1.e-10, std::min(1.0 - 1.e-10, -phi));
+    return (epsilon/scalingFactor) * atanh(z);
+  }
+  
+private:
+  double epsilon;
+  double scalingFactor;
+};
+
+struct SignedDistToPhaseField : AbstractFunction<double, double>
+{
+  SignedDistToPhaseField(double epsilon_ = -1.0, double scalingFactor_ = 1.0/sqrt(2.0))
+  : AbstractFunction<double, double>(6),
+    epsilon(epsilon_),
+    scalingFactor(scalingFactor_)
+  {
+    if (epsilon < 0.0)
+      Parameters::get("mesh->refinement->epsilon", epsilon);
+  }
+  
+  double operator()(const double &dist) const
+  {
+    return 0.5 * (1.0 - tanh(scalingFactor * dist / epsilon));
+  }
+  
+private:
+  double epsilon;
+  double scalingFactor;
+};
+
+struct SignedDistToCh : AbstractFunction<double, double>
+{
+  SignedDistToCh(double epsilon_ = -1.0, double scalingFactor_ = 1.0/sqrt(2.0))
+  : AbstractFunction<double, double>(6),
+    epsilon(epsilon_),
+    scalingFactor(scalingFactor_)
+  {
+    if (epsilon < 0.0)
+      Parameters::get("mesh->refinement->epsilon", epsilon);
+  }
+  
+  double operator()(const double &dist) const
+  {
+    return -tanh(scalingFactor * dist / epsilon);
+  }
+  
+private:
+  double epsilon;
+  double scalingFactor;
+};
+
+struct ChToPhaseField : AbstractFunction<double, double>
+{
+  ChToPhaseField() : AbstractFunction<double, double>(1) {};
+  double operator()(const double &c) const
+  {
+    return std::max(0.0, std::min(1.0, 0.5 * (c + 1.0)));
+  }
+};
+
+struct PhaseFieldToCh : AbstractFunction<double, double>
+{
+  PhaseFieldToCh() : AbstractFunction<double, double>(1) {};
+  double operator()(const double &c) const
+  {
+    return std::max(-1.0, std::min(1.0, 2.0 * c - 1.0));
+  }
+};
+
+#endif // PHASE_FIELD_CONVERT_H
diff --git a/extensions/Refinement.h b/extensions/Refinement.h
new file mode 100644
index 0000000000000000000000000000000000000000..08df6caf2a4ac9a4b13b4955fcb777adfdcfa128
--- /dev/null
+++ b/extensions/Refinement.h
@@ -0,0 +1,272 @@
+/** \file Refinement.h */
+
+#ifndef REFINEMENT_H
+#define REFINEMENT_H
+
+#include "ElementFunction.h"
+
+using namespace AMDiS;
+
+
+/** \brief
+ * Abstract class that can be passed to RefinementLevel* as indicator where
+ * to refine the mesh up to which level. It is an AbstractFunction that 
+ * overloads the operator() method to return a level or a meshsize depending
+ * on the coords/data passed to the operator.
+ * You can switch between meshsize and level with the methods hToLevel(double) and 
+ * levelToH(int)
+ **/
+template<typename T, typename T2>
+class MeshRefinementFunction : public AbstractFunction<T2, T>
+{
+public:
+
+  MeshRefinementFunction(Mesh* mesh_) :
+    AbstractFunction<T2, T>(0),
+    mesh(mesh_), 
+    globalSize(0)
+  {
+      h0 = getMacroMeshSize(mesh);
+      reduction = 1.0 / sqrt(2.0); // if dim==2
+  }
+
+  int getGlobalSize() { return globalSize; }
+
+  double meshSize() { return h0; }
+
+  virtual T2 operator()(const T &value) const { return globalSize; }
+  
+  virtual double indicator(const T &value) const { return 1.0; }
+
+protected:
+
+  int hToLevel(double h) {
+      int level = static_cast<int>(floor(log(h / h0) / log(reduction)));
+      return level;
+  }
+
+  double levelToH(int level) {
+      double h = pow(reduction,level)*h0;
+      return h;
+  }
+
+  double getMacroMeshSize(Mesh* mesh) {
+      FixVec<WorldVector<double>, VERTEX> coords = mesh->getMacroElement(0)->getCoord();
+      double h = 0.0;
+      for (int i = 0; i < coords.size(); ++i)
+          for (int j = i + 1; j < coords.size(); ++j)
+              h = std::max(h, norm(coords[i]-coords[j]));
+      return h;
+  }
+
+protected:
+
+  Mesh* mesh;
+
+  int globalSize;
+
+  double h0;
+  double reduction;
+};
+
+
+/** \brief
+ * Base class for Refinement structure to perform local anisotropic refinement
+ */
+template<typename T, typename T2>
+class RefinementLevel
+{
+public:
+
+  RefinementLevel(const FiniteElemSpace *feSpace_, MeshRefinementFunction<T,T2>* refineFct_) :
+    feSpace(feSpace_), 
+    refineFct(refineFct_),
+    numRefinements0(15),
+    globalRefined(false)
+  {	
+    mesh = feSpace->getMesh();
+    switch (mesh->getDim()) {
+    case 1:
+      coarseningManager = new CoarseningManager1d();
+      refinementManager = new RefinementManager1d();
+      break;
+    case 2:
+      coarseningManager = new CoarseningManager2d();
+      refinementManager = new RefinementManager2d();
+      break;
+    case 3:
+      coarseningManager = new CoarseningManager3d();
+      refinementManager = new RefinementManager3d();
+      break;
+    default:
+      ERROR_EXIT("invalid dim!\n");
+    }
+
+    numRefinements = numRefinements0;
+  }
+  
+  ~RefinementLevel() {
+    delete coarseningManager;
+    delete refinementManager;
+  }
+
+  void refine(bool onlyRefine= false) 
+  {
+    FUNCNAME("RefinementLevel::refine()");
+
+    if (!globalRefined) {
+      MSG_DBG("nr of global refinements: %d\n", refineFct->getGlobalSize());
+      refinementManager->globalRefine(mesh, refineFct->getGlobalSize());
+      globalRefined = true;
+    }
+    double minH = 0.0, maxH = 1.0;
+    int minLevel = 100, maxLevel = 0;
+    
+    // build mesh for phasefield-function
+    bool meshChanged = true;
+    Flag markFlag;
+    int oldMinLevel = 100, oldMaxLevel = 0, oldNr = 0, oldOldNr = 0;
+    int i = 0;
+    while (meshChanged && i < numRefinements) {
+      markElements(markFlag);
+      meshChanged = refineMesh(markFlag, onlyRefine);
+      
+      calcMeshSizes(minH, maxH, minLevel, maxLevel); 
+      int nr = mesh->getNumberOfVertices();
+      meshChanged = meshChanged && oldOldNr!=nr && oldNr!=nr;
+      if (meshChanged) {
+	MSG_DBG("Mesh sizes: [%f, %f], Vs: %d, ELs: %d\n", 
+          minH, maxH, nr, mesh->getNumberOfElements());
+      }
+      i++;
+			
+      oldMinLevel = minLevel; 
+      oldMaxLevel = maxLevel;
+      oldOldNr = oldNr;
+      oldNr = nr; 
+    }
+    calcMeshSizes(minH, maxH, minLevel, maxLevel); 
+    MSG("Final mesh: [%f, %f], Vs: %d, ELs: %d, Level: [%d, %d]\n",
+      minH, maxH, mesh->getNumberOfVertices(), mesh->getNumberOfElements(), minLevel, maxLevel);
+  }
+
+  void refine(int numRefinements_, bool onlyRefine= false) { 
+    numRefinements = numRefinements_; 
+    refine(onlyRefine);  
+    numRefinements = numRefinements0; 
+  }
+
+  int getNumRefinements(){
+      return numRefinements;
+  }
+
+  void calcMeshSizes(double& minH, double& maxH, int& minLevel, int& maxLevel) 
+  {
+    FUNCNAME("RefinementLevel::calcMeshSizes()");
+
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+    minH = 1e15; maxH = 0.0;
+    int k = 0;
+    minLevel = 100;
+    maxLevel = 0;
+    while (elInfo) {
+      maxLevel = std::max(maxLevel,elInfo->getLevel());
+      minLevel = std::min(minLevel,elInfo->getLevel());
+      coords = elInfo->getCoords();
+      double h = 0.0;
+      for (int i = 0; i < coords.size(); i++) {
+        for (int j = 0; j < coords.size(); j++) {
+	  if (i != j)
+            h = std::max(h,norm(coords[i]-coords[j]));
+        }
+      }
+      minH = std::min(h, minH);
+      maxH = std::max(h, maxH);
+      elInfo = stack.traverseNext(elInfo);
+      k++;
+    }
+    minLevel += mesh->getMacroElementLevel();
+    maxLevel += mesh->getMacroElementLevel();
+  }
+
+
+  double calcMeshSize(ElInfo *elInfo) 
+  {
+    FUNCNAME("RefinementLevel::calcMeshSizes()");
+
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    coords = elInfo->getCoords();
+    double h = 0.0;
+    for (int i = 0; i < coords.size(); i++) {
+      for (int j = 0; j < coords.size(); j++) {
+        if (i != j)
+          h = std::max(h,norm(coords[i]-coords[j]));
+      }
+    }
+
+    return h;
+  }
+
+
+  int calcMark(double refineH, double currentH)
+  {
+    return (refineH < currentH ? 
+        1 : (refineH > currentH * (mesh->getDim() == 1 ? 
+          2.0 : (mesh->getDim() == 2 ? 
+          sqrt(2.0) : 
+          sqrt(2.0)/2.0 + 0.5)) ? 
+        -1 : 
+        0));
+  }
+
+
+  virtual int calcMark(int refineLevel, int currentLevel)
+  {
+    int levelDiff = refineLevel - currentLevel;
+    return (levelDiff > 0 ? 1 : (levelDiff < 0 ? -1 : 0));
+  }
+
+	
+  bool refineMesh(Flag markFlag, bool onlyRefine) 
+  {
+    FUNCNAME("RefinementLevel::refineMesh()");
+
+    int oldSize = mesh->getNumberOfVertices();
+    if (markFlag.isSet(1))
+      refinementManager->refineMesh(mesh);
+    if (markFlag.isSet(2) && !onlyRefine)
+      coarseningManager->coarsenMesh(mesh);
+    if (markFlag.isSet(1) || markFlag.isSet(2)) {
+      int newSize = mesh->getNumberOfVertices();
+      if (oldSize != newSize) 
+        return true;
+    }
+    return false;
+  }
+
+  virtual void markElements(Flag &markFlag) = 0;
+
+  void setGlobalRefined(bool refined) { globalRefined = refined; }
+  RefinementManager* getRefinementManager() { return refinementManager; }
+  CoarseningManager* getCoarseningManager() { return coarseningManager; }
+
+protected:
+
+  const FiniteElemSpace *feSpace;
+  Mesh* mesh;
+  MeshRefinementFunction<T,T2>* refineFct;
+  RefinementManager* refinementManager;
+  CoarseningManager* coarseningManager;
+
+  int numRefinements;
+  int numRefinements0;
+  bool globalRefined;
+};
+
+#include "Refinement_Level.h"
+#include "Refinement_MeshSize.h"
+
+#endif // REFINEMENT_H
diff --git a/extensions/Refinement_DOFView.h b/extensions/Refinement_DOFView.h
new file mode 100644
index 0000000000000000000000000000000000000000..4ccacc702db51624736609f966d8910c40a12805
--- /dev/null
+++ b/extensions/Refinement_DOFView.h
@@ -0,0 +1,487 @@
+/** \file Refinement_DOFView.h */
+
+#ifndef REFINEMENT_DOFVIEW_H
+#define REFINEMENT_DOFVIEW_H
+
+#include "Refinement.h"
+#include "Views.h"
+#include "MeshFunction_Level.h"
+
+using namespace AMDiS;
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * value, like phase-value or distance-value.
+ **/
+class RefinementLevelDOFView : public RefinementLevel<double, int>
+{
+public:  
+    typedef double T;
+    
+public:
+  RefinementLevelDOFView(const FiniteElemSpace *feSpace_, 
+			 MeshRefinementFunction<T, int>* refineFct_, 
+			 DOFView<double> *vec_)
+  : RefinementLevel<T, int>(feSpace_, refineFct_), 
+    vec(vec_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOFView::markElements()");
+
+    T meanValue; nullify(meanValue);
+    WorldVector<double> centroid;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+    
+    int dim = mesh->getDim();
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    MacroElement* foundMacro = new MacroElement(dim);
+    bool found = false;
+    while (elInfo) {
+      centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+      
+      meanValue = evalAtPoint<T>(*vec, centroid);
+
+      int refineLevel = (*refineFct)(meanValue);
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() >= 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() <= -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+  
+private:
+
+  DOFView<double>* vec;
+};
+
+
+
+/** \brief
+ * Specialization of RefinementLevel, that uses an arbitrary container 'data'
+ * that gives the phase-field value or the distance value, or something that 
+ * can be handled by the reine-function.
+ * For the Container a free function evalAtPoint must be implemented, 
+ * e.g. DOFVector, DOFView, AbstractFunction, POD-Type.
+ **/
+template<typename Container>
+class RefinementLevel1 : public RefinementLevel<double, int>
+{
+public:  
+    typedef double T;
+    
+public:
+  RefinementLevel1(const FiniteElemSpace *feSpace_, 
+		   MeshRefinementFunction<T, int>* refineFct_, 
+		   Container &data_)
+  : RefinementLevel<T, int>(feSpace_, refineFct_), 
+    data(data_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOFView::markElements()");
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+    
+    int dim = mesh->getDim();
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+
+    while (elInfo) {
+      WorldVector<double> centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+      
+      typename ValueType<Container>::type meanValue = evalAtPoint<typename ValueType<Container>::type>(data, centroid, elInfo);
+
+      int refineLevel = (*refineFct)(meanValue);
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() >= 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() <= -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+  
+private:
+  Container& data;
+};
+
+
+/** \brief
+ * Specialization of RefinementLevel, that uses two arbitrary containers 'data1', 'data2'
+ * that give the phase-field values or the distance values, or something that 
+ * can be handled by the reine-function.
+ * For the Containers free functions evalAtPoint must be implemented, 
+ * e.g. DOFVector, DOFView, AbstractFunction, POD-Type.
+ **/
+template<typename Container1, typename Container2>
+class RefinementLevel2 : public RefinementLevel<boost::tuple<double, double>, int>
+{
+public:  
+    typedef boost::tuple<double, double> T;
+    
+public:
+  RefinementLevel2(const FiniteElemSpace *feSpace_, 
+		   MeshRefinementFunction<T, int>* refineFct_, 
+		   Container1 &data1_,
+		   Container2 &data2_)
+  : RefinementLevel<T, int>(feSpace_, refineFct_), 
+    data1(data1_),
+    data2(data2_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOFView::markElements()");
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+    
+    int dim = mesh->getDim();
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+
+    while (elInfo) {
+      WorldVector<double> centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+      
+      typename ValueType<Container1>::type meanValue1 = evalAtPoint<typename ValueType<Container1>::type>(data1, centroid, elInfo);
+      typename ValueType<Container1>::type meanValue2 = evalAtPoint<typename ValueType<Container2>::type>(data2, centroid, elInfo);
+
+      int refineLevel = (*refineFct)(boost::tuples::make_tuple(meanValue1, meanValue2));
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() >= 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() <= -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag |= 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+  
+private:
+  Container1& data1;
+  Container2& data2;
+};
+
+
+/** \brief
+ * Specialization of RefinementLevel, that uses two arbitrary containers 'data1', 'data2'
+ * that give the phase-field values or the distance values, or something that 
+ * can be handled by the reine-function.
+ * For the Containers free functions evalAtPoint must be implemented, 
+ * e.g. DOFVector, DOFView, AbstractFunction, POD-Type.
+ **/
+template<typename Container1, typename Container2, typename Container3>
+class RefinementLevel3 : public RefinementLevel<boost::tuple<double, double, double>, int>
+{
+public:  
+    typedef boost::tuple<double, double, double> T;
+    
+public:
+  RefinementLevel3(const FiniteElemSpace *feSpace_, 
+		   MeshRefinementFunction<T, int>* refineFct_, 
+		   Container1 &data1_,
+		   Container2 &data2_,
+		   Container3 &data3_)
+  : RefinementLevel<T, int>(feSpace_, refineFct_), 
+    data1(data1_),
+    data2(data2_),
+    data3(data3_) { };
+
+  void markElements(Flag &markFlag)
+  {
+    FUNCNAME("RefinementLevelDOFView::markElements()");
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+    
+    int dim = mesh->getDim();
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+
+    while (elInfo) {
+      WorldVector<double> centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+      
+      typename ValueType<Container1>::type meanValue1 = evalAtPoint<typename ValueType<Container1>::type>(data1, centroid, elInfo);
+      typename ValueType<Container2>::type meanValue2 = evalAtPoint<typename ValueType<Container2>::type>(data2, centroid, elInfo);
+      typename ValueType<Container3>::type meanValue3 = evalAtPoint<typename ValueType<Container3>::type>(data3, centroid, elInfo);
+
+      int refineLevel = (*refineFct)(boost::tuples::make_tuple(meanValue1, meanValue2, meanValue3));
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() >= 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() <= -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+  
+private:
+  Container1& data1;
+  Container2& data2;
+  Container3& data3;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * list of values, like phase-values or distance-values.
+ **/
+class RefinementLevelDOF2 : public RefinementLevel< boost::tuple<double, double>, int >
+{
+public:  
+    typedef boost::tuple<double, double> value_Type;
+    
+public:
+  RefinementLevelDOF2(
+      const FiniteElemSpace *feSpace_, 
+      MeshRefinementFunction< value_Type, int >* refineFct_, 
+      DOFVector<double>* vec0_, 
+      DOFVector<double>* vec1_)
+  : RefinementLevel< value_Type, int >(feSpace_, refineFct_),
+    vec0(vec0_),
+    vec1(vec1_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOFViewAndDOFVector::markElements()");
+
+    const DOFAdmin* admin = feSpace->getAdmin();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+
+    DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    ElementFunctionDOFVec<double> elFct0(vec0);
+    ElementFunctionDOFVec<double> elFct1(vec1);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i = 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+    int dim = mesh->getDim();
+    Flag traverseFlag = Mesh::CALL_LEAF_EL;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while(elInfo) {
+      // eval DOFVector0
+      elFct0.setElInfo(elInfo);
+      double meanValue0 = elFct0(lambda);
+      
+      // eval DOFVector1
+      elFct1.setElInfo(elInfo);
+      double meanValue1 = elFct1(lambda);
+      
+      int refineLevel = (*refineFct)(boost::tuples::make_tuple(meanValue0, meanValue1));
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+      
+    markFlag= 0;
+    if(elMarkRefine) 
+      markFlag = 1;
+    if(elMarkCoarsen) 
+      markFlag |= 2;
+    
+    delete [] localIndices;
+  };
+  
+  
+private:
+  
+  DOFVector<double>* vec0;
+  DOFVector<double>* vec1;
+};
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * list of values, like phase-values or distance-values.
+ **/
+class RefinementLevelDOFViewAndDOFVector : public RefinementLevel< boost::tuple<double, double>, int >
+{
+public:  
+    typedef boost::tuple<double, double> value_Type;
+    
+public:
+  RefinementLevelDOFViewAndDOFVector(
+      const FiniteElemSpace *feSpace_, 
+      MeshRefinementFunction< value_Type, int >* refineFct_, 
+      DOFView<double>* vec0_, 
+      DOFVector<double>* vec1_)
+  : RefinementLevel< value_Type, int >(feSpace_, refineFct_),
+    vec0(vec0_),
+    vec1(vec1_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOFViewAndDOFVector::markElements()");
+
+    const DOFAdmin* admin = feSpace->getAdmin();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+
+    DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    ElementFunctionDOFVec<double> elFct(vec1);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i = 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+    int dim = mesh->getDim();
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    WorldVector<double> border; border.set(0.0); border[0] = 0.5;
+    while (elInfo) {
+      WorldVector<double> centroid = elInfo->getCoord(0);
+      for (int i = 1; i < dim+1; i++)
+	centroid += elInfo->getCoord(i);
+      centroid *= 1.0/(dim+1.0);
+      
+      // eval DOFView
+      double meanValue0 = evalAtPoint<double>(*vec0, centroid);   
+      // eval DOFVector
+      elFct.setElInfo(elInfo);
+      double meanValue1 = elFct(lambda);
+      
+      int refineLevel = (*refineFct)(boost::tuples::make_tuple(meanValue0, meanValue1));      
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+      
+    markFlag = 0;
+    if(elMarkRefine) 
+      markFlag = 1;
+    if(elMarkCoarsen) 
+      markFlag |= 2;
+    
+    delete [] localIndices;
+  }
+  
+private:
+  
+  DOFView<double>* vec0;
+  DOFVector<double>* vec1;
+};
+
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the regions for interface refinement and domain refinement, etc.
+ **/
+class PhaseField2Refinement : public PhaseFieldRefinementBase<boost::tuple<double, double> >
+{
+public:
+
+    PhaseField2Refinement(Mesh* mesh_) : PhaseFieldRefinementBase<boost::tuple<double, double> >(mesh_) {};
+    
+    int operator()(const boost::tuple<double, double>& phases) const {
+      int result0= lOuter;
+      if (minPhase < phases.get<0>() && phases.get<0>() < maxPhase)
+        result0= lInterface;         // auf dem Interface
+      else if (phases.get<0>() > minOuterPhase && phases.get<0>() <= minPhase)
+        result0= std::max(lOuter, static_cast<int>(floor((lOuter+lInterface)/2.0)));
+      else if (phases.get<0>() < maxOuterPhase && phases.get<0>() >= maxPhase)
+        result0= std::max(lInner, static_cast<int>(floor((lInner+lInterface)/2.0)));
+      else if (phases.get<0>() > (minPhase+maxPhase)/2.0)
+        result0= lInner;
+      
+      int result1= lOuter;
+      if (minPhase < phases.get<1>() && phases.get<1>() < maxPhase)
+        result1= lInterface;         // auf dem Interface
+      else if (phases.get<1>() > minOuterPhase && phases.get<1>() <= minPhase)
+        result1= std::max(lOuter, static_cast<int>(floor((lOuter+lInterface)/2.0)));
+      else if (phases.get<1>() < maxOuterPhase && phases.get<1>() >= maxPhase)
+        result1= std::max(lInner, static_cast<int>(floor((lInner+lInterface)/2.0)));
+      else if (phases.get<1>() > (minPhase+maxPhase)/2.0)
+        result1= lInner;
+      
+      return std::max(result0, result1);
+    }
+};
+
+
+/** \brief
+ * Implementation of PhaseFieldRefinementBase. Provides the method operator()
+ * that defines the regions for interface refinement and domain refinement, etc.
+ **/
+class PhaseField2Refinement_simple : public PhaseFieldRefinementBase<boost::tuple<double, double> >
+{
+public:
+
+    PhaseField2Refinement_simple(Mesh* mesh_) : PhaseFieldRefinementBase<boost::tuple<double, double> >(mesh_) {};
+    
+    int operator()(const boost::tuple<double, double>& phases) const {
+      int result0 = lOuter;
+      if (minPhase < phases.get<0>() && phases.get<0>() < maxPhase)
+        result0 = lInterface;         // auf dem Interface vom Phase 1
+      
+      int result1 = lOuter;
+      if (minPhase < phases.get<1>() && phases.get<1>() < maxPhase)
+        result1 = lInterface;         // auf dem Interface von Phase 2
+      
+      return std::max(result0, result1);
+    }
+};
+
+#endif // REFINEMENT_DOFVIEW_H
diff --git a/extensions/Refinement_Level.h b/extensions/Refinement_Level.h
new file mode 100644
index 0000000000000000000000000000000000000000..e1e5e608edaba05c0777aefe33d0ff18d3c9e15b
--- /dev/null
+++ b/extensions/Refinement_Level.h
@@ -0,0 +1,413 @@
+/** \file Refinement_Level.h */
+
+#ifndef REFINEMENT_LEVEL_PHASEFIELD_H
+#define REFINEMENT_LEVEL_PHASEFIELD_H
+
+#include "ElementFunction.h"
+
+using namespace AMDiS;
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to given
+ * coordinates.
+ **/
+class RefinementLevelCoords : public RefinementLevel<WorldVector<double>, int >
+{
+public:
+  RefinementLevelCoords(const FiniteElemSpace *feSpace_, MeshRefinementFunction<WorldVector<double>, int >* refineFct_) :
+    RefinementLevel<WorldVector<double>, int >(feSpace_, refineFct_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelCoords::markElements()");
+
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    WorldVector<double> center;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      coords = elInfo->getCoords();
+      center.set(0.0);
+      for (int i = 0; i < coords.size(); ++i) {
+	center += coords[i];
+      }
+      center *= 1.0 / static_cast<double>(coords.size());
+      int refineLevel = (*refineFct)(center);
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+    
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to given
+ * coordinates.
+ **/
+class RefinementLevelCoords2 : public RefinementLevel<double, int >
+{
+public:
+  RefinementLevelCoords2(const FiniteElemSpace *feSpace_, MeshRefinementFunction<double, int >* refineFct_, AbstractFunction<double, WorldVector<double> > *fct_) :
+    RefinementLevel<double, int >(feSpace_, refineFct_), fct(fct_) { };
+
+  void markElements(Flag &markFlag)
+  {
+    FUNCNAME("RefinementLevelCoords::markElements()");
+
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    WorldVector<double> center;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      coords = elInfo->getCoords();
+      center.set(0.0);
+      for (int i = 0; i < coords.size(); ++i) {
+	center += coords[i];
+      }
+      center *= 1.0 / static_cast<double>(coords.size());
+      double value = (*fct)(center);
+      int refineLevel = (*refineFct)(value);
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+
+    markFlag = 0;
+    if (elMarkRefine)
+      markFlag = 1;
+    if (elMarkCoarsen)
+      markFlag |= 2;
+  };
+
+private:
+  AbstractFunction<double, WorldVector<double> > *fct;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * value, like phase-value or distance-value.
+ **/
+class RefinementLevelDOF : public RefinementLevel<double, int>
+{
+public:
+  RefinementLevelDOF(const FiniteElemSpace *feSpace_, MeshRefinementFunction<double, int>* refineFct_, DOFVector<double> *vec_) :
+    RefinementLevel<double, int>(feSpace_, refineFct_), 
+    vec(vec_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOF::markElements()");
+
+    double meanValue;
+
+    ElementFunctionDOFVec<double> elFct(vec);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i = 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      elFct.setElInfo(elInfo);
+      meanValue = elFct(lambda);
+
+      int refineLevel = (*refineFct)(meanValue);
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+
+private:
+
+  DOFVector<double>* vec;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * value, like phase-value or distance-value, and the center coords of the
+ * element.
+ **/
+class RefinementLevelCoordsDOF : public RefinementLevel<std::pair<WorldVector<double>, double>, int >
+{
+public:
+
+  RefinementLevelCoordsDOF(const FiniteElemSpace *feSpace_, MeshRefinementFunction<std::pair<WorldVector<double>, double>, int >* refineFct_, DOFVector<double> *vec_) :
+    RefinementLevel<std::pair<WorldVector<double>, double>, int >(feSpace_, refineFct_), vec(vec_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelCoordsDOF::markElements()");
+
+    double meanValue;
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    WorldVector<double> center;
+
+    ElementFunctionDOFVec<double> elFct(vec);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i= 0; i<lambda.getSize(); ++i)
+      lambda[i]= 1.0/lambda.getSize();
+
+    bool elMarkRefine= false, elMarkCoarsen= false;
+
+    Flag traverseFlag= Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo= stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      elFct.setElInfo(elInfo);
+      meanValue = elFct(lambda);
+      coords = elInfo->getCoords();
+      center.set(0.0);
+      for (int i = 0; i < coords.size(); ++i) {
+        center += coords[i];
+      }
+      center *= 1.0 / static_cast<double>(coords.size());
+
+      int refineLevel = (*refineFct)(std::make_pair<WorldVector<double>, double>(center, meanValue));
+      int oldLevel = elInfo->getLevel();
+      elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+                
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+
+private:
+
+  DOFVector<double>* vec;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * list of values, like phase-values or distance-values.
+ **/
+class RefinementLevelDOFList : public RefinementLevel< std::vector<double>, int >
+{
+public:
+  RefinementLevelDOFList(
+      const FiniteElemSpace *feSpace_, 
+      MeshRefinementFunction< std::vector<double>, int >* refineFct_, 
+      DOFVector<double>* vec1_, 
+      DOFVector<double>* vec2_ = NULL,
+      DOFVector<double>* vec3_ = NULL) : 
+    RefinementLevel< std::vector<double>, int >(feSpace_, refineFct_)
+  {
+    vecs.push_back(vec1_);
+    if(vec2_ != NULL) vecs.push_back(vec2_);
+    if(vec3_ != NULL) vecs.push_back(vec3_);			
+  };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOF::markElements()");
+
+    const DOFAdmin* admin = feSpace->getAdmin();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+
+    DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    double meanValue;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    std::vector<ElementFunctionDOFVec<double>*> elFcts;
+    for (unsigned i = 0; i < vecs.size(); ++i) {
+      elFcts.push_back(new ElementFunctionDOFVec<double>(vecs[i]));
+    }
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i= 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+      Flag traverseFlag = Mesh::CALL_LEAF_EL;
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+      while(elInfo) {
+	std::vector<double> meanValues;
+	for (unsigned v = 0; v < vecs.size(); ++v) {
+          elFcts[v]->setElInfo(elInfo);
+	  meanValues.push_back( (*(elFcts[v]))(lambda) );
+	}
+	
+        int refineLevel = (*refineFct)(meanValues);
+        int oldLevel = elInfo->getLevel();
+        elInfo->getElement()->setMark( calcMark(refineLevel, oldLevel) );
+
+	elMarkRefine |= elInfo->getElement()->getMark() == 1;
+	elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+	elInfo = stack.traverseNext(elInfo);
+    }
+      
+    markFlag= 0;
+    if(elMarkRefine) 
+	    markFlag= 1;
+    if(elMarkCoarsen) 
+	    markFlag|= 2;
+    
+    delete [] localIndices;
+  };
+private:
+	std::vector<DOFVector<double>*> vecs;
+};
+
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * list of values, like phase-values or distance-values.
+ **/
+class RefinementLevelES : public RefinementLevel< std::vector<double>, int >
+{
+public:
+  RefinementLevelES(
+      const FiniteElemSpace *feSpace_, 
+      MeshRefinementFunction< std::vector<double>, int >* refineFct_, 
+      DOFVector<double>* vec1_, 
+      DOFVector<double>* vec2_, 
+      DOFVector<double>* phase_,
+      double tol_) : 
+    RefinementLevel< std::vector<double>, int >(feSpace_, refineFct_),
+    phase(phase_),
+    tol(tol_)
+  {
+    vecs.push_back(vec1_);
+    vecs.push_back(vec2_);
+  };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOF::markElements()");
+
+    const DOFAdmin* admin = feSpace->getAdmin();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+
+    DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    double meanValue;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    std::vector<ElementFunctionDOFVec<double>*> elFcts;
+    for (unsigned i = 0; i < vecs.size(); ++i) {
+      elFcts.push_back(new ElementFunctionDOFVec<double>(vecs[i]));
+    }
+    ElementFunctionDOFVec<double>* elFct_phase = new ElementFunctionDOFVec<double>(phase);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i= 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+
+//     int n = 0;
+//     double mean = 0.0;
+//     while(elInfo) {
+//       elFct_phase->setElInfo(elInfo);
+//       if ((*elFct_phase)(lambda) > 0.001) {
+//         std::vector<double> meanValues;
+//         meanValues.push_back(0.0);
+//         for (unsigned v = 0; v < vecs.size(); ++v) {
+//           elFcts[v]->setElInfo(elInfo);
+//           meanValues.push_back( (*(elFcts[v]))(lambda) );
+//         }
+//         
+//         double value = refineFct->indicator(meanValues);
+//         mean += value;
+//         n++;
+//       }
+//       elInfo = stack.traverseNext(elInfo);
+//     }
+//     mean /= n;
+//     MSG("mean value = %e\n", mean);
+
+    elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    int nCoarse = 0;
+    while(elInfo) {
+      elFct_phase->setElInfo(elInfo);
+      if ((*elFct_phase)(lambda) > 0.0001) {
+        std::vector<double> meanValues;
+        meanValues.push_back(tol);
+        for (unsigned v = 0; v < vecs.size(); ++v) {
+          elFcts[v]->setElInfo(elInfo);
+          meanValues.push_back( (*(elFcts[v]))(lambda) );
+        }
+        
+        int refineLevel = (*refineFct)(meanValues);
+        nCoarse += refineLevel;
+        elInfo->getElement()->setMark( refineLevel );
+      } else {
+        elInfo->getElement()->setMark( -1 );
+      }
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+    MSG("number of elements marked for coarsening: %d\n", abs(nCoarse));
+      
+    markFlag= 0;
+    if(elMarkRefine) 
+            markFlag= 1;
+    if(elMarkCoarsen) 
+            markFlag|= 2;
+    
+    delete [] localIndices;
+  };
+private:
+        std::vector<DOFVector<double>*> vecs;
+        DOFVector<double>* phase;
+        double tol;
+};
+#endif // REFINEMENT_LEVEL_PHASEFIELD_H
+
diff --git a/extensions/Refinement_MeshSize.h b/extensions/Refinement_MeshSize.h
new file mode 100644
index 0000000000000000000000000000000000000000..1348e59adcdd502b287da00e0663ddfee91afa66
--- /dev/null
+++ b/extensions/Refinement_MeshSize.h
@@ -0,0 +1,251 @@
+/** \file Refinement_MeshSize.h */
+
+#ifndef REFINEMENT_MESHSIZE_H
+#define REFINEMENT_MESHSIZE_H
+
+using namespace AMDiS;
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to given
+ * coordinates.
+ **/
+class RefinementMeshSizeCoords : public RefinementLevel<WorldVector<double>, double >
+{
+public:
+  RefinementMeshSizeCoords(FiniteElemSpace *feSpace_, MeshRefinementFunction<WorldVector<double>, double >* refineFct_) :
+    RefinementLevel<WorldVector<double>, double >(feSpace_, refineFct_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelCoords::markElements()");
+
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    WorldVector<double> center;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      coords = elInfo->getCoords();
+      center.set(0.0);
+      for (int i = 0; i < coords.size(); ++i) {
+	center += coords[i];
+      }
+      center *= 1.0 / static_cast<double>(coords.size());
+
+      double refineH = (*refineFct)(center);
+      double oldH = calcMeshSize(elInfo);
+      elInfo->getElement()->setMark( calcMark(refineH, oldH) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+    
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * value, like phase-value or distance-value.
+ **/
+class RefinementMeshSizeDOF : public RefinementLevel<double, double>
+{
+public:
+  RefinementMeshSizeDOF(FiniteElemSpace *feSpace_, MeshRefinementFunction<double, double>* refineFct_, DOFVector<double> *vec_) :
+    RefinementLevel<double, double>(feSpace_, refineFct_), 
+    vec(vec_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOF::markElements()");
+
+    double meanValue;
+
+    ElementFunctionDOFVec<double> elFct(vec);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i = 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    Flag traverseFlag = Mesh::CALL_LEAF_EL;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      elFct.setElInfo(elInfo);
+      meanValue = elFct(lambda);
+
+      double refineH = (*refineFct)(meanValue);
+      double oldH = calcMeshSize(elInfo);
+      elInfo->getElement()->setMark( calcMark(refineH, oldH) );
+
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+		
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+
+private:
+
+  DOFVector<double>* vec;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * value, like phase-value or distance-value, and the center coords of the
+ * element.
+ **/
+class RefinementMeshSizeCoordsDOF : public RefinementLevel<std::pair<WorldVector<double>, double>, double >
+{
+public:
+
+  RefinementMeshSizeCoordsDOF(FiniteElemSpace *feSpace_, MeshRefinementFunction<std::pair<WorldVector<double>, double>, double >* refineFct_, DOFVector<double> *vec_) :
+    RefinementLevel<std::pair<WorldVector<double>, double>, double >(feSpace_, refineFct_), vec(vec_) { };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelCoordsDOF::markElements()");
+
+    double meanValue;
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    WorldVector<double> center;
+
+    ElementFunctionDOFVec<double> elFct(vec);
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i= 0; i<lambda.getSize(); ++i)
+      lambda[i]= 1.0/lambda.getSize();
+
+    bool elMarkRefine= false, elMarkCoarsen= false;
+
+    Flag traverseFlag= Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    TraverseStack stack;
+    ElInfo *elInfo= stack.traverseFirst(mesh, -1, traverseFlag);
+    while (elInfo) {
+      elFct.setElInfo(elInfo);
+      meanValue = elFct(lambda);
+      coords = elInfo->getCoords();
+      center.set(0.0);
+      for (int i = 0; i < coords.size(); ++i) {
+        center += coords[i];
+      }
+      center *= 1.0 / static_cast<double>(coords.size());
+
+      double refineH = (*refineFct)(std::make_pair<WorldVector<double>, double>(center, meanValue));
+      double oldH = calcMeshSize(elInfo);
+      elInfo->getElement()->setMark( calcMark(refineH, oldH) );
+
+      elMarkRefine |= elInfo->getElement()->getMark() == 1;
+      elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+      elInfo = stack.traverseNext(elInfo);
+    }
+                
+    markFlag = 0;
+    if (elMarkRefine) 
+      markFlag = 1;
+    if (elMarkCoarsen) 
+      markFlag |= 2;
+  };
+
+private:
+
+  DOFVector<double>* vec;
+};
+
+
+/** \brief
+ * Refinement structure to perform local anisotropic refinement depending
+ * on a refineFunction that defines the local refinement level to a given
+ * list of values, like phase-values or distance-values.
+ **/
+class RefinementMeshSizeDOFList : public RefinementLevel< std::vector<double>, double >
+{
+public:
+  RefinementMeshSizeDOFList(
+      FiniteElemSpace *feSpace_, 
+      MeshRefinementFunction< std::vector<double>, double >* refineFct_, 
+      DOFVector<double>* vec1_, 
+      DOFVector<double>* vec2_ = NULL,
+      DOFVector<double>* vec3_ = NULL) : 
+    RefinementLevel< std::vector<double>, double >(feSpace_, refineFct_)
+  {
+    vecs.push_back(vec1_);
+    if(vec2_ != NULL) vecs.push_back(vec2_);
+    if(vec3_ != NULL) vecs.push_back(vec3_);			
+  };
+
+  void markElements(Flag &markFlag) 
+  {
+    FUNCNAME("RefinementLevelDOF::markElements()");
+
+    const DOFAdmin* admin = feSpace->getAdmin();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+
+    DegreeOfFreedom *localIndices = new DegreeOfFreedom[numBasFcts];
+    FixVec<WorldVector<double>, VERTEX> coords(mesh->getDim(), NO_INIT);
+    double meanValue;
+
+    bool elMarkRefine = false, elMarkCoarsen = false;
+
+    std::vector<ElementFunctionDOFVec<double>*> elFcts;
+    for (unsigned i = 0; i < vecs.size(); ++i) {
+      elFcts.push_back(new ElementFunctionDOFVec<double>(vecs[i]));
+    }
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    for (int i= 0; i < lambda.getSize(); ++i)
+      lambda[i] = 1.0 / lambda.getSize();
+
+      Flag traverseFlag = Mesh::CALL_LEAF_EL;
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(mesh, -1, traverseFlag);
+      while(elInfo) {
+	std::vector<double> meanValues;
+	for (unsigned v = 0; v < vecs.size(); ++v) {
+          elFcts[v]->setElInfo(elInfo);
+	  meanValues.push_back( (*(elFcts[v]))(lambda) );
+	}
+	
+        double refineH = (*refineFct)(meanValues);
+        double oldH = calcMeshSize(elInfo);
+        elInfo->getElement()->setMark( calcMark(refineH, oldH) );
+
+	elMarkRefine |= elInfo->getElement()->getMark() == 1;
+	elMarkCoarsen |= elInfo->getElement()->getMark() == -1;
+	elInfo = stack.traverseNext(elInfo);
+    }
+      
+    markFlag= 0;
+    if(elMarkRefine) 
+	    markFlag= 1;
+    if(elMarkCoarsen) 
+	    markFlag|= 2;
+    
+    delete [] localIndices;
+  };
+private:
+	std::vector<DOFVector<double>*> vecs;
+};
+
+
+#endif // REFINEMENT_MESHSIZE_H
+
diff --git a/extensions/SignedDistFunctors.h b/extensions/SignedDistFunctors.h
new file mode 100644
index 0000000000000000000000000000000000000000..09d0a376e207d37c0910b90ef553bfd5a9570a3c
--- /dev/null
+++ b/extensions/SignedDistFunctors.h
@@ -0,0 +1,608 @@
+/** \file SignedDistFunctors.h */
+
+#ifndef SIGNED_DIST_FUNCTORS_H
+#define SIGNED_DIST_FUNCTORS_H
+
+#include "VectorOperations.h"
+#include "GeometryTools.h"
+
+using namespace std;
+using namespace AMDiS; 
+using namespace vector_operations;
+
+/**
+ * A collection of signed-dist function describing several gemoetric objects:
+ *   - Circle(radius [, center])
+ *   - PerturbedCircle(radius [, center])
+ *   - TwoCircles(radius, center1, center2)
+ *   - InverseCircle(radius [, center])
+ *   - InverseCircles(radius, vector(centers))
+ *   - Rectangle(width, height [, center])
+ *   - Ellipse(a,b [, center])
+ *   - Lemniskate(width, center)
+ *   - Plane(shift)
+ *   - PlaneRotation(shift, angle)
+ *   - Propeller(radius, angle)
+ *   - Torus(radius1, radius2)
+ *   - Polygon(v0, v1, v2, v2), or Polygon(vec(v_i))
+ **/
+
+// signed distance functions for surfaces in polar coords
+static double signedDist2D(const WorldVector<double> x, const WorldVector<double> midPoint, 
+			     AbstractFunction<double, double> *radius, double eps)
+{
+  FUNCNAME("signedDist2D");
+  WorldVector<double> x_trans;
+  double norm_xy;
+  double alpha;
+
+  TEST_EXIT(x.getSize() == 2)("Dimension of world must be 2 to use signedDist2D-function. Use signedDist3D instead!");
+
+  x_trans.fill(0.0);
+  for (int k = 0; k < x.getSize(); k++) {
+    x_trans[k] = x[k] - midPoint[k];
+  }
+
+  norm_xy = epsNorm(x_trans, eps);
+  
+  if (x_trans[0] >= 0.0) {
+    alpha = acos(x_trans[0] / norm_xy);
+  } else {
+    alpha = 2.0*M_PI - acos(x_trans[0] / norm_xy);
+  }
+  
+  return (norm_xy - (*radius)(alpha));
+};
+
+static double signedDist3D(const WorldVector<double> x, const WorldVector<double> midPoint, 
+			     BinaryAbstractFunction<double, double, double> *radius, double eps)
+{
+  FUNCNAME("signedDist3D");
+  WorldVector<double> x_trans;
+  double norm_xyz, norm_xy;
+  double alpha, beta;
+  
+  TEST_EXIT(x.getSize() == 3)("Dimension of world must be 3 to use signedDist3D-function. Use signedDist2D instead!");
+  
+  x_trans.fill(0.0);
+  for (int k = 0; k < x.getSize(); k++) {
+    x_trans[k] = x[k] - midPoint[k];
+  }
+
+  norm_xyz = epsNorm(x_trans, eps);
+  norm_xy = sqrt(sqr(x_trans[0]) + sqr(x_trans[1]) + sqr(eps));
+
+  if(x_trans[1]>=0) {
+    alpha = acos(x_trans[0]/norm_xy);
+  } else {
+    alpha = 2.0*M_PI - acos(x_trans[0]/norm_xy);
+  }
+  beta = 0.5*M_PI - atan(x_trans[2]/norm_xy);
+
+  return (norm_xyz - (*radius)(alpha, beta)); 
+};
+
+// radius-functions
+// ================
+
+class CircleRadius : public AbstractFunction<double, double>
+{
+public:
+  CircleRadius(double radius_) : radius(radius_) {};
+  double operator()(const double& alpha) const { return radius; };
+protected:
+  double radius;
+};
+
+class BallRadius : public BinaryAbstractFunction<double, double, double>
+{
+public:
+  BallRadius(double radius_) : radius(radius_) {};
+  double operator()(const double &alpha, const double &beta) const { return radius; };
+protected:
+  double radius;
+};
+
+class PerturbedCircleRadius : public AbstractFunction<double, double>
+{
+public:
+
+  PerturbedCircleRadius(const double radius_, const double strength_, const int period_) : 
+    radius(radius_), strength(strength_), rotation(0.0), period(period_) {};
+  PerturbedCircleRadius(const double radius_, const double strength_, const int period_, const double rotation_) : 
+    radius(radius_), strength(strength_), rotation(rotation_), period(period_) {};
+  double operator()(const double &alpha) const
+  {
+    double result = 1.0 + strength * cos(period * alpha + rotation);
+    result *= radius;
+    return result;
+  };
+
+protected:
+
+  double radius;
+  double strength;
+  double rotation;
+  int period;
+};
+
+class PerturbedBallRadius : public BinaryAbstractFunction<double, double, double>
+{
+public:
+
+  PerturbedBallRadius(const double radius_, const double strength_, const int period_) : 
+    radius(radius_), strength(strength_), period(period_) {};
+  double operator()(const double &alpha, const double &beta) const
+  {
+    double result = 1.0 + strength * (cos(period*alpha) + cos(period*beta) * cos(period*alpha));
+    result *= radius;
+    return result;
+  };
+
+protected:
+
+  double radius;
+  double strength;
+  int period;
+};
+
+// lemniscate of Bernoulli
+class LemniskateRadius : public AbstractFunction<double, double>
+{
+public:
+
+  LemniskateRadius(const double breite_) : breite(breite_) {};
+  double operator()(const double &alpha) const
+  {
+    double result = 2*cos(2*alpha);
+    result = breite*result;
+    return result;
+  };
+
+protected:
+
+  double breite;
+};
+
+// lemniscate of Bernoulli in 3D
+class Lemniskate3D : public BinaryAbstractFunction<double, double, double>
+{
+public:
+
+  Lemniskate3D(const double breite_) : breite(breite_) {};
+  double operator()(const double &alpha, const double &beta) const
+  {
+    double result = 2*breite*cos(2*alpha)*sin(beta);
+    return result;
+  };
+
+protected:
+
+  double breite;
+};
+
+class EllipseRadius : public AbstractFunction<double, double>
+{
+public:
+
+  EllipseRadius(const double a_, const double b_) : 
+    a(a_), b(b_) {};
+  double operator()(const double &alpha) const
+  {
+    double x=b*cos(alpha), y=a*sin(alpha);
+    return a*b / sqrt(x*x+y*y);
+  };
+
+protected:
+
+  double a,b;
+};
+
+class EllipsoidRadius : public BinaryAbstractFunction<double, double, double>
+{
+public:
+
+  EllipsoidRadius(const double a_, const double b_, const double c_) : 
+    a(a_), b(b_), c(c_) {};
+  double operator()(const double &alpha, const double &beta) const
+  {
+    double sa = sin(alpha), sb = sin(beta);
+    double ca = cos(alpha), cb = cos(beta);
+    double x = a*sa*cb, y = b*sa*sb, z = c*ca;
+    
+    return sqrt(x*x+y*y+z*z);
+  };
+
+protected:
+
+  double a,b,c;
+};
+
+// =============================================================
+
+class PlaneRotation : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  PlaneRotation(double shift_, double theta_, double factor_=1.0) :
+    shift(shift_), theta(theta_), factor(factor_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double x_temp;
+    x_temp= cos(theta)*x[0] - sin(theta)*x[1];
+//     x_temp[1]= sin(theta)*x[0] + cos(theta)*x[1]; 
+    return factor*(shift-x_temp);
+  };
+
+private:
+
+  double shift;
+  int comp;
+  double theta;
+  double factor;
+};
+
+class Plane : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Plane(double shift_, double factor_=1.0) :
+    shift(shift_), factor(factor_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    return factor*(shift-x[1]);
+  };
+
+private:
+
+  double shift;
+  int comp;
+  double factor;
+};
+
+class One : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+  double operator()(const WorldVector<double>& x) const
+  {
+    return 1.0;
+  };
+};
+
+class Rectangle : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Rectangle(double width_, double height_) : width(width_), height(height_) {shift.set(0.0);only2D();}
+  Rectangle(double width_, double height_, WorldVector<double> shift_) : width(width_), height(height_),shift(shift_) {only2D();}
+  double operator()(const WorldVector<double>& x0) const
+  {
+    WorldVector<double> x=x0-shift;
+    double result=0.0;
+    if(abs(x[0])<width/2.0 && abs(x[1])<height/2.0) {
+      result = -std::min(abs(abs(x[0])-width/2.0),abs(abs(x[1])-height/2.0));
+    } else if(abs(x[0])<width/2.0) {
+      result = abs(abs(x[1])-height/2.0);
+    } else if(abs(x[1])<height/2.0) {
+      result = abs(abs(x[0])-width/2.0);
+    } else {
+      WorldVector<double> corner;
+      corner[0] = abs(x[0])-width/2.0;
+      corner[1] = abs(x[1])-height/2.0;
+      result = norm(corner);
+    }
+    return result;
+  };
+  void only2D() { TEST_EXIT(shift.getSize()==2)("Rectangle is defined only for 2 dimension!\n"); }
+
+private:
+
+  double width,height;
+  WorldVector<double> shift;
+};
+
+// simple circle: phi_0(x,y) := sqrt(x^2+y^2)-r
+class Circle : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Circle(double radius_, WorldVector<double> midPoint_, double factor_ = 1.0) :
+    radius(radius_), midPoint(midPoint_), factor(factor_) {}
+  Circle(double radius_, double factor_ = 1.0) :
+    radius(radius_), factor(factor_) { midPoint.set(0.0); }
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result = 0.0;
+
+    for(int k=0; k<x.getSize(); k++) {
+      result += sqr(x[k]-midPoint[k]);
+    }
+    result = sqrt(result)-radius;
+    return factor * result;
+  };
+
+private:
+
+  double radius;
+  WorldVector<double> midPoint;
+  double factor;
+};
+
+class InverseCircle : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  InverseCircle(double radius_, WorldVector<double> midPoint_) :
+    radius(radius_), midPoint(midPoint_) {}
+  InverseCircle(double radius_) :
+    radius(radius_) { midPoint.set(0.0); }
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result = 0.0;
+
+    for(int k=0; k<x.getSize(); k++) {
+      result += sqr(x[k]-midPoint[k]);
+    }
+    result = sqrt(result)-radius;
+    return -result;
+  };
+
+private:
+
+  double radius;
+  WorldVector<double> midPoint;
+};
+
+
+class InverseCircles : public AbstractFunction<double, WorldVector<double> >
+{
+public:
+  InverseCircles(double radius_, std::vector<WorldVector<double> > pos_) :
+	  radius(radius_), pos(pos_) {}
+  InverseCircles(double radius_) :
+	  radius(radius_)
+  {
+    WorldVector<double> center; center.set(0.0);
+    pos.push_back(center);
+  }
+
+  double operator()(const WorldVector<double>& x) const
+  {
+	  std::vector<double> result(pos.size(),0.0);
+
+	  for(int k=0; k<x.getSize(); k++) {
+	    for (int j=0; j<pos.size(); j++) {
+	      result[j] += sqr(x[k]-pos[j][k]);
+	    }
+	  }
+	  double minResult = 1.e10;
+	  for (int j=0; j<pos.size(); j++) {
+	    minResult = std::min(minResult, sqrt(result[j])-radius);
+	  }
+	  return -minResult;
+  }
+private:
+  double radius;
+  std::vector<WorldVector<double> > pos;
+};
+
+
+class TwoCircles : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  TwoCircles(double radius_, WorldVector<double> pos1_, WorldVector<double> pos2_) :
+    radius(radius_), pos1(pos1_), pos2(pos2_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result1=0.0, result2=0.0;
+
+    for(int k=0; k<x.getSize(); k++) {
+      result1 += sqr(x[k]-pos1[k]);
+      result2 += sqr(x[k]-pos2[k]);
+    }
+    result1 = sqrt(result1)-radius;
+    result2 = sqrt(result2)-radius;
+    return -std::min(result1,result2);
+  };
+
+private:
+
+  double radius;
+  WorldVector<double> pos1,pos2;
+};
+
+// perturbed circle
+class PertCircle : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  PertCircle(double radius_, double strength_, int period_) : 
+    radius(radius_), strength(strength_), period(period_) { midPoint.set(0.0); }
+  PertCircle(double radius_, double strength_, int period_, WorldVector<double> midPoint_) : 
+    radius(radius_), strength(strength_), period(period_), midPoint(midPoint_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result=0.0;
+    if(x.getSize()==2) {
+      PerturbedCircleRadius perturbedCircle(radius, strength, period);
+      result = signedDist2D(x, midPoint, &perturbedCircle, 1.e-6);
+    } else {
+      PerturbedBallRadius perturbedBall(radius, strength, period);
+      result = signedDist3D(x, midPoint, &perturbedBall, 1.e-6);
+    }
+    return result;
+  };
+
+private:
+
+  double radius;
+  double strength;
+  int period;
+  WorldVector<double> midPoint;
+};
+
+class Propeller : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Propeller(double radius_, double rotation_) : 
+    radius(radius_), rotation(rotation_) { midPoint.set(0.0); }
+  Propeller(WorldVector<double> midPoint_, double radius_, double rotation_) : 
+    radius(radius_), rotation(rotation_),midPoint(midPoint_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result=0.0;
+    PerturbedCircleRadius perturbedCircle(radius, 1.0, 3, rotation);
+    result = signedDist2D(x, midPoint, &perturbedCircle, 1.e-6);
+    return -result;
+  };
+
+private:
+
+  double radius;
+  double rotation;
+  WorldVector<double> midPoint;
+};
+
+class Lemniskate : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Lemniskate(double breite_, WorldVector<double> midPoint_) : 
+    breite(breite_), midPoint(midPoint_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result=0.0;
+    if(x.getSize()==2) {
+      LemniskateRadius lemniskate(breite);
+      result = signedDist2D(x, midPoint, &lemniskate, 1.e-6);
+    } else {
+      Lemniskate3D lemniskate(breite);
+      result = signedDist3D(x, midPoint, &lemniskate, 1.e-6);
+    }
+    return result;
+  };
+
+private:
+
+  double breite;
+  WorldVector<double> midPoint;
+};
+
+class Ellipse : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Ellipse(double a_, double b_) :
+    a(a_), b(b_), c(0.0) { midPoint.set(0.0); }
+  Ellipse(double a_, double b_, WorldVector<double> midPoint_) :
+    a(a_), b(b_), c(0.0), midPoint(midPoint_) {}
+  Ellipse(double a_, double b_, double c_) :
+    a(a_), b(b_), c(c_) { midPoint.set(0.0); }
+  Ellipse(double a_, double b_, double c_, WorldVector<double> midPoint_) :
+    a(a_), b(b_), c(c_), midPoint(midPoint_) {}
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result = sqr(x[0]-midPoint[0])/sqr(a);
+    result+= sqr(x[1]-midPoint[1])/sqr(b);
+    if(x.getSize()>2) {
+      result+= sqr(x[2]-midPoint[2])/sqr(c);
+    }
+    result = 1.0-sqrt(result);
+    return result;
+  };
+
+private:
+
+  double a,b,c;
+  WorldVector<double> midPoint;
+};
+
+class Torus : public AbstractFunction<double, WorldVector<double> > 
+{
+public:
+
+  Torus(double r1_, double r2_) :
+    r1(r1_), r2(r2_) { midPoint.set(0.0); only3D(); }
+  Torus(double r1_, double r2_, WorldVector<double> midPoint_) :
+    r1(r1_), r2(r2_), midPoint(midPoint_) { only3D(); }
+  void only3D() { TEST_EXIT(midPoint.getSize()==3)("Torus is defined in 3D only!\n"); }
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result=0.0;
+    result = sqr(x[0]-midPoint[0])+sqr(x[1]-midPoint[1]);
+    result = sqr(sqrt(result)-r1)+ sqr(x[2]-midPoint[2]);
+    result = sqrt(result)-r2;
+    
+    return result;
+  };
+
+private:
+
+  double r1,r2;
+  WorldVector<double> midPoint;
+};
+
+
+class Polygon : public AbstractFunction<double, WorldVector<double> >
+{
+public:
+
+  Polygon(WorldVector<double> x0_, WorldVector<double> x1_, WorldVector<double> x2_, WorldVector<double> x3_, double factor_=1.0) : factor(factor_)
+  {
+    vertices.push_back(x0_);
+    vertices.push_back(x1_);
+    vertices.push_back(x2_);
+    vertices.push_back(x3_);
+    vertices.push_back(x0_);
+  }
+
+  Polygon(std::vector<WorldVector<double> > xi_, double factor_=1.0) : vertices(xi_), factor(factor_) { }
+
+  double operator()(const WorldVector<double>& x) const
+  {
+    double result = 1.e15;
+    for (size_t i = 0; i < vertices.size()-1; i++)
+      result = std::min(result, meshconv::distance_point_line_2d(x.begin(), vertices[i].begin(), vertices[i+1].begin()));
+    return factor * result * (meshconv::point_in_polygon(x.begin(), vertices) ? -1.0 : 1.0);
+  }
+
+  void refine(int np)
+  {
+    std::vector<WorldVector<double> > newVertices;
+
+    for (size_t i = 0; i < vertices.size()-1; i++) {
+      for (size_t j = 0; j < np-1; j++) {
+	double lambda = static_cast<double>(j)/static_cast<double>(np - 1.0);
+	WorldVector<double> p = lambda*vertices[i+1] + (1.0-lambda)*vertices[i];
+	newVertices.push_back(p);
+      }
+    }
+    swap(vertices, newVertices);
+  }
+
+  void move(const DOFVector<WorldVector<double> >* velocity)
+  {
+    for (size_t i = 0; i < vertices.size()-1; i++) {
+      WorldVector<double> shift = evalAtPoint(*velocity, vertices[i]);
+      vertices[i] += shift;
+    }
+    vertices[vertices.size()-1] = vertices[0];
+  }
+
+  void move(AbstractFunction<WorldVector<double>, WorldVector<double> >* velocity)
+  {
+    for (size_t i = 0; i < vertices.size()-1; i++) {
+      WorldVector<double> shift = (*velocity)(vertices[i]);
+      vertices[i] += shift;
+    }
+    vertices[vertices.size()-1] = vertices[0];
+  }
+
+private:
+  std::vector<WorldVector<double> > vertices;
+  double factor;
+};
+
+#endif // SIGNED_DIST_FUNCTORS_H
diff --git a/extensions/SingularDirichletBC.h b/extensions/SingularDirichletBC.h
new file mode 100644
index 0000000000000000000000000000000000000000..da686272a221e3aed03269ff881df7b42c16ea0c
--- /dev/null
+++ b/extensions/SingularDirichletBC.h
@@ -0,0 +1,501 @@
+/** \file SingularDirichletBC.h */
+
+#ifndef SINGULAR_DIRICHLET_BC_H
+#define SINGULAR_DIRICHLET_BC_H
+
+#include "AMDiS.h"
+
+namespace AMDiS {
+
+/**
+ * data structure that holds DOF-Index and double value for singular dirichlet boundary condition.
+ **/
+struct SingularDirichletBC {
+  SingularDirichletBC(int i_, int j_, DegreeOfFreedom idx_, double value_) :
+    row(i_), col(j_), idx(idx_), value(value_) {}
+
+  int row, col;
+  DegreeOfFreedom idx;
+  double value;
+};
+
+/**
+ * data structure that holds all periodic associations.
+ **/
+struct ManualPeriodicBC {
+  ManualPeriodicBC(size_t row_, std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &indices_) :
+    row(row_), indices(indices_) {}
+
+  size_t row;
+  std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > indices;
+};
+
+namespace details {
+    
+  /**
+   * traverses the mesh and stores all DegreeOfFreedom, that lie on the boundary with index 'nr'
+   * and have coordinates that give true in the 'meshIndicator', into a vector of 'indices'.
+   **/
+  inline void getBoundaryIndices(const FiniteElemSpace* feSpace,
+			  BoundaryType nr,
+			  AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			  std::vector<DegreeOfFreedom> &indices)
+  {
+    Mesh* mesh = feSpace->getMesh();
+    int dim = mesh->getDim();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+    std::vector<DegreeOfFreedom> localIndices(numBasFcts);
+
+    indices.clear();
+
+    WorldVector<double> coord;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1,
+      Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
+    while (elInfo) {
+      for (int face = 0; face < dim + 1; face++) {
+	if (elInfo->getBoundary(face) == nr) {
+	  basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices);
+
+	  for (int i = 0; i < numBasFcts; i++) {
+	    elInfo->coordToWorld(*(basFcts->getCoords(i)), coord);
+	    if ((*meshIndicator)(coord))
+	      indices.push_back(localIndices[i]);
+	  }
+	  break;
+	}
+      }
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+  }
+
+  /**
+   * traverses the mesh and stores all DegreeOfFreedom, that have coordinates that give true
+   * in the 'meshIndicator', into a vector of 'indices'.
+   **/
+  inline void getBoundaryIndices(const FiniteElemSpace* feSpace,
+			  AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			  std::vector<DegreeOfFreedom> &indices)
+  {
+    Mesh* mesh = feSpace->getMesh();
+    int dim = mesh->getDim();
+    const BasisFunction *basFcts = feSpace->getBasisFcts();
+    int numBasFcts = basFcts->getNumber();
+    std::vector<DegreeOfFreedom> localIndices(numBasFcts);
+
+    indices.clear();
+
+    WorldVector<double> coord;
+    TraverseStack stack;
+    ElInfo *elInfo = stack.traverseFirst(mesh, -1,
+      Mesh::CALL_LEAF_EL | Mesh::FILL_BOUND | Mesh::FILL_COORDS);
+    while (elInfo) {
+      for (int face = 0; face < dim + 1; face++) {
+	if (elInfo->getBoundary(face) != 0) {
+	  basFcts->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices);
+
+	  for (int i = 0; i < numBasFcts; i++) {
+	    elInfo->coordToWorld(*(basFcts->getCoords(i)), coord);
+	    if ((*meshIndicator)(coord))
+	      indices.push_back(localIndices[i]);
+	  }
+	  break;
+	}
+      }
+
+      elInfo = stack.traverseNext(elInfo);
+    }
+  }
+
+  inline void getImplicitIndices(const FiniteElemSpace* feSpace,
+			  AbstractFunction<double, WorldVector<double> >* signedDistFct,
+			  std::vector<DegreeOfFreedom> &indices)
+  {
+    const BasisFunction *vecBasisFcts = feSpace->getBasisFcts();
+    int nVecBasisFcts = vecBasisFcts->getNumber();
+
+    std::vector<DegreeOfFreedom> vecLocalIndices(nVecBasisFcts);
+    
+    DOFVector<short int> visited(feSpace, "visited"); visited.set(0);
+    WorldVector<double> coord;
+    TraverseStack stack;
+    Flag traverseFlag = Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS;
+    ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag);
+
+    while (elInfo) {
+      Element *el = elInfo->getElement();
+      vecBasisFcts->getLocalIndices(el, feSpace->getAdmin(), vecLocalIndices);
+
+      for (int i = 0; i < nVecBasisFcts; i++) {
+	if ( visited[vecLocalIndices[i]] == 0 ) {
+	  elInfo->coordToWorld(*(vecBasisFcts->getCoords(i)), coord);
+	  if ( (*signedDistFct)(coord) <= DBL_TOL ) { // eventuell nur Koordinaten an Gitterknoten bekommen!
+	    indices.push_back(vecLocalIndices[i]);
+	  }
+	  visited[vecLocalIndices[i]] = 1;
+	}
+      }
+      elInfo = stack.traverseNext(elInfo); 
+    }
+  }
+  
+  inline void getImplicitIndices(const FiniteElemSpace* feSpace,
+			  DOFVector<double>* signedDistDOF,
+			  std::vector<DegreeOfFreedom> &indices)
+  {
+   
+    const BasisFunction *vecBasisFcts = feSpace->getBasisFcts();
+    int nVecBasisFcts = vecBasisFcts->getNumber();
+
+    std::vector<DegreeOfFreedom> vecLocalIndices(nVecBasisFcts);
+    ElementVector signedDistLocalCoeffs(nVecBasisFcts);
+
+    DimVec<double> *baryCoords = NULL;
+    DOFVector<short int> visited(feSpace, "visited"); visited.set(0);
+    TraverseStack stack;
+    Flag traverseFlag = Mesh::CALL_LEAF_EL;
+    ElInfo *elInfo = stack.traverseFirst(feSpace->getMesh(), -1, traverseFlag);
+
+    while (elInfo) {
+      Element *el = elInfo->getElement();
+
+      vecBasisFcts->getLocalIndices(el, feSpace->getAdmin(), vecLocalIndices);
+      signedDistDOF->getLocalVector(el, signedDistLocalCoeffs);
+
+      for (int i = 0; i < nVecBasisFcts; i++) {
+	if ( visited[vecLocalIndices[i]] == 0 ) {
+	  baryCoords = vecBasisFcts->getCoords(i);
+
+	  double dist = vecBasisFcts->evalUh(*baryCoords, signedDistLocalCoeffs);
+	  if (dist <= DBL_TOL) {
+	    indices.push_back(vecLocalIndices[i]);
+	  }
+	  visited[vecLocalIndices[i]] = 1;
+	}
+      }
+      elInfo = stack.traverseNext(elInfo); 
+    }
+  }
+  
+  /**
+   * get al list of pairs that describes wich DegreeOfFreedom are assiciated in the given mesh
+   * with given feSpace. Uses the function getBoundaryIndices().
+   * The 'nr' and 'meshIndicator' describe one boundary of the mesh and to each DegreeOfFreedom
+   * the 'periodicMap' associates a second DegreeOfFreedom.
+   **/
+  inline void getPeriodicAssociation(const FiniteElemSpace* feSpace,
+			      BoundaryType nr,
+			      AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			      AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap,
+			      std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &association)
+  {
+    std::vector<DegreeOfFreedom> indices;
+    details::getBoundaryIndices(feSpace, nr, meshIndicator, indices);
+
+    association.clear();
+
+    DOFVector<WorldVector<double> > coords(feSpace, "coords");
+    feSpace->getMesh()->getDofIndexCoords(feSpace, coords);
+    for (size_t i = 0; i < indices.size(); i++)
+    {
+      DegreeOfFreedom idx2;
+      WorldVector<double> p;
+      p = (*periodicMap)(coords[indices[i]]);
+      TEST_EXIT(coords.getDofIdxAtPoint(p,idx2))("periodic association not found!\n");
+
+      association.push_back(std::make_pair(indices[i], idx2));
+    }
+  }
+
+  /**
+   * get al list of pairs that describes wich DegreeOfFreedom are assiciated in the given mesh
+   * with given feSpace. Uses the function getBoundaryIndices().
+   * The 'meshIndicator' describes one boundary of the mesh and to each DegreeOfFreedom
+   * the 'periodicMap' associates a second DegreeOfFreedom.
+   **/
+  inline void getPeriodicAssociation(const FiniteElemSpace* feSpace,
+			      AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			      AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap,
+			      std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > &association)
+  {
+    std::vector<DegreeOfFreedom> indices;
+    details::getBoundaryIndices(feSpace, meshIndicator, indices);
+
+    association.clear();
+
+    DOFVector<WorldVector<double> > coords(feSpace, "coords");
+    feSpace->getMesh()->getDofIndexCoords(feSpace, coords);
+    for (size_t i = 0; i < indices.size(); i++)
+    {
+      DegreeOfFreedom idx2;
+      WorldVector<double> p;
+      p = (*periodicMap)(coords[indices[i]]);
+      TEST_EXIT(coords.getDofIdxAtPoint(p,idx2))("periodic association not found!\n");
+
+      association.push_back(std::make_pair(indices[i], idx2));
+    }
+  }
+  
+  inline void getDOFValues(const FiniteElemSpace* feSpace, AbstractFunction<double, WorldVector<double> >* values, std::vector<DegreeOfFreedom> &indices, std::vector<double> &dofValues)
+  {
+    WorldVector<double> x;
+    for (size_t i = 0; i < indices.size(); i++) {
+      if (feSpace->getMesh()->getDofIndexCoords(indices[i], feSpace, x))
+	dofValues.push_back((*values)(x));
+    }
+  }
+  
+  inline void getDOFValues(const FiniteElemSpace* feSpace, DOFVector<double>* values, std::vector<DegreeOfFreedom> &indices, std::vector<double> &dofValues)
+  {
+    for (size_t i = 0; i < indices.size(); i++) {
+      dofValues.push_back((*values)[indices[i]]);
+    }
+  }
+} // end namespace
+
+
+
+/**
+ * data structure that holds all possible variation of description of coords and value
+ * of (singular/implicit) dirichlet boundary condition.
+ **/
+struct DirichletBcData {
+
+  // pos = WorldVector
+  DirichletBcData(int i_, int j_, WorldVector<double> pos_, double val_)
+  : row(i_), col(j_), pos(pos_), val0(val_),
+    posType(0), valueType(0),
+    idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), val1(NULL), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL) {}
+
+  DirichletBcData(int i_, int j_, WorldVector<double> pos_, DOFVector<double> &val_)
+  : row(i_), col(j_), pos(pos_), val1(&val_),
+    posType(0), valueType(1),
+    idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), val0(0.0), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  {}
+
+  DirichletBcData(int i_, int j_, WorldVector<double> pos_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), pos(pos_), val2(&val_),
+    posType(0), valueType(2),
+    idx(0), SignedDistFct(NULL), SignedDistDOF(NULL), val0(0.0), val1(NULL),
+    boundary_nr(0), meshIndicator(NULL)  {}
+
+  // pos = idx
+  DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, double val_)
+  : row(i_), col(j_), idx(idx_), val0(val_),
+    posType(1), valueType(0),
+    SignedDistFct(NULL), SignedDistDOF(NULL), val1(NULL), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, DOFVector<double> &val_)
+  : row(i_), col(j_), idx(idx_), val1(&val_),
+    posType(1), valueType(1),
+    SignedDistFct(NULL), SignedDistDOF(NULL), val0(0.0), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, DegreeOfFreedom idx_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), idx(idx_), val2(&val_),
+    posType(1), valueType(2),
+    SignedDistFct(NULL), SignedDistDOF(NULL), val0(0.0), val1(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  // pos = SignedDistFct
+  DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, double val_)
+  : row(i_), col(j_), SignedDistFct(SignedDistFct_), val0(val_),
+    posType(2), valueType(0),
+    idx(0), SignedDistDOF(NULL), val1(NULL), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, DOFVector<double> &val_)
+  : row(i_), col(j_), SignedDistFct(SignedDistFct_), val1(&val_),
+    posType(2), valueType(1),
+    idx(0), SignedDistDOF(NULL), val0(0.0), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, AbstractFunction<double, WorldVector<double> > *SignedDistFct_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), SignedDistFct(SignedDistFct_), val2(&val_),
+    posType(2), valueType(2),
+    idx(0), SignedDistDOF(NULL), val0(0.0), val1(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  // pos = SignedDistDOF
+  DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, double val_)
+  : row(i_), col(j_), SignedDistDOF(SignedDistDOF_), val0(val_),
+    posType(3), valueType(0),
+    idx(0), SignedDistFct(NULL), val1(NULL), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, DOFVector<double> &val_)
+  : row(i_), col(j_), SignedDistDOF(SignedDistDOF_), val1(&val_),
+    posType(3), valueType(1),
+    idx(0), SignedDistFct(NULL), val0(0.0), val2(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, DOFVector<double> *SignedDistDOF_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), SignedDistDOF(SignedDistDOF_), val2(&val_),
+    posType(3), valueType(2),
+    idx(0), SignedDistFct(NULL), val0(0.0), val1(NULL),
+    boundary_nr(0), meshIndicator(NULL)  { pos.set(0.0); }
+    
+  // pos = meshindicator + boundary_nr
+  DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, double val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val0(val_),
+    posType(4), valueType(0),
+    idx(0), SignedDistFct(NULL), val1(NULL), val2(NULL),
+    boundary_nr(nr), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, DOFVector<double> &val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val1(&val_),
+    posType(4), valueType(1),
+    idx(0), SignedDistFct(NULL), val0(0.0), val2(NULL),
+    boundary_nr(nr), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, BoundaryType nr, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val2(&val_),
+    posType(4), valueType(2),
+    idx(0), SignedDistFct(NULL), val0(0.0), val1(NULL),
+    boundary_nr(nr), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+    
+  // pos = meshindicator
+  DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, double val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val0(val_),
+    posType(4), valueType(0),
+    idx(0), SignedDistFct(NULL), val1(NULL), val2(NULL),
+    boundary_nr(0), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, DOFVector<double> &val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val1(&val_),
+    posType(4), valueType(1),
+    idx(0), SignedDistFct(NULL), val0(0.0), val2(NULL),
+    boundary_nr(0), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+
+  DirichletBcData(int i_, int j_, AbstractFunction<bool, WorldVector<double> > *meshIndicator_, AbstractFunction<double, WorldVector<double> > &val_)
+  : row(i_), col(j_), SignedDistDOF(NULL), val2(&val_),
+    posType(4), valueType(2),
+    idx(0), SignedDistFct(NULL), val0(0.0), val1(NULL),
+    boundary_nr(0), meshIndicator(meshIndicator_)  { pos.set(0.0); }
+    
+  void addToList(const FiniteElemSpace *feSpace, std::vector<SingularDirichletBC> &list)
+  {
+    std::vector<DegreeOfFreedom> indices_;
+    std::vector<double> values_;
+    DegreeOfFreedom idx_ = 0;
+
+    switch (posType) {
+      case 0:
+	if (val1 == NULL && SignedDistDOF == NULL) {
+	  val1 = new DOFVector<double>(feSpace, "vel1");
+	}
+	if (val1 != NULL) {
+	  if (!val1->getDofIdxAtPoint(pos, idx_))
+	    idx_ = 0;
+	} else if (SignedDistDOF != NULL) {
+	  if (!SignedDistDOF->getDofIdxAtPoint(pos, idx_))
+	    idx_ = 0;
+	}
+	indices_.push_back(idx_);
+	break;
+	
+      case 1:
+	indices_.push_back(idx);
+	break;
+	
+      case 2:
+	details::getImplicitIndices(feSpace, SignedDistFct, indices_);
+	break;
+	
+      case 3:
+	details::getImplicitIndices(feSpace, SignedDistDOF, indices_);
+	break;
+	
+      case 4:
+	if (boundary_nr == 0)
+	  details:: getBoundaryIndices(feSpace, meshIndicator, indices_);
+	else
+	  details:: getBoundaryIndices(feSpace, boundary_nr, meshIndicator, indices_);
+	break;
+    }
+
+    switch (valueType) {
+      case 0:
+	values_.resize(indices_.size(), val0);
+	break;
+	
+      case 1:
+	details::getDOFValues(feSpace, val1, indices_, values_);
+	break;
+	
+      case 2:
+	details::getDOFValues(feSpace, val2, indices_, values_);
+	break;
+    }
+
+    DOFVector<WorldVector<double> > coords(feSpace, "coords");
+    feSpace->getMesh()->getDofIndexCoords(feSpace, coords);
+    
+
+    for (size_t i = 0; i < indices_.size(); i++) {
+      list.push_back(SingularDirichletBC(row, col, indices_[i], values_[i]));
+    }
+    
+    MSG_DBG("Dirichle BC at %d DOFs added.\n",indices_.size());
+  }
+
+
+  int row,col;
+
+private:
+  int posType; 		// 0..WorldVector, 1..DegreeOfFreedom, 2..SignedDistFct, 3..signedDistDOF, 4..meshIndicator
+  int valueType; 	// 0..double, 1..DOFVector, 2..AbstractFunction
+
+  // pos
+  WorldVector<double> pos;
+  DegreeOfFreedom idx;
+  AbstractFunction<double, WorldVector<double> > *SignedDistFct;
+  DOFVector<double> *SignedDistDOF;
+
+  BoundaryType boundary_nr;
+  AbstractFunction<bool, WorldVector<double> >* meshIndicator;
+  
+  // value
+  double val0;
+  DOFVector<double> *val1;
+  AbstractFunction<double, WorldVector<double> > *val2;
+};
+
+
+struct PeriodicBcData {
+
+  // pos = WorldVector
+  PeriodicBcData(int row_, BoundaryType nr_, AbstractFunction<bool, WorldVector<double> >* meshIndicator_,
+		 AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap_)
+  : row(row_), nr(nr_), meshIndicator(meshIndicator_), periodicMap(periodicMap_) {}
+
+  PeriodicBcData(int row_, AbstractFunction<bool, WorldVector<double> >* meshIndicator_,
+		 AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap_)
+  : row(row_), nr(0), meshIndicator(meshIndicator_), periodicMap(periodicMap_) {}
+
+  void addToList(const FiniteElemSpace *feSpace, std::vector<ManualPeriodicBC> &list)
+  {
+    std::vector<std::pair<DegreeOfFreedom, DegreeOfFreedom> > associations;
+    if (nr == 0)
+      details::getPeriodicAssociation(feSpace, meshIndicator, periodicMap, associations);
+    else
+      details::getPeriodicAssociation(feSpace, nr, meshIndicator, periodicMap, associations);
+    list.push_back(ManualPeriodicBC(row, associations));
+  }
+
+protected:
+
+  int row;
+
+  BoundaryType nr;
+  AbstractFunction<bool, WorldVector<double> >* meshIndicator;
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* periodicMap;
+};
+
+} // end namespace 
+
+#endif // SINGULAR_DIRICHLET_BC_H
diff --git a/extensions/Tools.h b/extensions/Tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..16c856ddcc2eb56d198b1806385cfb38ce259c5d
--- /dev/null
+++ b/extensions/Tools.h
@@ -0,0 +1,186 @@
+/** \file Tools.h */
+
+#ifndef TOOLS_H
+#define TOOLS_H
+
+#include <boost/array.hpp>
+#include <boost/fusion/container/vector.hpp>
+#include <boost/fusion/include/at_c.hpp>
+#include <boost/fusion/include/boost_array.hpp>
+
+#include "MetaTools.h"
+
+namespace tools {
+
+/// Quadrature Rules
+///____________________________________________________________________________________
+
+  struct SimpsonQuad
+  {
+    template<typename Functor, typename T> /// requires Callable1<Functor, T>, Addable<T>, Multiplicable<T>
+    T quad(Functor& f, T a, T b)
+    {
+      return (b - a) * (f(a) * (1.0 / 6.0) + f((a + b) * 0.5) * (4.0 / 6.0) + f(b) * (1.0 / 6.0));
+    }
+  };
+
+
+  template<typename Container>
+  struct GeneralQuad
+  {
+    GeneralQuad(Container& xi_, Container& ci_) : xi(xi_), ci(ci_) {}
+    
+    template<typename Functor, typename T>
+    struct IntegralValue {
+      IntegralValue(Functor& f_, T a_, T b_) : f(f_), a(a_), b(b_)
+      {
+	h = b - a;
+      }
+      void operator()(double& x, double& c, T& value)
+      {
+	value += f(a + x * h) * c;
+      }
+      Functor& f;
+      T a, b, h;
+    };
+
+    template<typename Functor, typename T> /// requires Callable1<Functor, T>, Addable<T>, Multiplicable<T>, Nullifyable<T>
+    T quad(Functor& f, T a, T b)
+    {
+      T I; nullify(I);
+
+      IntegralValue<Functor, T> integralValue(f,a,b);
+      for_each<boost::fusion::result_of::size<Container>::value - 1>::accumulate(xi, ci, I, integralValue);
+      
+      return (b - a) * I;
+    }
+
+  private:
+    Container& xi; // intermediate points
+    Container& ci; // weights
+  };
+
+
+  template<typename Quad>
+  struct CompositeQuad
+  {
+    CompositeQuad() : q(*(new SimpsonQuad)), n(1) {}
+    CompositeQuad(Quad& q_, unsigned int n_) : q(q_), n(n_) {}
+
+    template<typename Functor, typename T> /// requires Callable1<Functor, T>, Addable<T>, Multiplicable<T>, Nullifyable<T>
+    T quad(Functor& f, T a, T b)
+    {
+      T h = (b - a) * (1.0 / (n - 1.0));
+      T I; nullify(I);
+      for (unsigned int i = 1; i < n; i++)
+	I += q.quad(f, a + (i - 1.0) * h, a + i * h);
+      return h * I;
+    }
+
+    template<typename Functor, typename Vector, typename T> /// requires Callable1<Functor, T>, Addable<T>, Multiplicable<T>, Nullifyable<T>
+    T quad(Functor& f, Vector& x)
+    {
+      typename Vector::iterator xIter;
+      T I; nullify(I);
+      for (xIter = x.begin(); xIter+1 != x.end(); xIter++)
+	I += (*(xIter+1) - *xIter) * q.quad(f, *xIter, *(xIter+1));
+      return I;
+    }
+    
+  private:
+    Quad& q; 		// quadrature rule
+    unsigned int n; 	// number of points
+  };
+
+
+  struct SequenceQuad
+  {
+    // integration zwischen zwei Punkten mittels Trapezregel
+    template<typename Vector1, typename Vector2, typename T> /// requires Callable1<Functor, T>, Addable<T>, Multiplicable<T>, Nullifyable<T>
+    T quad(Vector1& y, Vector2& x)
+    {
+      T I; nullify(I);
+      for (size_t i = 0; i < x.size()-1; i++)
+	I += (x[i+1] - x[i]) * 0.5*(y[i] + y[i+1]);
+      return I;
+    }
+  };  
+
+  
+/// Regression, Interpolation and Approximation
+///____________________________________________________________________________________
+
+
+  struct Regression
+  {
+    Regression(int DOW_) : DOW(DOW_)
+    {
+      coefficients = std::vector<double>(DOW+1, 0.0);
+    }
+    
+    template<typename Vector1, typename Vector2>
+    void apply(Vector1& points, Vector2& values) {
+      int row = points.size();
+      int col = DOW + 1;
+      mtl::dense2D<double> A(row, col);
+      mtl::dense_vector<double> b(row);
+      for (size_t i = 0; i < row; i++) {
+	for (size_t j = 0; j < col-1; j++)
+	  A(i,j) = points[i][j];
+	A(i,DOW) = 1.0;
+	b[i] = values[i];
+      }
+      mtl::dense2D<double> Q(row, row), Qt(row, row), R(row, col);
+      boost::tie(Q, R) = mtl::matrix::qr_factors(A);
+      
+      mtl::dense_vector<double> bQ(col), x(col);
+      using mtl::iall;
+      using mtl::irange;
+      irange cols(0, col);
+      bQ = trans(Q[iall][cols])*b;
+      x = mtl::matrix::upper_trisolve(R[cols][cols], bQ[cols]);
+      for (int i = 0; i < DOW+1; i++)
+	coefficients[i] = x[i];
+    }
+    
+    template<typename Vector1, typename Vector2, typename Vector3>
+    void apply(Vector1& points, Vector2& values, Vector3& weights) {
+      int row = points.size();
+      int col = DOW + 1;
+      mtl::dense2D<double> A(row, col);
+      mtl::dense_vector<double> b(row);
+      for (size_t i = 0; i < row; i++) {
+	for (size_t j = 0; j < col-1; j++)
+	  A(i,j) = weights[i] * points[i][j];
+	A(i,DOW) = weights[i];
+	b[i] = weights[i] * values[i];
+      }
+      mtl::dense2D<double> Q(row, row), Qt(row, row), R(row, col);
+      boost::tie(Q, R) = mtl::matrix::qr_factors(A);
+      
+      mtl::dense_vector<double> bQ(col), x(col);
+      using mtl::iall;
+      using mtl::irange;
+      irange cols(0, col);
+      bQ = trans(Q[iall][cols])*b;
+      x = mtl::matrix::upper_trisolve(R[cols][cols], bQ[cols]);
+      for (int i = 0; i < DOW+1; i++)
+	coefficients[i] = x[i];
+    }
+    
+    template<typename Coords>
+    double value(Coords& x) {
+      double f = coefficients[DOW];
+      for (int i = 0; i < DOW; i++)
+	f += coefficients[i]*x[i];
+      return f;
+    }
+    
+  private:
+    int DOW;
+    std::vector<double> coefficients; // c[0]*x[0] + c[1]*x[1] + c[2]
+  };
+
+} // end namespace
+
+#endif // TOOLS_H
diff --git a/extensions/VectorOperations.h b/extensions/VectorOperations.h
new file mode 100644
index 0000000000000000000000000000000000000000..de8572e6c8d286e9bc5ea2e7ab42395789e5b776
--- /dev/null
+++ b/extensions/VectorOperations.h
@@ -0,0 +1,533 @@
+/** \file VectorOperations.h */
+
+#ifndef VECTOR_OPERATIONS_H
+#define VECTOR_OPERATIONS_H
+
+#include "AMDiS.h"
+
+#if HAVE_PARALLEL_DOMAIN_AMDIS
+#include "parallel/StdMpi.h"
+#endif
+
+#include <unistd.h>
+#include <ios>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/itl/itl.hpp>
+
+using namespace AMDiS; 
+
+template<typename T>
+const WorldVector<T>& operator*=(WorldVector<T>& v1, const WorldVector<T>& v2)
+{
+  T* v1It, *v2It;
+  for (v1It = v1.begin(), v2It = v2.begin();
+	  v1It != v1.end(); 
+	  v1It++, v2It++)
+  *v1It *= *v2It;
+  
+  return v1;
+};
+
+// x ~= y
+template<typename T>
+class compareTol : public binary_function<T, T, bool> {
+public:
+	compareTol(double tol_) : tol(tol_) {}
+	bool operator()(const T &x, const T &y) const { return sqrt((x-y)*(x-y))<tol; }
+	double tol;
+};
+template<typename T1, typename T2, int component>
+struct comparePair : public binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool> 
+{
+  bool operator()(const std::pair<T1, T2> &x, const std::pair<T1, T2> &y) const 
+  { 
+    return (component==0?(x.first<y.first):(x.second<y.second));
+  }
+};
+
+template<typename T1, typename T2>
+struct compare0 : public binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool> 
+{
+  bool operator()(const std::pair<T1, T2> &x, const std::pair<T1, T2> &y) const 
+  { 
+    return x.first<y.first;
+  }
+};
+template<typename T1, typename T2>
+struct compare1 : public binary_function<std::pair<T1, T2>, std::pair<T1, T2>, bool> 
+{
+  bool operator()(const std::pair<T1, T2> &x, const std::pair<T1, T2> &y) const 
+  { 
+    return x.second<y.second;
+  }
+};
+
+class SortPair : public binary_function<std::pair<WorldVector<double>, double>, std::pair<WorldVector<double>, double>, bool> {
+public:
+	SortPair(int component_=1,int idx_=0) : component(component_),idx(idx_) {}
+	bool operator()(const std::pair<WorldVector<double>, double> &x, 
+		const std::pair<WorldVector<double>, double> &y) const { 
+		return (component==1?(x.first)[idx]<(y.first)[idx]:x.second<y.second); }
+	int component,idx;
+};
+
+namespace vector_operations {
+
+  // num_rows for vector types
+  template<typename T>
+  size_t num_rows(WorldVector<T> &v) {
+    return static_cast<size_t>(v.getSize());
+  };
+  template<typename T>
+  size_t num_rows(const WorldVector<T> &v) {
+    return static_cast<size_t>(v.getSize());
+  };
+  template<typename T>
+  size_t num_rows(std::vector<T> &v) {
+    return static_cast<size_t>(v.size());
+  };
+  template<typename T>
+  size_t num_rows(const std::vector<T> &v) {
+    return static_cast<size_t>(v.size());
+  };
+
+  // num_rows/num_cols for matrix types
+  template<typename T>
+  size_t num_rows(WorldMatrix<T> &m) {
+    return static_cast<size_t>(m.getNumRows());
+  };
+  template<typename T>
+  size_t num_rows(const WorldMatrix<T> &m) {
+    return static_cast<size_t>(m.getNumRows());
+  };
+  template<typename T>
+  size_t num_cols(WorldMatrix<T> &m) {
+    return static_cast<size_t>(m.getNumCols());
+  };
+  template<typename T>
+  size_t num_cols(const WorldMatrix<T> &m) {
+    return static_cast<size_t>(m.getNumCols());
+  };
+  
+  // common interface to resize vectors
+  template<typename T>
+  void resize(WorldVector<T> &v, size_t dim) {
+    TEST_EXIT(dim==v.getSize())("WorldVectors can not be resized to the given dimension!\n");
+  };
+  template<typename T>
+  void resize(std::vector<T> &v, size_t dim) {
+    v.resize(dim);
+  };
+  template<typename T>
+  void resize(mtl::dense_vector<T> &v, size_t dim) {
+    v.change_dim(dim);
+  };
+  
+  
+  
+  // B(phi)=phi^2*(1-phi)^2
+  template<typename T>
+  T norm(mtl::dense_vector<T> &b) { return two_norm(b); };
+  
+  template<typename T>
+  T norm(std::vector<T> &b) 
+  {
+    T value = 0.0;
+    for (size_t i = 0; i < b.size(); ++i)
+      value += sqr(b[i]);
+    return sqrt(value);
+  };
+  
+  template<typename Matrix>
+  double matrix_norm(Matrix &M)
+  {
+    typename Matrix::value_type asum;
+    asum = 0.0;
+    for (size_t i = 0; i < num_rows(M); ++i) {
+      for (size_t j = 0; j < num_cols(M); ++j)
+	asum += abs(M[i][j]);
+    }
+    return static_cast<double>(asum/(num_rows(M)*num_cols(M)));
+  };
+  
+  // |x|_eps
+  inline double epsNorm(const WorldVector<double> &x, const double &eps) { return std::max(AMDiS::norm(x),eps); };
+  
+  // 1/|x|_eps
+  inline double epsNormInv(const WorldVector<double> &x, const double &eps) { return 1.0/epsNorm(x,eps); };
+  
+  // 1/[|x|_eps]^3
+  inline double epsNormInv3(const WorldVector<double> &x, const double &eps)
+  {
+    double result = epsNorm(x,eps);
+    result = 1.0/(result*sqr(result));  
+    return result;
+  };
+  
+  // y:=x/|x|_eps
+  inline void epsNormalize(const WorldVector<double> &x, const double &eps, WorldVector<double> &y)
+  {
+    double nrmInv = epsNormInv(x,eps);
+    for(int k=0; k<x.getSize(); k++) {
+      y[k] = x[k] * nrmInv;
+    }
+  };
+
+  template<typename Matrix>
+  double trace(Matrix &M)
+  {
+    TEST_EXIT(num_rows(M)==num_cols(M))("Matrix dimensions must be equal!\n");
+    typename Matrix::value_type sum;
+    sum = 0.0;
+    for (size_t i = 0; i < num_rows(M); ++i) {
+      sum += M[i][i];
+    }
+    return static_cast<double>(sum);
+  };
+  
+  template<typename T>
+  Vector<T> mult(const Vector<T>& v1, const Vector<T>& v2)
+  {
+    TEST_EXIT(v1.getSize()==v2.getSize())("Vectors must have the same size!\n");
+    Vector<T> result(v1.getSize());
+    Vector<T> *v1It, *v2It, *resultIt;
+    for (v1It = v1.begin(), v2It = v2.begin(), resultIt = result.begin(); v1It != v1.end(); ++v1It, ++v2It, ++resultIt)
+	*resultIt = *v1It * *v2It;
+    return result;
+  };
+  
+  inline WorldVector<double> mult(const mtl::dense2D<double> &A, const WorldVector<double> &x)
+  {
+    TEST_EXIT(num_rows(A)==x.getSize())("Falsche Dimensionen multipliziert!");
+    WorldVector<double> result;
+    for (unsigned i = 0; i < x.getSize(); ++i) {
+      result[i] = 0.0;
+      for (unsigned j = 0; j < x.getSize(); ++j)
+	result[i] += A[i][j]*x[j];
+    }
+    return result;
+  };
+  
+  template<typename ResultVector, typename Matrix, typename Vector1, typename Vector2>
+  ResultVector Axpy(const Matrix &A, const Vector1 &x, const Vector2 &y)
+  {
+    size_t n = num_rows(x);
+    TEST_EXIT(num_rows(A)==n && num_cols(A)==n && num_rows(y)==n)("Falsche Dimensionen multipliziert!");
+    ResultVector result;
+    resize(result, n);
+    for (unsigned i = 0; i < n; ++i) {
+      result[i] = y[i];
+      for (unsigned j = 0; j < n; ++j)
+	result[i] += A[i][j]*x[j];
+    }
+    return result;
+  };
+
+  inline void unitVector(WorldVector<double> &b, int &idx) {
+    TEST_EXIT(idx>=0 && idx<b.getSize())("Unit-Vector component does not exist!\n");
+    b.set(0.0);
+    b[idx]=1.0;
+  };
+  
+  inline WorldVector<double> *unitVector(int &idx) {
+    WorldVector<double> *result = new WorldVector<double>;
+    TEST_EXIT(idx>=0 && idx<result->size())("Unit-Vector component does not exist!\n");
+    (*result)[idx]=1.0;
+    return result;
+  };
+
+  template<typename T>
+  void copy(std::vector<T> &v, WorldVector<T> &w)
+  {
+    for(int i=0; i<std::min((int)v.size(),(int)w.getSize()); i++)
+	    w[i]=v[i];
+  };
+  
+  template<typename T>
+  void copy(mtl::dense_vector<T> &v, WorldVector<T> &w)
+  {
+    for(int i=0; i<std::min((int)num_rows(v),(int)w.getSize()); i++)
+	    w[i]=v[i];
+  };
+  
+  template<typename T>
+  void copy(WorldVector<T> &w, mtl::dense_vector<T> &v)
+  {
+    for(int i=0; i<std::min((int)num_rows(v),(int)w.getSize()); i++)
+	    v[i]=w[i];
+  };
+  
+  template<typename T>
+  void merge(std::vector<T> &v1, std::vector<T> &v2, std::vector<T> &v3)
+  {
+    v3.resize(v1.size()+v2.size());
+    for(int i=0;i<v1.size();i++)
+	    v3[i]=v1[i];
+    for(int j=0;j<v2.size();j++)
+	    v3[j+v1.size()]=v2[j];
+  };
+  
+  template<typename T>
+  void getMin(mtl::dense_vector<T> &v, T &minVal, unsigned &minIdx)
+  {
+    if(num_rows(v)==0) {
+      minVal = numeric_limits<T>::infinity();
+    } else {
+      minVal=v[0]; minIdx=0;
+      for(unsigned i=1; i<num_rows(v); i++) {
+	if(v[i]<minVal) { minVal=v[i]; minIdx=i; }
+      }
+    }
+  };
+  
+  template<typename T>
+  void getMin(std::vector<T> &v, T &minVal, size_t &minIdx)
+  {
+    if (v.size() == 0) {
+      minVal = numeric_limits<T>::infinity();
+    } else {
+      minVal = v[0];
+      minIdx = 0;
+      for(size_t i = 1; i < v.size(); i++) {
+	if (v[i] < minVal) { 
+	  minVal=v[i];
+	  minIdx=i;
+	}
+      }
+    }
+  };
+  
+  template<typename T>
+  void getMax(mtl::dense_vector<T> &v, T &maxVal, unsigned &maxIdx)
+  {
+    if(num_rows(v)==0) {
+      maxVal = -numeric_limits<T>::infinity();
+    } else {
+      maxVal=v[0]; maxIdx=0;
+      for(unsigned i=1; i<num_rows(v); i++) {
+	if(v[i]>maxVal) { maxVal=v[i]; maxIdx=i; }
+      }
+    }
+  };
+
+  template<typename T>
+  T max(const std::vector<T> &vec)
+  {
+    double maxVal;
+    if(vec.size()==0) {
+      maxVal = -numeric_limits<T>::infinity();
+    } else {
+      maxVal=vec[0];
+      for(size_t i=1; i<vec.size(); i++) {
+	if(vec[i]>maxVal) { maxVal=vec[i]; }
+      }
+    }
+    return maxVal;
+  };
+
+  template<typename T>
+  T min(const std::vector<T> &vec)
+  {
+    double minVal;
+    if(vec.size()==0) {
+      minVal = numeric_limits<T>::infinity();
+    } else {
+      minVal=vec[0];
+      for(size_t i=1; i<vec.size(); i++) {
+	if(vec[i]<minVal) { minVal=vec[i]; }
+      }
+    }
+    return minVal;
+  };
+  
+  template<typename T>
+  T absmax(std::vector<T> &vec)
+  {
+    double maxVal;
+    if(vec.size()==0) {
+      maxVal = -numeric_limits<T>::infinity();
+    } else {
+      maxVal=abs(vec[0]);
+      for(size_t i=1; i<vec.size(); i++) {
+	if(abs(vec[i])>maxVal) { maxVal=abs(vec[i]); }
+      }
+    }
+    return maxVal;
+  };
+  
+  template<typename T>
+  T sum(std::vector<T> &vec)
+  {
+    unsigned N=vec.size();
+    T value = 0;
+    if(N>0) {
+      value = vec[0];
+      for(unsigned i=1; i<N; ++i) {
+	value += vec[i];
+      }
+    }
+    return value;
+  };
+  
+  template<typename T>
+  void getMean(std::vector<T> &vec, T &meanValue)
+  {
+    unsigned N=vec.size();
+    meanValue = sum(vec)/double(N);
+  };
+  
+//   template<typename Vector1, typename Vector2>
+//   struct VectorPair {
+//     typedef typename Vector1::size_type 	size_type;
+//     typedef typename Vector1::value_type 	T1;
+//     typedef typename Vector2::value_type 	T2;
+//     typedef typename Vector1::iterator 		iterator1;
+//     typedef typename Vector2::iterator 		iterator2;
+//     typedef typename std::pair<T1, T2>& 	reference;
+//     typedef typename const std::pair<T1, T2>& 	const_reference;
+//     
+//     typedef struct PairIterator : public iterator<random_access_iterator_tag> {
+//       PairIterator(iterator1& iter1_, iterator2& iter2_) : iter1(iter1_), iter2(iter2_) {}
+//       PairIterator(const PairIterator& piter) : iter1(piter.iter1), iter2(piter.iter2) {}
+//       PairIterator& operator++() {++iter1; ++iter2; return *this;}
+//       PairIterator& operator--() {--iter1; --iter2; return *this;}
+//       PairIterator& operator+(int n) {PairIterator tmp(*this); tmp.iter1+=n; tmp.iter2+=n; return tmp;}
+//       PairIterator& operator-(int n) {PairIterator tmp(*this); tmp.iter1-=n; tmp.iter2-=n; return tmp;}
+//       PairIterator& operator+=(int n) {iter1+=n; iter2+=n; return *this;}
+//       PairIterator& operator-=(int n) {iter1-=n; iter2-=n; return *this;}
+// //       PairIterator operator++(int) {PairIterator tmp(*this); operator++(); return tmp;} //?1
+//       bool operator==(const PairIterator& rhs) {return iter1 == rhs.iter1 && iter2 == rhs.iter2;}
+//       bool operator<(const PairIterator& rhs) {return iter1 < rhs.iter1 && iter2 < rhs.iter2;}
+//       bool operator>(const PairIterator& rhs) {return iter1 > rhs.iter1 && iter2 > rhs.iter2;}
+//       bool operator<=(const PairIterator& rhs) {return iter1 <= rhs.iter1 && iter2 <= rhs.iter2;}
+//       bool operator>=(const PairIterator& rhs) {return iter1 >= rhs.iter1 && iter2 >= rhs.iter2;}
+//       bool operator!=(const PairIterator& rhs) {return iter1 != rhs.iter1 || iter2 != rhs.iter2;}
+//       std::pair<T1&, T2&>& operator*() {return std::make_pair(*iter1, *iter2);}
+//       std::pair<T1&, T2&>& operator[](int n) {return std::make_pair(*(iter1+n), *(iter2+n));}
+// 
+//     protected:
+//       iterator1 iter1;
+//       iterator2 iter2;
+//     } iterator;
+//   };
+  
+  template<typename T1, typename T2, typename Compare>
+  void sort(std::vector<T1> &vec1, std::vector<T2> &vec2, Compare &comp)
+  {
+    std::vector<pair<T1,T2> > order(vec1.size());
+    
+    // create vector of pairs
+    for (int i=0; i<vec1.size(); ++i)
+      order[i] = make_pair(vec1[i], vec2[i]);
+    
+    // sort vector of pairs
+    sort(order.begin(), order.end(), comp);
+    
+    // copy sorted pairs back to vectors
+    for (int i=0; i<vec1.size(); ++i) {
+      vec1[i] = order[i].first;
+      vec2[i] = order[i].second;
+    }
+  };
+  
+  template<typename T1, typename T2, typename Compare>
+  void sort(std::vector<std::pair<T1,T2> > &vec, Compare &comp)
+  {
+    std::sort(vec.begin(), vec.end(), comp);
+  };
+  
+  inline void unique(std::vector<WorldVector<double> > &vec, double tol, std::vector<unsigned> &ind)
+  {
+    compareTol<WorldVector<double> > comp(tol);
+    unsigned newVec=0;
+    for(unsigned i=0; i<vec.size();++i) {
+      bool inNew=false;
+      for(unsigned j=0;j<newVec;++j) {
+	inNew=inNew||comp(vec[i],vec[j]);
+	if(inNew) break;
+      }
+      if(!inNew) {vec[newVec]=vec[i]; newVec++; ind.push_back(i);}
+    }
+    vec.erase(vec.begin()+newVec,vec.end());
+  };
+  
+  template<typename T1, typename T2>
+  void unique(std::vector<std::pair<T1,T2> > &vec, double tol, int uniqueBy=1)
+  {
+//     comparePair comp = comparePair(tol,uniqueBy);
+//     unsigned newVec=0;
+//     for(unsigned i=0; i<vec.size();++i) {
+//       bool inNew=false;
+//       for(unsigned j=0;j<newVec;++j) {
+// 	inNew=inNew||comp(vec[i],vec[j]);
+// 	if(inNew) break;
+//       }
+//       if(!inNew) {vec[newVec]=vec[i]; newVec++;}
+//     }
+//     vec.erase(vec.begin()+newVec,vec.end());
+  };
+  
+  inline void filter(std::vector<WorldVector<double> > &x, std::vector<bool> &filter)
+  {
+    unsigned j=0;
+    for(unsigned i=0; i<x.size(); ++i) {
+      if(filter[i]) {
+	x[j]=x[i];
+	j++;
+      }
+    }
+    x.erase(x.begin()+j,x.end());
+  };
+  
+  inline void filter(std::vector<WorldVector<double> > &x, std::vector<int> &filter)
+  {
+    unsigned j=0;
+    for(unsigned i=0; i<filter.size(); ++i) {
+      x[j]=x[filter[i]];
+      j++;
+    }
+    x.erase(x.begin()+j,x.end());
+  };
+  template<typename T, typename T1, typename T2>
+  T dot(std::vector<T1> &vec1, std::vector<T2> &vec2)
+  {
+    unsigned N=vec1.size();
+    T value = 0;
+    if(N>0) {
+      value = static_cast<T>(vec1[0])*static_cast<T>(vec2[0]);
+      for(unsigned i=1; i<N; ++i) {
+	value += static_cast<T>(vec1[i])*static_cast<T>(vec2[i]);
+      }
+    }
+    return value;
+  };
+  template<typename T, typename T1, typename T2>
+  T dot(mtl::dense_vector<T1> &vec1, WorldVector<T2> &vec2)
+  {
+      unsigned N=vec2.getSize();
+      T value = 0;
+      if(N>0) {
+	  value = static_cast<T>(vec1[0])*static_cast<T>(vec2[0]);
+	  for(unsigned i=1; i<N; ++i) {
+	      value += static_cast<T>(vec1[i])*static_cast<T>(vec2[i]);
+	  }
+      }
+      return value;
+  };
+  
+  template<class T>
+  static void fillMatrix(WorldMatrix<T> &m, mtl::dense2D<T> &m_in)
+  {
+    m.resize(num_rows(m_in),num_cols(m_in));
+    for (size_t i = 0; i < num_rows(m_in); ++i) {
+      for (size_t j = 0; j < num_cols(m_in); ++j) {
+	m[i][j] = m_in(i,j);
+      }
+    }
+  };
+}
+
+#endif // VECTOR_OPERATIONS_H
diff --git a/extensions/Views.h b/extensions/Views.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c2f7ba76262a96f3629df9df7c024e6284a1e6f
--- /dev/null
+++ b/extensions/Views.h
@@ -0,0 +1,558 @@
+/** \file Views.h */
+
+#ifndef MY_VIEWS_H
+#define MY_VIEWS_H
+
+#include <stdexcept>
+#include <boost/type_traits/is_base_of.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include "AMDiS.h"
+#ifdef USE_BACKGROUNDMESH
+  #include "BackgroundMesh.h"
+#endif
+#ifdef USE_KD_TREE
+  #include "kdtree_nanoflann_dof.h"
+#endif
+
+using namespace AMDiS; 
+
+/// Abstract-Function-Views
+/// ________________________________________________________________________________________________
+
+/// result = 0.5*(f(x)+1)
+template<typename T>
+struct PhaseView : AbstractFunction<T, WorldVector<double> > {
+  PhaseView(AbstractFunction<T, WorldVector<double> > &fct_) : fct(fct_) {}
+  PhaseView(AbstractFunction<T, WorldVector<double> > *fct_) : fct(*fct_) {}
+  T operator()(const WorldVector<double>& x) const {
+	  return std::max(0.0, std::min(1.0, 0.5*(fct(x)+1.0)));
+  }
+private:
+  AbstractFunction<T, WorldVector<double> > fct;
+};
+
+/// result = 2*f(x)-1
+template<typename T>
+struct ChView : AbstractFunction<T, WorldVector<double> > {
+  ChView(AbstractFunction<T, WorldVector<double> > &fct_) : fct(fct_) {}
+  ChView(AbstractFunction<T, WorldVector<double> > *fct_) : fct(*fct_) {}
+  T operator()(const WorldVector<double>& x) const {
+	  return std::max(-1.0, std::min(1.0, 2.0*fct(x)-1.0));
+  }
+private:
+  AbstractFunction<T, WorldVector<double> > fct;
+};
+
+template<typename T>
+struct MultView : AbstractFunction<T, WorldVector<double> > {
+  MultView(AbstractFunction<T, WorldVector<double> > &fct_, double factor_) : fct(fct_), factor(factor_) {}
+  MultView(AbstractFunction<T, WorldVector<double> > *fct_, double factor_) : fct(*fct_), factor(factor_) {}
+  T operator()(const WorldVector<double>& x) const {
+    return factor*fct(x);
+  }
+private:
+  AbstractFunction<T, WorldVector<double> > fct;
+  double factor;
+};
+
+/// DOFVector-Views
+/// ________________________________________________________________________________________________
+
+template<typename T>
+struct DOFView : public DOFVector<T> {
+  typedef T result_type;
+  
+  DOFView(DOFVector<T> *vec_)
+  : DOFVector<T>(vec_->getFeSpace(), "dof_view"), 
+    vector(vec_)
+  {
+    nullify(value0);
+  }
+    
+  DOFView(DOFVector<T> &vec_)
+  : DOFVector<T>(vec_.getFeSpace(), "dof_view"), 
+    vector(&vec_)
+  {
+    nullify(value0);
+  }
+  
+  /// Returns \ref vec[i]
+  inline const T& operator[](WorldVector<double> &x) const 
+  {
+    FUNCNAME("DOFVector<T>::operator[x]");
+    DegreeOfFreedom idx = -1;
+    WorldVector<double> x_ = coordsView(x);
+    bool inside = vector->getDofIdxAtPoint(x_, idx);
+    
+    return (inside ? operator[](idx) : value0);
+  } 
+
+  /// Returns \ref vec[i]
+  inline T& operator[](WorldVector<double> &x) 
+  {
+    FUNCNAME("DOFVector<T>::operator[x]");
+    DegreeOfFreedom idx = -1;
+    WorldVector<double> x_ = coordsView(x);
+    bool inside = vector->getDofIdxAtPoint(x_, idx);
+
+    return (inside ? operator[](idx) : value0);
+  }
+  
+  inline T& operator[](DegreeOfFreedom idx)
+  {
+    DOFVector<T>::operator[](idx)= valueView(idx);
+    return DOFVector<T>::operator[](idx);
+  }
+  
+  inline const T& operator[](DegreeOfFreedom idx) const 
+  {
+    const T& swap(valueView(idx));
+    T& swap2 = const_cast<T&>(DOFVector<T>::operator[](idx));
+    swap2 = swap;
+    return swap2;
+  }
+  
+  inline const T evalAtPoint(WorldVector<double> &p, 
+			      ElInfo *oldElInfo = NULL, 
+			      T* valueReturn = NULL
+			    ) const 
+  {
+    FUNCNAME("DOFVector<T>::operator[x]");
+    
+    WorldVector<double> x_ = coordsView(p);
+    const FiniteElemSpace* feSpace = vector->getFeSpace();
+    
+    if (oldElInfo && feSpace->getMesh() == oldElInfo->getMesh()) {
+      Mesh* mesh = feSpace->getMesh();
+      DimVec<double> lambda(mesh->getDim(), NO_INIT);
+      int k = oldElInfo->worldToCoord(x_, &lambda);
+      if (k < 0) {
+	std::vector<DegreeOfFreedom> localIndices;	// DOF-indices of all DOFs in trinangle
+	mtl::dense_vector<double> uh; 		// evaluation of DOFVectors at QPs
+
+	localIndices.resize(feSpace->getBasisFcts()->getNumber());
+	uh.change_dim(mesh->getDim()+1);
+	
+	feSpace->getBasisFcts()->getLocalIndices(oldElInfo->getElement(), feSpace->getAdmin(), localIndices);
+	for (int l = 0; l < feSpace->getBasisFcts()->getNumber(); l++)
+	  uh[l] = (*vector)[localIndices[l]];
+	T value = feSpace->getBasisFcts()->evalUh(lambda, uh);
+	return value;
+      }
+    }
+    
+#ifdef USE_BACKGROUNDMESH
+    using namespace experimental;
+    bool use_backgroundmesh = false;
+    Parameters::get("backgroundMesh->enabled",use_backgroundmesh);
+    if (use_backgroundmesh) {
+      Box* box = Box::provideBackgroundMesh(feSpace);
+      int evaluation_accuracy = 0;
+      Parameters::get("backgroundMesh->evaluation accuracy",evaluation_accuracy);
+      T value = box->evalAtPoint(*vector, x_, evaluation_accuracy);
+      return value;
+    }
+#endif
+#ifdef USE_KD_TREE
+    using namespace experimental;
+    bool use_kdtree = false;
+    Parameters::get("KD-Tree->enabled",use_kdtree);
+    if (use_kdtree) {
+      KD_Tree* tree = provideKDTree(feSpace);
+      T value = tree->evalAtPoint(*vector, x_);
+      return value;
+    }
+#endif
+    DegreeOfFreedom idx = -1;
+    T value = value0;    
+    Mesh* mesh = feSpace->getMesh();
+    
+    ElInfo *elInfo = mesh->createNewElInfo();
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+
+    bool inside = mesh->findElInfoAtPoint(x_, elInfo, lambda, (oldElInfo ? oldElInfo->getMacroElement() : NULL), NULL, NULL);
+    
+    if (inside) {      
+      std::vector<DegreeOfFreedom> localIndices;
+      mtl::dense_vector<T> uh; 	
+
+      localIndices.resize(feSpace->getBasisFcts()->getNumber());
+      uh.change_dim(feSpace->getBasisFcts()->getNumber());
+    
+      feSpace->getBasisFcts()->getLocalIndices(elInfo->getElement(), feSpace->getAdmin(), localIndices);
+      for (int l = 0; l < feSpace->getBasisFcts()->getNumber(); l++)
+	uh[l] = valueView(localIndices[l]);
+      value = feSpace->getBasisFcts()->evalUh(lambda, uh);
+    }
+    if (valueReturn)
+      *valueReturn = value;
+    delete elInfo;
+    
+    return value;
+  } 
+  
+protected:
+  
+  virtual inline T valueView(DegreeOfFreedom idx) const
+  {
+    return (*vector)[idx];
+  }
+  
+  virtual inline WorldVector<double> coordsView(WorldVector<double> &x) const
+  {
+    return x;
+  }
+  
+  void setDefaultValue(T& value0_)
+  {
+    value0 = value0_;
+  };
+  
+  DOFVector<T> *vector;
+  T value0;
+};
+
+/// DOFVector-Views ... Value-Views
+/// ________________________________________________________________________________________________
+
+template<typename T> 
+struct PhaseDOFView : public DOFView<T> {
+  typedef T result_type;
+  
+  PhaseDOFView(DOFVector<T> &vec_) : DOFView<T>(&vec_) {}
+  PhaseDOFView(DOFVector<T> *vec_) : DOFView<T>(vec_) {}
+	
+protected:
+  
+  inline T valueView(DegreeOfFreedom idx) const
+  {
+    return std::max(0.0, std::min(1.0, 0.5*((*DOFView<T>::vector)[idx]+1.0)));
+  }
+};
+
+
+template<typename T> 
+struct InvPhaseView : public DOFView<T> {
+  typedef T result_type;
+
+  InvPhaseView(DOFVector<T> &vec_) : DOFView<T>(&vec_) {}
+  InvPhaseView(DOFVector<T> *vec_) : DOFView<T>(vec_) {}
+ 
+protected:
+  
+  inline T valueView(DegreeOfFreedom idx) const
+  {
+    return -(*DOFView<T>::vector)[idx];
+  }
+};
+
+/// DOFVector-Views ... Coord-Views
+/// ________________________________________________________________________________________________
+
+/// vec[x] := vec.evalAtPoint(R^(-1) * x)
+template<typename T> 
+struct RotateView : public DOFView<T> {
+  typedef T result_type;
+
+  RotateView(DOFVector<T> &vec_, WorldMatrix<double> R_) : DOFView<T>(&vec_), R(R_) {}
+  RotateView(DOFVector<T> *vec_, WorldMatrix<double> R_) : DOFView<T>(vec_), R(R_) {}
+  
+  RotateView(DOFVector<T> &vec_, double alpha) : DOFView<T>(&vec_) {
+    R.setDiag(1.0);
+    R[0][0] = cos(alpha);  R[0][1] = -sin(alpha);
+    R[1][0] = sin(alpha);  R[1][1] = cos(alpha);
+  }
+  RotateView(DOFVector<T> *vec_, double alpha) : DOFView<T>(vec_) {
+    R.setDiag(1.0);
+    R[0][0] = cos(alpha);  R[0][1] = -sin(alpha);
+    R[1][0] = sin(alpha);  R[1][1] = cos(alpha);
+  }
+ 
+protected:
+  
+  inline WorldVector<double> coordsView(WorldVector<double> &x) const
+  {
+    WorldVector<double> x_;
+    WorldMatrix<double> R_ = R;
+    for (int i = 0; i < R_.getNumRows(); i++)
+      for (int j = 0; j < i; j++)
+	std::swap(R_[i][j], R_[j][i]);
+    x_.multMatrixVec(R_, x);
+    return x_;
+  }
+  
+private:
+  
+  WorldMatrix<double> R;
+};
+
+
+/// vec[x] := vec.evalAtPoint(x ./ scale)
+template<typename T> 
+struct ScaleView : public DOFView<T> {
+  typedef T result_type;
+
+  ScaleView(DOFVector<T> &vec_, WorldVector<double> scale_) : DOFView<T>(&vec_), scale(scale_) {}
+  ScaleView(DOFVector<T> *vec_, WorldVector<double> scale_) : DOFView<T>(vec_), scale(scale_) {}
+ 
+  ScaleView(DOFVector<T> &vec_, double scale_) : DOFView<T>(&vec_) { scale.set(scale_); }
+  ScaleView(DOFVector<T> *vec_, double scale_) : DOFView<T>(vec_) { scale.set(scale_); }
+  
+protected:
+  
+  inline WorldVector<double> coordsView(WorldVector<double> &x) const
+  {
+    WorldVector<double> x_;
+    for (int i = 0; i < x_.getSize(); i++)
+      x_[i] = x[i]/scale[i];
+    return x_;
+  }
+  
+private:
+  
+  WorldVector<double> scale;
+};
+
+/// vec[x] := vec.evalAtPoint(x - shift)
+template<typename T> 
+struct ShiftView : public DOFView<T> {
+  typedef T result_type;
+
+  ShiftView(DOFVector<T> &vec_, WorldVector<double> shift_) : DOFView<T>(&vec_), shift(shift_) {}
+  ShiftView(DOFVector<T> *vec_, WorldVector<double> shift_) : DOFView<T>(vec_), shift(shift_) {}
+  
+  void setShift(WorldVector<double> &shift_) { shift = shift_; }
+  
+protected:
+  
+  inline WorldVector<double> coordsView(WorldVector<double> &x) const
+  {
+    WorldVector<double> x_;
+    for (int i = 0; i < x_.getSize(); i++)
+      x_[i] = x[i]-shift[i];
+    return x_;
+  }
+  
+private:
+  
+  WorldVector<double> shift;
+};
+
+/// evalAtPoint for several Data-Structures
+/// ________________________________________________________________________________________________
+
+// DOFVector can be accessed by locating the elInfo and than using barycentric coordinates
+// The default value, if p outside of geometry, is 0.0
+template<typename T>
+inline T evalAtPoint(const DOFVector<T> &obj, WorldVector<double> &p, ElInfo* oldElInfo = NULL)
+{
+  const FiniteElemSpace* feSpace = obj.getFeSpace();
+  Mesh* mesh = feSpace->getMesh();
+  
+  if (oldElInfo && feSpace->getMesh() == oldElInfo->getMesh()) {
+    DimVec<double> lambda(mesh->getDim(), NO_INIT);
+    oldElInfo->worldToCoord(p, &lambda);
+    
+    std::vector<DegreeOfFreedom> localIndices;	// DOF-indices of all DOFs in trinangle
+    mtl::dense_vector<T> uh; 		// evaluation of DOFVectors at QPs
+
+    localIndices.resize(feSpace->getBasisFcts()->getNumber());
+    uh.change_dim(mesh->getDim()+1);
+    
+    feSpace->getBasisFcts()->getLocalIndices(oldElInfo->getElement(), feSpace->getAdmin(), localIndices);
+    for (int l = 0; l < feSpace->getBasisFcts()->getNumber(); l++)
+      uh[l] = obj[localIndices[l]];
+    T value = feSpace->getBasisFcts()->evalUh(lambda, uh);
+    return value;
+  }
+    
+#ifdef USE_BACKGROUNDMESH
+  using namespace experimental;
+  bool use_backgroundmesh = false;
+  Parameters::get("backgroundMesh->enabled",use_backgroundmesh);
+  if (use_backgroundmesh) {
+    Box* box = Box::provideBackgroundMesh(feSpace);
+    int evaluation_accuracy = 0;
+    Parameters::get("backgroundMesh->evaluation accuracy",evaluation_accuracy);
+    T value = box->evalAtPoint(obj, p, evaluation_accuracy);
+    return value;
+  }
+#endif
+#ifdef USE_KD_TREE
+    using namespace experimental;
+    bool use_kdtree = false;
+    Parameters::get("KD-Tree->enabled",use_kdtree);
+    if (use_kdtree) {
+      KD_Tree* tree = provideKDTree(feSpace);
+      T value = tree->evalAtPoint(obj, p);
+      return value;
+    }
+#endif   
+  T value; nullify(value);
+  
+  ElInfo *elInfo = mesh->createNewElInfo();
+  DimVec<double> lambda(mesh->getDim(), NO_INIT);
+
+  std::vector<DegreeOfFreedom> localIndices;	// DOF-indices of all DOFs in trinangle
+  mtl::dense_vector<T> uh; 	
+
+  localIndices.resize(feSpace->getBasisFcts()->getNumber());
+  uh.change_dim(feSpace->getBasisFcts()->getNumber());
+
+  bool inside = mesh->findElInfoAtPoint(p, elInfo, lambda, NULL, NULL, NULL);
+  
+  if (inside) {
+    feSpace->getBasisFcts()->getLocalIndices(elInfo->getElement(), obj.getFeSpace()->getAdmin(), localIndices);
+    for (int l = 0; l < feSpace->getBasisFcts()->getNumber(); l++)
+      uh[l] = obj[localIndices[l]];
+    value = feSpace->getBasisFcts()->evalUh(lambda, uh);
+  }
+  delete elInfo;
+  return value;
+};
+
+// DOFView can be accessed by own method
+template<typename T >
+inline T evalAtPoint(const DOFView<T> &obj, WorldVector<double> &p, ElInfo* elInfo = NULL)
+{
+  return obj.evalAtPoint(p, elInfo);
+};
+
+// intrinsic types can return values directly
+template<typename T>
+inline T evalAtPoint(T &obj, WorldVector<double> &p, ElInfo* elInfo = NULL)
+{
+  return obj;
+};
+
+// AbstractFunctions with argument-type = WorldVector can be accessed directly
+template<typename T>
+inline T evalAtPoint(AbstractFunction<T, WorldVector<double> > &obj, WorldVector<double> &p, ElInfo* elInfo = NULL)
+{
+  return obj(p);
+};
+
+/// Type-Traits for value_type of Data-Structures
+/// ________________________________________________________________________________________________
+
+template<typename T, typename enable=void> struct ValueType { typedef T type; };
+template<typename T> struct ValueType<DOFVector<T> > { typedef T type; };
+template<typename Derived> struct ValueType<Derived, typename boost::enable_if<boost::is_base_of<DOFView<double>, Derived > >::type> { typedef double type; };
+template<typename Derived> struct ValueType<Derived, typename boost::enable_if<boost::is_base_of<DOFView<WorldVector<double> >, Derived > >::type> { typedef WorldVector<double> type; };
+template<typename Derived> struct ValueType<Derived, typename boost::enable_if<boost::is_base_of<AbstractFunction<double, WorldVector<double> >, Derived > >::type> { typedef double type; };
+template<typename Derived> struct ValueType<Derived, typename boost::enable_if<boost::is_base_of<AbstractFunction<WorldVector<double>, WorldVector<double> >, Derived > >::type> { typedef WorldVector<double> type; };
+  
+/// transformDOF by coords (independent of mesh and feSpace)
+/// ________________________________________________________________________________________________
+
+// result = vec
+template<typename TOut, typename Vector>
+inline void interpol_coords(Vector &vec, DOFVector<TOut> &result)
+{
+  typedef typename ValueType<Vector>::type T;
+  DOFVector<WorldVector<double> > coords(result.getFeSpace(), "coords");
+  result.getFeSpace()->getMesh()->getDofIndexCoords(result.getFeSpace(), coords);
+
+  DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+  DOFIterator<TOut> it_result(&result, USED_DOFS);
+  for (it_coords.reset(), it_result.reset(); !it_coords.end(); ++it_coords, ++it_result) {
+    *it_result = evalAtPoint<T>(vec, *it_coords);
+  }
+};
+
+// result = op(vec)
+template<typename TOut, typename Vector>
+inline void transformDOF_coords(Vector &vec,
+  DOFVector<TOut> &result,
+  AbstractFunction<TOut, typename ValueType<Vector>::type> *op)
+{
+  typedef typename ValueType<Vector>::type T;
+  DOFVector<WorldVector<double> > coords(result.getFeSpace(), "coords");
+  result.getFeSpace()->getMesh()->getDofIndexCoords(result.getFeSpace(), coords);
+
+  DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+  DOFIterator<TOut> it_result(&result, USED_DOFS);
+  for (it_coords.reset(), it_result.reset(); !it_coords.end(); ++it_coords, ++it_result) {
+    T value = evalAtPoint<T>(vec, *it_coords);
+    *it_result = (*op)(value);
+  }
+};
+
+// result = binary_op(vec1, vec2)
+template<typename TOut, typename Vector1, typename Vector2>
+inline void transformDOF_coords(Vector1 &vec1, Vector2 &vec2,
+  DOFVector<TOut> &result,
+  BinaryAbstractFunction<TOut, typename ValueType<Vector1>::type, 
+			       typename ValueType<Vector2>::type> *binary_op)
+{
+  typedef typename ValueType<Vector1>::type T1;
+  typedef typename ValueType<Vector2>::type T2;
+  DOFVector<WorldVector<double> > coords(result.getFeSpace(), "coords");
+  result.getFeSpace()->getMesh()->getDofIndexCoords(result.getFeSpace(), coords);
+
+  DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+  DOFIterator<TOut> it_result(&result, USED_DOFS);
+  for (it_coords.reset(), it_result.reset(); !it_coords.end(); ++it_coords, ++it_result) {
+    T1 value1 = evalAtPoint<T1>(vec1, *it_coords);
+    T2 value2 = evalAtPoint<T2>(vec2, *it_coords);
+    
+    *it_result = (*binary_op)(value1, value2);
+  }
+};
+
+// result = tertiary_op(vec1, vec2, vec3)
+template<typename TOut, typename Vector1, typename Vector2, typename Vector3>
+inline void transformDOF_coords(Vector1 &vec1, Vector2 &vec2, Vector3 &vec3,
+  DOFVector<TOut> &result,
+  TertiaryAbstractFunction<TOut, typename ValueType<Vector1>::type, 
+				 typename ValueType<Vector2>::type, 
+				 typename ValueType<Vector3>::type> *tertiary_op)
+{
+  typedef typename ValueType<Vector1>::type T1;
+  typedef typename ValueType<Vector2>::type T2;
+  typedef typename ValueType<Vector3>::type T3;
+  DOFVector<WorldVector<double> > coords(result.getFeSpace(), "coords");
+  result.getFeSpace()->getMesh()->getDofIndexCoords(result.getFeSpace(), coords);
+
+  DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+  DOFIterator<TOut> it_result(&result, USED_DOFS);
+  for (it_coords.reset(), it_result.reset(); !it_coords.end(); ++it_coords, ++it_result) {
+    T1 value1 = evalAtPoint<T1>(vec1, *it_coords);
+    T2 value2 = evalAtPoint<T2>(vec2, *it_coords);
+    T3 value3 = evalAtPoint<T3>(vec3, *it_coords);
+
+    *it_result = (*tertiary_op)(value1, value2, value3);
+  }
+};
+
+
+// result = quart_op(vec1, vec2, vec3, vec4)
+template<typename TOut, typename Vector1, typename Vector2, typename Vector3, typename Vector4>
+inline void transformDOF_coords(Vector1 &vec1, Vector2 &vec2, Vector3 &vec3, Vector4 &vec4,
+  DOFVector<TOut> &result,
+  QuartAbstractFunction<TOut, typename ValueType<Vector1>::type, 
+			      typename ValueType<Vector2>::type, 
+			      typename ValueType<Vector3>::type, 
+			      typename ValueType<Vector4>::type> *quart_op)
+{
+  typedef typename ValueType<Vector1>::type T1;
+  typedef typename ValueType<Vector2>::type T2;
+  typedef typename ValueType<Vector3>::type T3;
+  typedef typename ValueType<Vector4>::type T4;
+  DOFVector<WorldVector<double> > coords(result.getFeSpace(), "coords");
+  result.getFeSpace()->getMesh()->getDofIndexCoords(result.getFeSpace(), coords);
+
+  DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+  DOFIterator<TOut> it_result(&result, USED_DOFS);
+  for (it_coords.reset(), it_result.reset(); !it_coords.end(); ++it_coords, ++it_result) {
+    T1 value1 = evalAtPoint<T1>(vec1, *it_coords);
+    T2 value2 = evalAtPoint<T2>(vec2, *it_coords);
+    T3 value3 = evalAtPoint<T3>(vec3, *it_coords);
+    T4 value4 = evalAtPoint<T3>(vec4, *it_coords);
+
+    *it_result = (*quart_op)(value1, value2, value3, value4);
+  }
+};
+
+#endif // MY_VIEWS_H
diff --git a/extensions/VtuReader.h b/extensions/VtuReader.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b85e8f1de94d063b0acba226faeee8591708661
--- /dev/null
+++ b/extensions/VtuReader.h
@@ -0,0 +1,276 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ==  http://www.amdis-fem.org                                              ==
+// ==                                                                        ==
+// ============================================================================
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+
+/** \file VtuReader.h */
+
+#ifndef AMDIS_VTUREADER_H
+#define AMDIS_VTUREADER_H
+
+#include <cstring>
+#include "DOFVector.h"
+#include "Mesh.h"
+#include "boost/filesystem.hpp"
+#include "pugixml/src/pugixml.hpp"
+#include "kdtree_nanoflann.h"
+
+namespace AMDiS {
+
+  namespace VtuReader {
+    
+    /// Copies the values of a VTU-file to a DOF vector.
+    template<typename T>
+    inline void readValue(std::string filename,
+			  Mesh *mesh,
+			  DOFVector<T> *dofVector,
+			  std::string componentName);
+
+    /// Copies the values of a VTU-file to a vector of DOF vectors.
+    template<typename T>
+    inline void readValue(std::string filename,
+			  Mesh *mesh,
+			  std::vector<DOFVector<T>*> dofVectors,
+			  std::vector<std::string> componentNames);
+
+
+    namespace details {
+
+      // num_rows for scalar types
+      template<typename T>
+      size_t num_rows(T &v) {
+	return 1;
+      };
+      // for WorldVectors print 3 components
+      template<typename T>
+      size_t num_rows(WorldVector<T> &v) {
+	return static_cast<size_t>(v.getSize());
+      }
+      // num_rows for vector types
+      template<typename T>
+      size_t num_rows(std::vector<T> &v) {
+	return v.size();
+      };
+      template<typename T>
+      size_t num_rows(const std::vector<T> &v) {
+	return v.size();
+      };
+      template<typename T>
+      size_t num_rows(mtl::dense_vector<T> &v) {
+	return mtl::num_rows(v);
+      };
+      template<typename T>
+      size_t num_rows(const mtl::dense_vector<T> &v) {
+	return mtl::num_rows(v);
+      };
+
+      template<typename T>
+      struct LessPairEps
+      {
+	LessPairEps() : eps(1.e-7) {}
+	bool operator()(const std::pair<WorldVector<double>, T>& lhs, const std::pair<WorldVector<double>, T>& rhs) const
+	{
+	  return (lhs.first.getSize()==1 ? vertexi_compare1(lhs.first, rhs.first) :
+		    (lhs.first.getSize()==2 ? vertexi_compare2(lhs.first, rhs.first) :
+		      (lhs.first.getSize()==3 ? vertexi_compare3(lhs.first, rhs.first) : false)));
+	}
+	bool operator()(const std::pair<WorldVector<double>, T>& lhs, const WorldVector<double>& rhs) const
+	{
+	  return (lhs.first.getSize()==1 ? vertexi_compare1(lhs.first, rhs) :
+		    (lhs.first.getSize()==2 ? vertexi_compare2(lhs.first, rhs) :
+		      (lhs.first.getSize()==3 ? vertexi_compare3(lhs.first, rhs) : false)));
+	}
+	bool operator()(const WorldVector<double>& lhs, const std::pair<WorldVector<double>, T>& rhs) const
+	{
+	  return (lhs.getSize()==1 ? vertexi_compare1(lhs, rhs.first) :
+		    (lhs.getSize()==2 ? vertexi_compare2(lhs, rhs.first) :
+		      (lhs.getSize()==3 ? vertexi_compare3(lhs, rhs.first) : false)));
+	}
+	bool operator()(const WorldVector<double>& lhs, const WorldVector<double>& rhs) const
+	{
+	  return (lhs.getSize()==1 ? vertexi_compare1(lhs, rhs) :
+		    (lhs.getSize()==2 ? vertexi_compare2(lhs, rhs) :
+		      (lhs.getSize()==3 ? vertexi_compare3(lhs, rhs) : false)));
+	}
+      private:
+	double eps;
+
+	//returns true if vertex lhs is "smaller" than vertex rhs
+	//----------------------------------------< vertexi_compare1 >
+	bool vertexi_compare1(const WorldVector<double> lhs, const WorldVector<double> rhs) const {
+	  return (lhs[0]-rhs[0]>eps);
+	}
+
+	//----------------------------------------< vertexi_compare2 >
+	bool vertexi_compare2(const WorldVector<double> lhs, const WorldVector<double> rhs) const {
+	  return (lhs[0]-rhs[0]>eps)
+		|| (abs(lhs[0]-rhs[0])<=eps && lhs[1]-rhs[1]>eps);
+	}
+
+	//----------------------------------------< vertexi_compare3 >
+	bool vertexi_compare3(const WorldVector<double> lhs, const WorldVector<double> rhs) const {
+	  return (lhs[0]-rhs[0]>eps)
+		|| (abs(lhs[0]-rhs[0])<=eps && lhs[1]-rhs[1]>eps)
+		|| (abs(lhs[0]-rhs[0])<=eps && abs(lhs[1]-rhs[1])<=eps
+		&& lhs[2]-rhs[2]>eps);
+	}
+      };
+
+      
+      inline void string2pointList(std::string& input, std::vector<WorldVector<double> >& pointList)
+      {
+	int dow = Global::getGeo(WORLD);
+	int dowExplicit = 3;
+
+	std::vector<std::string> valueStringList;
+	std::stringstream ss(input);
+	std::string buf;
+	while (ss >> buf)
+	  valueStringList.push_back(buf);
+
+	pointList.clear();
+
+	std::vector<std::string>::iterator it;
+	size_t j = 0;
+	for (it = valueStringList.begin(); it != valueStringList.end();j++) {
+	  WorldVector<double> p;
+	  for (int i = 0; i < dowExplicit && it != valueStringList.end(); i++, it++)
+	    if (i < dow)
+	      p[i] = boost::lexical_cast<double>(*it);
+	  pointList.push_back(p);
+	}
+      }
+
+      template<typename T>
+      inline void string2valueList(std::string& input, std::vector<T>& valueList, int numComponent = 1, int numComponentMax = -1)
+      {
+	if (numComponentMax < 0)
+	  numComponentMax = numComponent;
+
+	std::vector<std::string> valueStringList;
+	std::stringstream ss(input);
+	std::string buf;
+	while (ss >> buf)
+	  valueStringList.push_back(buf);
+
+	valueList.clear();
+
+	std::vector<std::string>::iterator it;
+	for (it = valueStringList.begin(); it != valueStringList.end();) {
+	  std::vector<double> p;
+	  for (int i = 0; i < numComponentMax && it != valueStringList.end(); i++, it++)
+	    if (i < numComponent)
+	      p.push_back(boost::lexical_cast<double>(*it));
+	  T value; valueVector2type(p, value);
+	  valueList.push_back(value);
+	}
+      }
+
+
+      template<typename T>
+      inline void string2dataMap(std::string& strPoints, std::string& strValues, std::map<WorldVector<double>, T, LessPairEps<T> >& dataList, int numComponent = 1, int numComponentMax = -1)
+      {
+	int dow = Global::getGeo(WORLD);
+	int dowExplicit = 3;
+	if (numComponentMax < 0)
+	  numComponentMax = numComponent;
+	std::string buf;
+
+	std::vector<std::string> pointStringList;
+	std::stringstream ss1(strPoints);
+	while (ss1 >> buf)
+	  pointStringList.push_back(buf);
+
+	std::vector<std::string> valueStringList;
+	std::stringstream ss2(strValues);
+	while (ss2 >> buf)
+	  valueStringList.push_back(buf);
+
+	if (pointStringList.size()/dowExplicit != valueStringList.size()/numComponentMax)
+	  throw(std::runtime_error("Coordinates and values do not match! nPoints="
+				    + boost::lexical_cast<std::string>(pointStringList.size()/dowExplicit)
+				    + ", nValues="
+				    + boost::lexical_cast<std::string>(valueStringList.size()/numComponentMax)));
+
+	std::vector<std::string>::iterator it1, it2;
+	it1 = pointStringList.begin();
+	it2 = valueStringList.begin();
+	for (; it1 != pointStringList.end() && it2 != valueStringList.end();) {
+	  WorldVector<double> p;
+	  for (int i = 0; i < dowExplicit && it1 != pointStringList.end(); i++, it1++)
+	    if (i < dow)
+	      p[i] = boost::lexical_cast<double>(*it1);
+
+	  std::vector<double> v;
+	  for (int i = 0; i < numComponentMax && it2 != valueStringList.end(); i++, it2++)
+	    if (i < numComponent)
+	      v.push_back(boost::lexical_cast<double>(*it2));
+	  T value; valueVector2type(v, value);
+
+	  dataList[p] = value;
+	}
+      }
+
+      inline void valueVector2type(std::vector<double> p, double& value)
+      {
+	if (p.size() == 0)
+	  throw(std::runtime_error("Not enough data for assignment!\n"));
+	value = p[0];
+      }
+
+      inline void valueVector2type(std::vector<double> p, WorldVector<double>& value)
+      {
+	if (p.size() != Global::getGeo(WORLD))
+	  throw(std::runtime_error("Not enough data for assignment!\n"));
+	for (int i = 0; i < Global::getGeo(WORLD); i++)
+	  value[i] = p[i];
+      }
+
+      inline void valueVector2type(std::vector<double> p, std::vector<double>& value)
+      {
+	if (p.size() == 0)
+	  throw(std::runtime_error("Not enough data for assignment!\n"));
+	for (int i = 0; i < p.size(); i++)
+	  value.push_back(p[i]);
+      }
+
+
+      // find point in mesh using KD-tree structure
+      inline size_t getNearestIndex(experimental::KD_Tree& tree, WorldVector<double>& x)
+      {
+	// do a knn search
+	const size_t num_nnp = 1;
+	std::vector<size_t>   ret_indexes(num_nnp);
+	std::vector<double> out_dists_sqr(num_nnp);
+
+	nanoflann::KNNResultSet<double> resultSet(num_nnp);
+	resultSet.init(&ret_indexes[0], &out_dists_sqr[0] );
+
+	tree.index->findNeighbors(resultSet, x.begin(), nanoflann::SearchParams(10));
+	return ret_indexes[0];
+      }
+
+    } // end namespace details
+    
+  } // end namespace VtuReader
+  
+} // end namespace AMDiS
+
+#include "VtuReader.hh"
+
+#endif // AMDIS_VTUREADER_H
diff --git a/extensions/VtuReader.hh b/extensions/VtuReader.hh
new file mode 100644
index 0000000000000000000000000000000000000000..8187d2536643e9bee44e82683e718116a01a1750
--- /dev/null
+++ b/extensions/VtuReader.hh
@@ -0,0 +1,121 @@
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+/** \file VtuReader.hh */
+
+namespace AMDiS {
+
+  namespace VtuReader {
+    
+    /** \brief
+     * Copies the values of a VTU file to a DOF vector.
+     *
+     * The DOF vector must have been created by a corresponding mesh file. The
+     * function now reads the corresponding VTU file and
+     * copies the values to the correct positions in the DOF vector.
+     */
+    template<typename T>
+    void readValue(std::string filename,
+		    Mesh *mesh,
+		    DOFVector<T> *dofVector,
+		    std::string componentName)
+    {
+      std::vector<DOFVector<T>*> dofVectors; dofVectors.push_back(dofVector);
+      std::vector<std::string> componentNames; componentNames.push_back(componentName);
+
+      readValue(filename, mesh, dofVectors, componentNames);
+    }
+
+    template<typename T>
+    void readValue(std::string filename,
+		    Mesh *mesh,
+		    std::vector<DOFVector<T>*> dofVectors,
+		    std::vector<std::string> componentNames)
+    {
+      using namespace pugi;
+      using namespace VtuReader::details;
+
+      FUNCNAME("VtuReader::readValue()");
+
+      TEST_EXIT(filename != "")("Filename not specified!\n");
+      TEST_EXIT(mesh)("no mesh specified\n");
+      TEST_EXIT(dofVectors.size() > 0)("no DOF vectors specified\n");
+      TEST_EXIT(componentNames.size() > 0)("no componentName specified\n");
+
+
+      if(!boost::filesystem::exists(filename))
+	throw(std::runtime_error(filename + " does not exist!"));
+
+      xml_document vtu;
+      if(!vtu.load_file(filename.c_str()))
+	throw(std::runtime_error("Could not load vtu file! Error in xml structure."));
+
+      xml_node VTKFile = vtu.child("VTKFile");
+      xml_node UnstructuredGrid = VTKFile.child("UnstructuredGrid");
+      xml_node Piece = UnstructuredGrid.child("Piece");
+      xml_node PointData = Piece.child("PointData");
+      xml_node Points = Piece.child("Points");
+
+      std::string points = Points.child_value("DataArray");
+      typedef std::vector<WorldVector<double> > PL;
+      PL pointList;
+      string2pointList(points, pointList);
+
+      std::vector<std::vector<T> > valueList(dofVectors.size());
+      T test;
+
+      for (xml_node DataArray = PointData.child("DataArray"); DataArray; DataArray = DataArray.next_sibling("DataArray")) {
+	std::string Name = DataArray.attribute("Name").value();
+	for (size_t i = 0; i < componentNames.size(); i++) {
+	  if (Name == componentNames[i]) {
+	    std::string values = DataArray.last_child().value();
+	    int nComponents = -1;
+	    if (DataArray.attribute("NumberOfComponents"))
+	      nComponents = DataArray.attribute("NumberOfComponents").as_int();
+	    if (nComponents != -1 && num_rows(test) > nComponents)
+	      throw(std::runtime_error("Can not store values in DOFVector with given value type. Too many components!"));
+	    string2valueList(values, valueList[i], num_rows(test), nComponents);
+	    break;
+	  }
+	}
+      }
+      for (size_t i = 0; i < dofVectors.size(); i++) {
+	if (valueList[i].size() == 0)
+	  throw(std::runtime_error("no values found for component name '"+componentNames[i]+"'!"));
+	if (pointList.size() != valueList[i].size())
+	  throw(std::runtime_error("Coordinates and values["+boost::lexical_cast<std::string>(i)+"] do not match!"));
+      }
+
+      DOFVector<WorldVector<double> > coords(dofVectors[0]->getFeSpace(), "coords");
+      dofVectors[0]->getFeSpace()->getMesh()->getDofIndexCoords(dofVectors[0]->getFeSpace(), coords);
+
+      experimental::KD_Tree tree(Global::getGeo(WORLD), pointList, 10);
+      tree.index->buildIndex();
+
+      DOFIterator<WorldVector<double> > it_coords(&coords, USED_DOFS);
+      std::vector<DOFIterator<T>*> it_results;
+      for (size_t i = 0; i < dofVectors.size(); i++) {
+	it_results.push_back(new DOFIterator<T>(dofVectors[i], USED_DOFS));
+	it_results[i]->reset();
+      }
+      for (it_coords.reset(); !it_coords.end(); ++it_coords) {
+	size_t idx = getNearestIndex(tree, *it_coords);
+
+	for (size_t i = 0; i < dofVectors.size(); i++) {
+	  if (valueList[i].size() > idx)
+	    *(*it_results[i]) = valueList[i][idx];
+	  (*it_results[i])++;
+	}
+      }
+    }
+  } // end namespace VtuReader
+  
+} // end namespace
diff --git a/extensions/base_problems/BaseProblem.h b/extensions/base_problems/BaseProblem.h
new file mode 100644
index 0000000000000000000000000000000000000000..443a880436127f54b17208bd14ff4cb5b84158e5
--- /dev/null
+++ b/extensions/base_problems/BaseProblem.h
@@ -0,0 +1,184 @@
+/** \file BaseProblem.h */
+
+#ifndef BASE_PROBLEM_H
+#define BASE_PROBLEM_H
+
+#include "AMDiS.h"
+#include "time/RosenbrockStationary.h"
+#include "CouplingTimeInterface.h"
+
+using namespace AMDiS;
+
+const Flag MESH_ADOPTED = 1<<2;
+const Flag DATA_ADOPTED = 1<<3;
+
+template<typename ProblemType=ProblemStat>
+class BaseProblem : public ProblemIterationInterface,
+		    public ProblemInstatBase
+{
+public:
+
+  BaseProblem(const std::string &name_);
+  ~BaseProblem()
+  {
+    delete prob;
+  }
+
+  /// Initialisation of the problem.
+  virtual void initialize(Flag initFlag,
+                  ProblemStat *adoptProblem = NULL,
+                  Flag adoptFlag = INIT_NOTHING);
+
+  /// Initialisation of DOFVectors and AbstractFunctions,
+  /// is called in \ref initTimeInteface after feSpace and mesh are initialized
+  virtual void initData() {};
+
+  /// calls \ref initData, \ref fillOperators and \ref fillBoundaryConditions in this ordering
+  virtual void initTimeInterface()
+  { FUNCNAME("BaseProblem::initTimeInterface()");
+    initData();
+    fillOperators();
+    fillBoundaryConditions();
+  };
+
+  /// read solution DOFVectors from .arh or .dat files
+  virtual Flag initDataFromFile(AdaptInfo *adaptInfo);
+
+  /// calls \ref initDataFromFile
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo)
+  { FUNCNAME("BaseProblem::solveInitialProblem()");
+    Flag initFlag = initDataFromFile(adaptInfo);
+  };
+
+  /// calls \ref writeFiles
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo)
+  { FUNCNAME("BaseProblem::transferInitialSolution()");
+    oldMeshChangeIdx = getMesh()->getChangeIndex();
+    writeFiles(adaptInfo, false);
+  };
+
+  /// This method is called before \ref beginIteration, \ref oneIteration and \ref endIteration.
+  virtual void initTimestep(AdaptInfo *adaptInfo) {};
+
+  /// calls \ref writeFiles
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  virtual void beginIteration(AdaptInfo *adaptInfo);
+  virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION);
+  virtual void endIteration(AdaptInfo *adaptInfo);
+
+  /// Calls writeFiles of the problem
+  virtual void writeFiles(AdaptInfo *adaptInfo, bool force)
+  { FUNCNAME("BaseProblem::writeFiles()");
+    prob->writeFiles(adaptInfo, force);
+  };
+  
+  // getting methods
+
+  /// pointer to the solution of the problem
+  SystemVector *getSolution()
+  {
+    return prob->getSolution();
+  }
+
+  /// pointer to the mesh of the problem
+  inline Mesh* getMesh(int comp = 0) 
+  {
+    return prob->getMesh(comp); 
+  }
+
+  /// pointer to the feSpace of the problem
+  inline FiniteElemSpace* getFeSpace(int comp = 0) 
+  {
+    return prob->getFeSpace(comp); 
+  }
+
+  /// name of the baseBroblem
+  std::string getName()
+  {
+    return name;
+  };
+
+  int getNumProblems() 
+  {
+    return 1;
+  };
+  
+  int getNumComponents()
+  {
+    return prob->getNumComponents();
+  };
+
+  ProblemType *getProblem(int number= 0)
+  {
+    if (number<0 || number >= getNumProblems())
+      throw(std::runtime_error("problem with given number does not exist"));
+    if (number == 0)
+      return prob;
+  };
+
+  ProblemType *getProblem(std::string name)
+  {
+    if (name == "prob")
+      return prob;
+    else
+      throw(std::runtime_error("problem with given name '" + name + "' does not exist"));
+  };
+
+  // setting methods
+
+  void setAssembleMatrixOnlyOnce_butTimestepChange(int i, int j)
+  {
+    fixedMatrixTimestep.push_back(std::make_pair(i,j));
+  }
+
+  void setNumberOfTimesteps(int nTimesteps_)
+  {
+    nTimesteps= nTimesteps_;
+  }
+
+  void serialize(std::ostream&) {};
+  void deserialize(std::istream&) {};
+
+  /// method where operators are added to the problem
+  virtual void fillOperators() {};
+  
+  /// method where boundary conditions are added to the problem
+  virtual void fillBoundaryConditions() {};
+
+  /// classical backward-euler time-discretization
+  void addTimeOperator(ProblemStat *prob, int i, int j);
+  
+  /// for rosenbrock-problems a special time-operator can be added
+  void addTimeOperator(RosenbrockStationary *prob, int i, int j);
+  
+protected:
+
+  ProblemType *prob;
+
+  /// catch errors and exceptions in solve-block and continue with last iteration on failure
+  /// standard: false
+  bool secureIteration; 
+
+  /// dimension of the mesh (set in \ref initialize(...) )
+  unsigned dim;
+  
+  /// dimension of world (set in constructur)
+  unsigned dow;
+
+  int nTimesteps;
+  int oldMeshChangeIdx;
+
+  double oldTimestep;
+
+private:
+
+  std::vector<std::pair<int,int> > fixedMatrixTimestep;
+
+};
+
+#include "BaseProblem.hh"
+
+typedef BaseProblem<ProblemStat> StandardBaseProblem;
+
+#endif // BASE_PROBLEM_H
diff --git a/extensions/base_problems/BaseProblem.hh b/extensions/base_problems/BaseProblem.hh
new file mode 100644
index 0000000000000000000000000000000000000000..15f69de7ba0de9e63a3985266d31a95999bf8e3e
--- /dev/null
+++ b/extensions/base_problems/BaseProblem.hh
@@ -0,0 +1,213 @@
+using namespace AMDiS;
+
+template<typename ProblemType>
+BaseProblem<ProblemType>::BaseProblem(const std::string &name_) :
+  ProblemInstatBase(name_,NULL),
+  prob(NULL),
+  secureIteration(false),
+  oldMeshChangeIdx(0),
+  nTimesteps(-1),
+  dim(1),
+  dow(1),
+  oldTimestep(0.0)
+{
+  // create basic problems
+  prob = new ProblemType(name + "->space");
+  dow = Global::getGeo(WORLD);
+
+  Initfile::get(name + "->secure iteration", secureIteration);
+};
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::initialize(Flag initFlag,
+                              ProblemStat *adoptProblem,
+                              Flag adoptFlag)
+{ FUNCNAME("BaseProblem::initialize()");
+
+  prob->initialize(initFlag, adoptProblem, adoptFlag);
+  dim = getMesh()->getDim();
+};
+
+
+template<typename ProblemType>
+Flag BaseProblem<ProblemType>::initDataFromFile(AdaptInfo *adaptInfo)
+{ FUNCNAME("BaseProblem::initDataFromFile()");
+
+  Flag initFlag;
+  bool readDataFromFile = false, readArhFiles = false, readDatFiles = false;
+  Initfile::get(name + "->read data from file", readDataFromFile, 2);
+  if (!readDataFromFile)
+    return initFlag;
+  
+  Initfile::get(name + "->read arh files", readArhFiles, 2);
+  Initfile::get(name + "->read dat files", readDatFiles, 2);
+  if (readArhFiles && readDatFiles) {
+    WARNING("You can not read data from both formats, .arh and .dat! The .arh-format is selected.\n");
+  }
+
+  std::string data_file="", phase_file="";
+
+  // read data and mesh from arh-files/dat-files
+  MSG("read data from file...\n");
+  if (readArhFiles) {
+    Initfile::get(name + "->data file", data_file);
+    if (data_file.size() == 0) return initFlag;
+    if (!file_exists(data_file))
+      throw(std::runtime_error("The file '" + data_file + "' does not exist!"));
+    
+    std::vector<DOFVector<double>*> solutions;
+    for (size_t i = 0; i < prob->getNumComponents(); i++)
+      solutions.push_back(prob->getSolution()->getDOFVector(i));
+    ArhReader::read(data_file, prob->getMesh(), solutions);
+  } else if(readDatFiles) {
+    bool preserveMacroFileInfo = false;
+    Parameters::get(prob->getMesh()->getName() + "->preserve macroFileInfo", preserveMacroFileInfo);
+    if (prob->getMesh()->getMacroFileInfo() == NULL || !preserveMacroFileInfo)
+      throw(std::runtime_error("Yout have to set the flag 'mesh_name->preserve macroFileInfo' to 'true' ("+boost::lexical_cast<std::string>(preserveMacroFileInfo)+"), in order to read .dat-files"));
+    
+    std::string filename = "";
+    for (size_t i = 0; i < prob->getNumComponents(); i++) {
+      Parameters::get(name + "->value file["+boost::lexical_cast<std::string>(i)+"]",filename);
+      if (!file_exists(filename))
+	throw(std::runtime_error("The file '" + filename + "'does not exist!"));
+      ValueReader::readValue(filename,prob->getMesh(),prob->getSolution()->getDOFVector(i),prob->getMesh()->getMacroFileInfo());
+    }
+  } else
+    throw(std::runtime_error("Parameter 'read data from file' set to 'true', but no input format specified!"));
+  
+  initFlag.setFlag(DATA_ADOPTED);
+  initFlag.setFlag(MESH_ADOPTED);
+
+  return initFlag;
+};
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::beginIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("BaseProblem::beginIteration()");
+	
+  MSG("\n");
+  MSG(("[[ <"+name+"> iteration ]]\n").c_str());
+    
+  // assemble some blocks only once, if some conditions are fullfilled
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  bool fixedMatrixCell = false;
+  #else
+  bool fixedMatrixCell = adaptInfo->getTimestepNumber() > 0
+    && std::abs(adaptInfo->getTimestep() - oldTimestep) < DBL_TOL
+    && oldMeshChangeIdx == getMesh()->getChangeIndex();
+  #endif
+  for(size_t i = 0; i < fixedMatrixTimestep.size(); ++i) {
+    prob->setAssembleMatrixOnlyOnce(
+      fixedMatrixTimestep[i].first, 
+      fixedMatrixTimestep[i].second,
+      fixedMatrixCell);
+  }
+};
+
+
+template<typename ProblemType>
+Flag BaseProblem<ProblemType>::oneIteration(AdaptInfo *adaptInfo, 
+                                Flag toDo) 
+{ FUNCNAME("BaseProblem::oneIteration()");
+
+  Flag flag, markFlag;
+  
+  if (toDo.isSet(MARK))
+    markFlag = prob->markElements(adaptInfo);
+  else
+    markFlag = 3;
+
+  // refine
+  if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_REFINED))
+    flag = prob->refineMesh(adaptInfo);  
+  // coarsen
+  if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_COARSENED))
+    flag |= prob->coarsenMesh(adaptInfo);
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  MPI::COMM_WORLD.Barrier();
+  #endif
+
+  #ifndef NONLIN_PROBLEM
+  if (toDo.isSet(BUILD)) {    
+    prob->getSolver()->setMultipleRhs(false);
+    prob->buildAfterCoarsen(adaptInfo, markFlag, true, true);
+  }
+  #endif
+
+  if (toDo.isSet(SOLVE)) {
+    if (secureIteration) {
+      try {
+	prob->solve(adaptInfo);
+      } catch(std::exception &e) {
+	WARNING(("Could not solve system. Simulation will be stoped here! ERROR: "
+	  + std::string(e.what()) + "\n").c_str());
+	adaptInfo->setTime(adaptInfo->getEndTime());
+	adaptInfo->setTimestepNumber(adaptInfo->getNumberOfTimesteps());
+	return flag;
+      } catch(...) {
+	WARNING("Could not solve system. Simulation will be stoped here! Unknown ERROR\n");
+	adaptInfo->setTime(adaptInfo->getEndTime());
+	adaptInfo->setTimestepNumber(adaptInfo->getNumberOfTimesteps());
+	return flag;
+      }
+    } else {
+      prob->solve(adaptInfo);
+    }
+  }
+
+  if (toDo.isSet(ESTIMATE))
+    prob->estimate(adaptInfo);
+
+  oldTimestep = adaptInfo->getTimestep();
+  oldMeshChangeIdx = getMesh()->getChangeIndex();
+
+  return flag;
+};
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::endIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("BaseProblem::endIteration()");
+	
+  MSG("\n");
+  MSG(("[[ end of <"+name+"> iteration ]]\n").c_str());
+};
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("BaseProblem::closeTimestep()");
+
+  int outputPeriod = 1;
+  Initfile::get("user parameter->write every ith timestep", outputPeriod);
+  if (adaptInfo->getTimestepNumber() % outputPeriod == 0
+    && adaptInfo->getStartTime() < adaptInfo->getEndTime()) {
+    writeFiles(adaptInfo, false);
+  }
+};
+
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::addTimeOperator(ProblemStat *prob, int i, int j)
+{ FUNCNAME("BaseProblem::addTimeOperator()");
+
+  Operator *op = new Operator(prob->getFeSpace(i), prob->getFeSpace(j));
+    op->addZeroOrderTerm(new Simple_ZOT);
+  Operator *opRhs = new Operator(prob->getFeSpace(i));
+    opRhs->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(j), NULL));
+
+  prob->addMatrixOperator(op, i, j, getInvTau(), getInvTau());
+  prob->addVectorOperator(opRhs, i, getInvTau(), getInvTau());
+};
+
+
+template<typename ProblemType>
+void BaseProblem<ProblemType>::addTimeOperator(RosenbrockStationary *prob, int i, int j)
+{ FUNCNAME("BaseProblem::addTimeOperator()");
+
+  prob->addTimeOperator(i,j);
+};
diff --git a/extensions/base_problems/CahnHilliard.cc b/extensions/base_problems/CahnHilliard.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1ce6f74ee6c716ebf0016a75145ff332a54c4512
--- /dev/null
+++ b/extensions/base_problems/CahnHilliard.cc
@@ -0,0 +1,193 @@
+#include "CahnHilliard.h"
+#include "Views.h"
+#include "SignedDistFunctors.h"
+#include "PhaseFieldConvert.h"
+
+using namespace AMDiS;
+
+CahnHilliard::CahnHilliard(const std::string &name_) :
+  super(name_),
+  useMobility(false),
+  doubleWell(0),
+  gamma(1.0),
+  eps(0.1),
+  minusEps(-0.1),
+  epsInv(10.0),
+  minusEpsInv(-10.0),
+  epsSqr(0.01),
+  minusEpsSqr(-0.01),
+  reinit(NULL)
+{
+  // parameters for CH
+  Parameters::get(name + "->use mobility", useMobility); // mobility
+  Parameters::get(name + "->gamma", gamma); // mobility
+  Parameters::get(name + "->epsilon", eps); // interface width
+  
+  // type of double well: 0= [0,1], 1= [-1,1]
+  Parameters::get(name + "->double-well type", doubleWell); 
+
+  // transformation of the parameters
+  minusEps = -eps;
+  epsInv = 1.0/eps;
+  minusEpsInv = -epsInv;
+  epsSqr = sqr(eps);
+  minusEpsSqr = -epsSqr;
+}
+
+
+CahnHilliard::~CahnHilliard() 
+{ FUNCNAME("CahnHilliard::~CahnHilliard()");
+
+  if (reinit)
+    delete reinit;
+}
+
+
+void CahnHilliard::initData()
+{ FUNCNAME("CahnHilliard::initData()");
+
+  // create instance redistancing class
+  reinit = new HL_SignedDistTraverse("reinit", getMesh()->getDim());
+  
+  super::initData();
+}
+
+
+void CahnHilliard::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("CahnHilliard::solveInitialProblem()");
+
+  Flag initFlag = initDataFromFile(adaptInfo);
+
+  if (!initFlag.isSet(DATA_ADOPTED)) {
+    int initialInterface = 0;
+    Initfile::get(name + "->initial interface", initialInterface);
+    double initialEps = eps;
+    Initfile::get(name + "->initial epsilon", initialEps);
+
+    if (initialInterface == 0) {
+      /// horizontale Linie
+      double a= 0.0, dir= -1.0;
+      Initfile::get(name + "->line->pos", a);
+      Initfile::get(name + "->line->direction", dir);
+      prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, dir));
+    }
+    else if (initialInterface == 1) {
+      /// schraege Linie
+      double theta = m_pi/4.0;
+      prob->getSolution()->getDOFVector(0)->interpol(new PlaneRotation(0.0, theta, 1.0));
+      transformDOFInterpolation(prob->getSolution()->getDOFVector(0),new PlaneRotation(0.0, -theta, -1.0), new AMDiS::Min<double>);
+    }
+    else if (initialInterface == 2) {
+      /// Ellipse
+      double a= 1.0, b= 1.0;
+      Initfile::get(name + "->ellipse->a", a);
+      Initfile::get(name + "->ellipse->b", b);
+      prob->getSolution()->getDOFVector(0)->interpol(new Ellipse(a,b));
+    }
+    else if (initialInterface == 3) {
+      /// zwei horizontale Linien
+      double a= 0.75, b= 0.375;
+      Initfile::get(name + "->lines->pos1", a);
+      Initfile::get(name + "->lines->pos2", b);
+      prob->getSolution()->getDOFVector(0)->interpol(new Plane(a, -1.0));
+      transformDOFInterpolation(prob->getSolution()->getDOFVector(0),new Plane(b, 1.0), new AMDiS::Max<double>);
+    }
+    else if (initialInterface == 4) {
+      /// Kreis
+      double radius= 1.0;
+      Initfile::get(name + "->kreis->radius", radius);
+      prob->getSolution()->getDOFVector(0)->interpol(new Circle(radius));
+    } else if (initialInterface == 5) {
+      /// Rechteck
+      double width = 0.5;
+      double height = 0.3;
+      WorldVector<double> center; center.set(0.5);
+      Initfile::get(name + "->rectangle->width", width);
+      Initfile::get(name + "->rectangle->height", height);
+      Initfile::get(name + "->rectangle->center", center);
+      prob->getSolution()->getDOFVector(0)->interpol(new Rectangle(width, height, center));
+    }
+
+    /// create phase-field from signed-dist-function
+    if (doubleWell == 0) {
+      transformDOF(prob->getSolution()->getDOFVector(0),
+        new SignedDistToPhaseField(initialEps));
+    } else {
+      transformDOF(prob->getSolution()->getDOFVector(0),
+        new SignedDistToCh(initialEps));
+    }
+  }
+}
+
+
+void CahnHilliard::fillOperators()
+{ FUNCNAME("CahnHilliard::fillOperators()");
+  MSG("CahnHilliard::fillOperators()\n");
+
+  // c
+  Operator *opChMnew = new Operator(prob->getFeSpace(0),prob->getFeSpace(0));
+  opChMnew->addZeroOrderTerm(new Simple_ZOT);
+  Operator *opChMold = new Operator(prob->getFeSpace(0),prob->getFeSpace(0));
+  opChMold->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0)));
+  // -nabla*(grad(c))
+  Operator *opChL = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
+  opChL->addSecondOrderTerm(new Simple_SOT);
+  
+  // div(M(c)grad(mu)), with M(c)=gamma/4*(c^2-1)^2
+  Operator *opChLM = new Operator(prob->getFeSpace(0),prob->getFeSpace(1));
+  if (useMobility) {
+    if (doubleWell == 0)
+      opChLM->addSecondOrderTerm(new VecAtQP_SOT(
+	prob->getSolution()->getDOFVector(0),
+	new MobilityCH0(gamma)));
+    else
+      opChLM->addSecondOrderTerm(new VecAtQP_SOT(
+	prob->getSolution()->getDOFVector(0),
+	new MobilityCH1(gamma)));
+  } else
+    opChLM->addSecondOrderTerm(new Simple_SOT(gamma));
+  
+  // -2*c_old^3 + 3/2*c_old^2
+  Operator *opChMPowExpl = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
+  opChMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(
+    prob->getSolution()->getDOFVector(0),
+    new Pow3Functor(-2.0)));
+  if (doubleWell == 0) {
+    opChMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(
+      prob->getSolution()->getDOFVector(0),
+      new Pow2Functor(3.0/2.0)));
+  }
+
+  // -3*c_old^2 * c
+  Operator *opChMPowImpl = new Operator(prob->getFeSpace(1),prob->getFeSpace(0));
+  opChMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(
+    prob->getSolution()->getDOFVector(0),
+    new Pow2Functor(-3.0)));
+  if (doubleWell == 0) {
+    opChMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(
+      prob->getSolution()->getDOFVector(0),
+      new AMDiS::Factor<double>(3.0)));
+    opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(-0.5));
+  } else {
+    opChMPowImpl->addZeroOrderTerm(new Simple_ZOT(1.0));
+  }
+  
+  // dt(c) = laplace(mu) - u*grad(c)
+  // -----------------------------------
+  prob->addMatrixOperator(*opChMnew,0,0, getInvTau()); /// < phi*c/tau , psi >
+  prob->addMatrixOperator(*opChLM,0,1);                /// < phi*grad(mu) , grad(psi) >
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(*opChMold,0, getInvTau());   /// < phi*c^old/tau , psi >
+  
+//   setAssembleMatrixOnlyOnce_butTimestepChange(0,0);
+
+  // mu + eps^2*laplace(c) + c - 3*(c_old^2)*c = -2*c_old^3 [+ BC]
+  // ----------------------------------------------------------------------
+  prob->addMatrixOperator(*opChMPowImpl,1,0);          /// < -3*phi*c*c_old^2 , psi >
+  prob->addMatrixOperator(*opChL,1,0, &minusEpsSqr);   /// < -eps^2*phi*grad(c) , grad(psi) >
+  prob->addMatrixOperator(*opChMnew,1,1);              /// < phi*mu , psi >
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(*opChMPowExpl,1);            /// < -2*phi*c_old^3 , psi >
+
+//   setAssembleMatrixOnlyOnce_butTimestepChange(1,1);
+}
diff --git a/extensions/base_problems/CahnHilliard.h b/extensions/base_problems/CahnHilliard.h
new file mode 100644
index 0000000000000000000000000000000000000000..abff846b159de9a3c016b3731859a89823264bd5
--- /dev/null
+++ b/extensions/base_problems/CahnHilliard.h
@@ -0,0 +1,141 @@
+/** \file CahnHilliard.h */
+
+#ifndef CAHN_HILLIARD_H
+#define CAHN_HILLIARD_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+#include "ExtendedProblemStat.h"
+#include "HL_SignedDistTraverse.h"
+
+using namespace AMDiS;
+
+class CahnHilliard : public BaseProblem<ExtendedProblemStat>
+{
+public: // definition of types
+
+  typedef BaseProblem<ExtendedProblemStat> super;
+
+public: // public methods
+
+  CahnHilliard(const std::string &name_);
+  ~CahnHilliard();
+
+  virtual void initData();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  double getEpsilon() { return eps; }
+  int getDoubleWellType() { return doubleWell; }
+
+protected: // protected methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions() {}
+
+protected: // protected variables
+
+  HL_SignedDistTraverse *reinit;
+
+  bool useMobility;
+
+  unsigned dim;
+
+  int doubleWell;
+
+  double gamma;
+  double eps;
+  double minusEps;
+  double epsInv;
+  double minusEpsInv;
+  double epsSqr;
+  double minusEpsSqr;
+};
+
+
+/** \brief
+ * Abstract function for Cahn-Hilliard mobility
+ */
+class MobilityCH0 : public AbstractFunction<double,double>
+{
+  public:
+    MobilityCH0(double gamma_=1.0) : 
+      AbstractFunction<double,double>(4), 
+      gamma(gamma_),
+      delta(1.e-6) { }
+    double operator()(const double &ch) const 
+    {
+      double phase = std::max(0.0, std::min(1.0, ch));
+      double mobility = 0.25*sqr(phase)*sqr(phase-1.0);
+      return gamma * std::max(mobility, delta);
+    }
+
+  protected:
+    double gamma;
+    double delta;
+};
+
+class MobilityCH1 : public AbstractFunction<double,double>
+{
+  public:
+    MobilityCH1(double gamma_=1.0) :
+      AbstractFunction<double,double>(4),
+      gamma(gamma_),
+      delta(1.e-6) { }
+    double operator()(const double &ch) const
+    {
+      double phase = std::max(-1.0, std::min(1.0, ch));
+      double mobility = 0.25*sqr(sqr(phase)-1.0);
+      return gamma * std::max(mobility, delta);
+    }
+
+  protected:
+    double gamma;
+    double delta;
+};
+
+class ScaleFunctor : public AbstractFunction<double,double>
+{
+  public:
+    ScaleFunctor(double factor_=1.0) :
+      AbstractFunction<double,double>(1),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * ch;
+    }
+
+  protected:
+    double factor;
+};
+
+class Pow2Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow2Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(2),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch);
+    }
+
+  protected:
+    double factor;
+};
+
+class Pow3Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow3Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(3),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch) * ch;
+    }
+
+  protected:
+    double factor;
+};
+
+#endif // CAHN_HILLIARD_H
diff --git a/extensions/base_problems/DiffuseDomainFsi.cc b/extensions/base_problems/DiffuseDomainFsi.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0b034703054357566410782a94c36ee559191111
--- /dev/null
+++ b/extensions/base_problems/DiffuseDomainFsi.cc
@@ -0,0 +1,245 @@
+#include "DiffuseDomainFsi.h"
+
+using namespace std;
+using namespace AMDiS;
+
+DiffuseDomainFsi::DiffuseDomainFsi(const std::string &name_) :
+  super(name_),
+  phase(NULL),
+  phaseInv(NULL),
+  velocity(NULL),
+  displacement(NULL),
+  beta(1.0),
+  epsilon(1.e-1),
+  alpha(3.0),
+  mu(1.0),
+  viscosity(1.0),
+  density(1.0),
+  lambda(1.0),
+  rho(1.0),
+  fileWriterPhase(NULL),
+  fileWriterVelocity(NULL),
+  fileWriterDisplacement(NULL)
+{
+  
+  Parameters::get(name + "->beta", beta);
+  Parameters::get(name + "->epsilon", epsilon);
+  Parameters::get(name + "->alpha", alpha);
+
+  // parameters for navier-stokes
+  Initfile::get(name + "->viscosity", viscosity);
+  Initfile::get(name + "->density", density);
+  // parameters for linear elasticity
+  Parameters::get(name + "->mu", mu);
+  Parameters::get(name + "->lambda", lambda);
+  Parameters::get(name + "->rho", rho);
+};
+
+DiffuseDomainFsi::~DiffuseDomainFsi()
+{
+  if (fileWriterPhase != NULL)
+    delete fileWriterPhase;
+  if (fileWriterVelocity != NULL)
+    delete fileWriterVelocity;
+  if (fileWriterDisplacement != NULL)
+    delete fileWriterDisplacement;
+}
+
+void DiffuseDomainFsi::initData()
+{
+  super::initData();
+
+  phaseInv = new DOFVector<double>(getFeSpace(dow+1), "phaseInv");
+  velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
+  displacement = new DOFVector<WorldVector<double> >(getFeSpace(dow+1), "displacement");
+  
+  dbc_factor = beta/pow(epsilon, alpha);
+  MSG_DBG("dbc_factor = %f\n", dbc_factor);
+  pressure_factor = -(lambda+(2.0/3.0)*mu);
+  MSG_DBG("pressure_factor = %f\n", pressure_factor);
+}
+
+
+void DiffuseDomainFsi::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("DiffuseDomainFsi::transferInitialSolution()");
+
+  fileWriterPhase = new FileWriter(name + "->phase->output", getFeSpace()->getMesh(), phase);
+  fileWriterVelocity = new FileVectorWriter(name + "->velocity->output", getFeSpace()->getMesh(), velocity);
+  fileWriterDisplacement = new FileVectorWriter(name + "->displacement->output", getFeSpace()->getMesh(), displacement);
+
+  super::transferInitialSolution(adaptInfo);
+  transformDOF(1.0, phase, phaseInv, new Subtract<double>);
+
+  calcVelocity();
+  calcDisplacement();
+
+  for (int i = 0; i < prob->getNumComponents(); i++)
+    prob->setExactSolution(prob->getSolution()->getDOFVector(i), i);
+
+  writeFiles(adaptInfo, false);
+
+  // initial parameters for detecting mesh changes
+  oldMeshChangeIdx = getMesh()->getChangeIndex();
+}
+
+
+void DiffuseDomainFsi::closeTimestep(AdaptInfo *adaptInfo)
+{
+  calcVelocity();
+  calcDisplacement();
+  
+  super::closeTimestep(adaptInfo);
+}
+
+
+void DiffuseDomainFsi::fillOperators()
+{ FUNCNAME("DiffuseDomainFsi::fillOperators()");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (size_t i = 0; i < dow; i++)
+    vel[i] = prob->getSolution()->getDOFVector(i);
+
+  TEST_EXIT(phase != NULL && phaseInv != NULL)("PhaseField is not set!\n");
+
+  for (size_t i = 0; i < dow; ++i) {
+    // time-derivative
+    // ===============
+    
+    /// < (1/tau)*u'_i , psi >
+    Operator *opTime = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opTime->addTerm(new Simple_ZOT(density));
+    prob->addMatrixOperator(*opTime, i, i, getInvTau());
+    /// < (1/tau)*u_i^old , psi >
+    Operator *opTimeOld = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opTimeOld->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(i), new Factor<double>(density)));
+    prob->addVectorOperator(*opTimeOld, i, getInvTau());
+
+    /// < (1/tau)*(1-phase)*eta_i , psi >
+    Operator *opTimeE = new Operator(getFeSpace(dow+1+i), getFeSpace(dow+1+i));
+    opTimeE->addTerm(new VecAtQP_ZOT(phaseInv));
+    prob->addMatrixOperator(*opTimeE, dow+1+i, dow+1+i, getInvTau(), getInvTau());
+    /// < (1/tau)*(1-phase)*eta_i^old , psi >
+    Operator *opTimeEOld = new Operator(getFeSpace(i+dow));
+    opTimeEOld->addTerm(new Vec2AtQP_ZOT(phaseInv, prob->getSolution()->getDOFVector(dow+1+i)));
+    prob->addVectorOperator(*opTimeEOld, dow+1+i, getInvTau(), getInvTau());
+    
+    /// < (1-phase)*u , psi >
+    Operator *opU = new Operator(getFeSpace(dow+1+i), getFeSpace(i));
+    opU->addTerm(new Phase_ZOT(phaseInv, -1.0));
+    prob->addMatrixOperator(*opU, dow+1+i, dow+1+i);
+    
+    // nonlinear terms
+    // ===============
+    
+    /// < u^old*grad(u_i^old) , psi >
+    Operator *opUGradU0 = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradU0->addTerm(new WorldVector_FOT(velocity, -density), GRD_PHI);
+    opUGradU0->setUhOld(prob->getSolution()->getDOFVector(i));
+    if (nonLinTerm == 0)
+      prob->addVectorOperator(*opUGradU0, i);
+
+    if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU1 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU1->addTerm(new PartialDerivative_ZOT(
+          prob->getSolution()->getDOFVector(i), j, density));
+        prob->addMatrixOperator(*opUGradU1, i, j);
+      }
+    } else if (nonLinTerm == 2) {
+      /// < u^old*grad(u'_i) , psi >
+      for(unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU2 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU2->addTerm(new VecAndPartialDerivative_FOT(
+          prob->getSolution()->getDOFVector(j), j, density), GRD_PHI);
+        prob->addMatrixOperator(*opUGradU2, i, i);
+      }
+    }
+
+    // ====================
+
+    /// < u^old*grad(u_i^old) , psi >
+    Operator *opUGradE0 = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow+1+i));
+    opUGradE0->addTerm(new WorldVecPhase_FOT(phaseInv, vel), GRD_PHI);
+    opUGradE0->setUhOld(prob->getSolution()->getDOFVector(dow+1+i));
+    if (nonLinTerm == 0)
+      prob->addVectorOperator(*opUGradE0, dow+1+i);
+
+    if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (size_t j = 0; j < dow; ++j) {
+        Operator *opUGradE1 = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow+1+i));
+        opUGradE1->addTerm(new VecAndPartialDerivative_ZOT(
+          phaseInv,
+          prob->getSolution()->getDOFVector(dow+1+i), j));
+        prob->addMatrixOperator(*opUGradE1, dow+1+i, j);
+      }
+    } else if (nonLinTerm == 2) {
+      /// < u^old*grad(u'_i) , psi >
+      for(size_t j = 0; j < dow; ++j) {
+        Operator *opUGradE2 = new Operator(prob->getFeSpace(i),prob->getFeSpace(i));
+        opUGradE2->addTerm(new Vec2ProductPartial_FOT(
+          phaseInv,
+          prob->getSolution()->getDOFVector(j), j, density), GRD_PHI);
+        prob->addMatrixOperator(*opUGradE2, dow+1+i, dow+1+i);
+      }
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity)
+    addLaplaceTerm(i);
+  }
+
+  /// phase*div(u) +(1 - phase)*(p - (lambda + 2/3*mu)*div(eta))
+  for (size_t i = 0; i < dow; ++i) {
+    /// < phase*d_i(u_i) , psi >
+    Operator *opDivU = new Operator(prob->getFeSpace(dow),prob->getFeSpace(i));
+    opDivU->addTerm(new VecAndPartialDerivative_FOT(phase, i), GRD_PHI);
+    prob->addMatrixOperator(*opDivU, dow, i);
+
+    /// < (1-phase)*d_i(eta_i) , psi >
+    Operator *opDivEta = new Operator(prob->getFeSpace(dow),prob->getFeSpace(dow+1+i));
+    opDivEta->addTerm(new VecAndPartialDerivative_FOT(phaseInv, i, pressure_factor), GRD_PHI);
+    prob->addMatrixOperator(*opDivEta, dow, dow+1+i);
+  }
+
+  /// < (1-phase)*p , psi >
+  Operator *opP = new Operator(prob->getFeSpace(dow),prob->getFeSpace(dow));
+  opP->addTerm(new VecAtQP_ZOT(phaseInv));
+  prob->addMatrixOperator(*opP, dow, dow);
+  
+}
+
+
+void DiffuseDomainFsi::addLaplaceTerm(int i)
+{ FUNCNAME("DiffuseDomainFsi::addLaplaceTerm()");
+    
+    for (size_t j = 0; j < dow; ++j) {
+      /// < nu*[grad(u)+grad(u)^t] , grad(psi) >
+      Operator *opLaplaceUi1 = new Operator(prob->getFeSpace(i), prob->getFeSpace(j));
+      opLaplaceUi1->addTerm(new MatrixIJPhase_SOT(phase, 1-i, 1-j, viscosity));
+      prob->addMatrixOperator(*opLaplaceUi1, i, j);
+
+      /// < (mu+lambda)*[grad(u)+grad(u)^t] , grad(psi) >
+      Operator *opLaplaceEi1 = new Operator(prob->getFeSpace(dow+1+i), prob->getFeSpace(dow+1+j));
+      opLaplaceEi1->addTerm(new MatrixIJPhase_SOT(phaseInv, 1-i, 1-j, mu+lambda));
+      prob->addMatrixOperator(*opLaplaceEi1, dow+1+i, dow+1+j);
+    }
+    
+    /// < nu*grad(u_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+      opLaplaceUi->addTerm(new Phase_SOT(phase, viscosity));
+    prob->addMatrixOperator(*opLaplaceUi, i, i);
+
+    /// < mu*grad(eta_i) , grad(psi) >
+    Operator *opLaplaceEi = new Operator(prob->getFeSpace(dow+1+i), prob->getFeSpace(dow+1+i));
+      opLaplaceEi->addTerm(new Phase_SOT(phaseInv, mu));
+    prob->addMatrixOperator(*opLaplaceEi, dow+1+i, dow+1+i);
+
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow));
+    opGradP->addTerm(new VecAndPartialDerivative_FOT(phase,i, -1.0), GRD_PSI);
+    prob->addMatrixOperator(*opGradP, i, dow);
+    Operator *opGradP2 = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow));
+    opGradP2->addTerm(new PartialDerivative_ZOT(phase,i, -1.0));
+    prob->addMatrixOperator(*opGradP2, i, dow);
+}
diff --git a/extensions/base_problems/DiffuseDomainFsi.h b/extensions/base_problems/DiffuseDomainFsi.h
new file mode 100644
index 0000000000000000000000000000000000000000..f54cb1a2a08d6209cebd8b9a2f49084401383559
--- /dev/null
+++ b/extensions/base_problems/DiffuseDomainFsi.h
@@ -0,0 +1,176 @@
+/** \file DiffuseDomainFsi.h */
+
+#ifndef DIFFUSE_DOMAIN_FSI_H
+#define DIFFUSE_DOMAIN_FSI_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+#include "ExtendedProblemStat.h"
+#include "Helpers.h"
+#include "POperators.h"
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * fully coupled fluid structure interaction using diffuse doamins
+ * 
+ * dt(u_j) + u*grad(u_j) - div(phase*sigma_f) - div((1-phase)*sigma_s) = 0; j=1...d
+ * div(phase*u) = grad(phase)*u
+ * (1-phase)*(dt(eta_j)+u*grad(eta_j)) = (1-phase)*u_j; j=1...d
+ */
+class DiffuseDomainFsi : public BaseProblem<ExtendedProblemStat>
+{
+public: // typedefs
+
+  typedef BaseProblem<ExtendedProblemStat> super;
+
+public: // methods
+
+  DiffuseDomainFsi(const std::string &name_);
+  ~DiffuseDomainFsi();
+  
+  virtual void initData();
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+  
+  // === getting/setting methods ===
+  
+  DOFVector<double> *getPhase()
+  {
+    return phase;
+  }
+  
+  double getEpsilon()
+  {
+    return epsilon;
+  }
+
+  DOFVector<WorldVector<double> >* getVelocity()
+  {
+    return velocity;
+  }
+
+  DOFVector<WorldVector<double> >* getDisplacement()
+  {
+    return displacement;
+  }
+  
+  void setPhase(DOFVector<double>* phase_)
+  {
+    phase = phase_;
+  }
+  
+  void setEpsilon(double epsilon_)
+  {
+    epsilon = epsilon_;
+  }
+
+  void writeFiles(AdaptInfo* adaptInfo, bool force = false)
+  {
+    fileWriterPhase->writeFiles(adaptInfo, force);
+    fileWriterVelocity->writeFiles(adaptInfo, force);
+    fileWriterDisplacement->writeFiles(adaptInfo, force);
+    super::writeFiles(adaptInfo, force);
+  }
+
+// protected: // methods
+
+  virtual void fillOperators();
+//   virtual void fillBoundaryConditions();
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+  
+  double dbc_factor; // beta/epsilon^alpha
+  double pressure_factor; // -(lambda+2/3*mu)
+  double beta;
+  double epsilon;
+  double alpha;
+
+  int laplaceType;
+  int nonLinTerm;
+
+  double oldTimestep;
+
+  // navier-stokes parameters
+  double viscosity;
+  double density;
+  // elasticity parameters
+  double mu;
+  double lambda;
+  double rho;
+  
+  DOFVector<double> *phase;
+  DOFVector<double> *phaseInv;
+
+  DOFVector<WorldVector<double> >* velocity;
+
+  void calcVelocity()
+  {
+    if (dow == 1)
+      transformDOF(prob->getSolution()->getDOFVector(0), velocity, new AMDiS::Vec1WorldVec<double>);
+    else if (dow == 2)
+      transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), velocity, new AMDiS::Vec2WorldVec<double>);
+    else if (dow == 3)
+      transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), velocity, new AMDiS::Vec3WorldVec<double>);
+  }
+  
+  DOFVector<WorldVector<double> >* displacement;
+
+  void calcDisplacement()
+  {
+    if (dow == 1)
+      transformDOF(prob->getSolution()->getDOFVector(dow+1), displacement, new AMDiS::Vec1WorldVec<double>);
+    else if (dow == 2)
+      transformDOF(prob->getSolution()->getDOFVector(dow+1), prob->getSolution()->getDOFVector(dow+2), displacement, new AMDiS::Vec2WorldVec<double>);
+    else if (dow == 3)
+      transformDOF(prob->getSolution()->getDOFVector(dow+1), prob->getSolution()->getDOFVector(dow+2), prob->getSolution()->getDOFVector(dow+3), displacement, new AMDiS::Vec3WorldVec<double>);
+  }
+  
+  FileWriter* fileWriterPhase;
+  FileVectorWriter* fileWriterVelocity;
+  FileVectorWriter* fileWriterDisplacement;
+};
+
+
+struct ComponentExtractor : AbstractFunction<double, WorldVector<double> >
+{
+  ComponentExtractor(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_, int comp_, double factor_=1.0)
+  : AbstractFunction<double, WorldVector<double> >(fct_->getDegree()),
+    fct(fct_), 
+    comp(comp_),
+    factor(factor_) {}
+  
+  double operator()(const WorldVector<double>& x) const {
+    WorldVector<double> result = (*fct)(x);
+    return factor*result[comp];
+  }
+  
+private:
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* fct;
+  int comp;
+  double factor;
+};
+
+
+struct VecAndComponentExtractor : BinaryAbstractFunction<double, double, WorldVector<double> >
+{
+  VecAndComponentExtractor(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_, int comp_, double factor_=1.0)
+  : BinaryAbstractFunction<double, double, WorldVector<double> >(fct_->getDegree()+1),
+    fct(fct_), 
+    comp(comp_),
+    factor(factor_) {}
+  
+  double operator()(const double& vec, const WorldVector<double>& x) const {
+    WorldVector<double> result = (*fct)(x);
+    return factor*vec*result[comp];
+  }
+  
+private:
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* fct;
+  int comp;
+  double factor;
+};
+
+#endif // DIFFUSE_DOMAIN_FSI_H
diff --git a/extensions/base_problems/LinearElasticity.cc b/extensions/base_problems/LinearElasticity.cc
new file mode 100644
index 0000000000000000000000000000000000000000..05755a5b713c9a013fca0681ad0708d64f2f8574
--- /dev/null
+++ b/extensions/base_problems/LinearElasticity.cc
@@ -0,0 +1,158 @@
+#include "LinearElasticity.h"
+
+using namespace std;
+using namespace AMDiS;
+
+LinearElasticity::LinearElasticity(const std::string &name_) :
+  super(name_),
+  mu(1.0),
+  lambda(1.0),
+  rho(1.0),
+  displacement(NULL)
+{  
+  Parameters::get(name + "->mu", mu);
+  Parameters::get(name + "->lambda", lambda);
+  Parameters::get(name + "->rho", rho);
+  
+  force.set(0.0);
+  Parameters::get(name + "->force", force);
+}
+
+
+LinearElasticity::~LinearElasticity() 
+{ FUNCNAME("LinearElasticity::~LinearElasticity()");
+
+  if (displacement != NULL)
+    delete displacement;
+  delete fileWriter;
+}
+
+
+void LinearElasticity::initData()
+{ FUNCNAME("LinearElasticity::initTimeInterface()");
+
+  if (displacement == NULL)
+    displacement = new DOFVector<WorldVector<double> >(getFeSpace(0), "displacement");
+  fileWriter = new FileVectorWriter(name + "->displacement->output", getFeSpace()->getMesh(), displacement);
+
+  super::initData();
+}
+
+
+void LinearElasticity::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("LinearElasticity::solveInitialProblem()");
+
+  for (size_t i = 0; i < 2*dow-1; i++)
+    prob->getSolution()->getDOFVector(i)->set(0.0);
+}
+
+
+void LinearElasticity::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("LinearElasticity::transferInitialSolution()");
+
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), displacement, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), displacement, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), displacement, new AMDiS::Vec3WorldVec<double>);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+  
+  // initial parameters for detecting mesh changes
+  oldMeshChangeIdx= getMesh()->getChangeIndex();
+}
+
+
+void LinearElasticity::fillOperators()
+{ FUNCNAME("LinearElasticity::fillOperators()");
+  MSG("LinearElasticity::fillOperators()\n");
+
+  // fill operators for prob
+  for (size_t i = 0; i < dow; ++i) {
+    /// dt(u) - v = 0
+    /// ____________________________________________________________________________
+    
+    if (abs(rho) > DBL_TOL) {
+      // < (1/tau)*u_i , psi >
+      Operator *opTimeU = new Operator(getFeSpace(i+dow), getFeSpace(i));
+      opTimeU->addTerm(new Simple_ZOT);
+      prob->addMatrixOperator(*opTimeU, i+dow, i, getInvTau(), getInvTau());
+      // < (1/tau)*u_i^old , psi >
+      Operator *opTimeUOld = new Operator(getFeSpace(i+dow));
+      opTimeUOld->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(i)));
+      prob->addVectorOperator(*opTimeUOld, i+dow, getInvTau(), getInvTau());
+    }
+    // < v , psi >
+    Operator *opV = new Operator(getFeSpace(i+dow), getFeSpace(i+dow));
+    opV->addTerm(new Simple_ZOT(abs(rho) > DBL_TOL ? -1.0/rho : -1.0));
+    prob->addMatrixOperator(*opV, i+dow, i+dow);
+    
+    /// dt(v) - mu*div(grad(u)) - (mu+lambda)*grad(div(u)) = F
+    /// ____________________________________________________________________________
+ 
+    
+    if (abs(rho) > DBL_TOL) {
+      // < (1/tau)*v_i , psi >
+      Operator *opTimeV = new Operator(getFeSpace(i), getFeSpace(i+dow));
+      opTimeV->addTerm(new Simple_ZOT);
+      prob->addMatrixOperator(*opTimeV, i, i+dow, getInvTau(), getInvTau());
+      // < (1/tau)*v_i^old , psi >
+      Operator *opTimeVOld = new Operator(getFeSpace(i));
+      opTimeVOld->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(i+dow)));
+      prob->addVectorOperator(*opTimeVOld, i, getInvTau(), getInvTau());
+    }
+    
+    // < grad(u_i) , grad(psi) >
+    Operator *opDivGradU = new Operator(getFeSpace(i), getFeSpace(i));
+    opDivGradU->addTerm(new Simple_SOT(mu));
+    prob->addMatrixOperator(*opDivGradU, i, i);
+
+    // < d_j(u_j) , d_i(psi) >
+    for (size_t j = 0; j < dow; j++) {
+      Operator *opGradDivU = new Operator(getFeSpace(i), getFeSpace(j));
+      opGradDivU->addTerm(new FactorIJ_SOT(i, j, mu+lambda));
+      prob->addMatrixOperator(*opGradDivU, i, j);
+    }
+  
+    // external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addTerm(new Simple_ZOT(force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+}
+
+
+void LinearElasticity::fillBoundaryConditions()
+{ FUNCNAME("LinearElasticity::fillBoundaryConditions()");
+
+//   ERROR("You have to implement some boundary conditions!\n");
+  AbstractFunction<double, WorldVector<double> > *zero = new AMDiS::Const<double, WorldVector<double> >(0.0);
+  for (size_t i = 0; i < 2*dow-1; i++) {
+    prob->addDirichletBC(1, i, i, zero);
+  }
+}
+
+
+// void LinearElasticity::initTimestep(AdaptInfo *adaptInfo)
+// { FUNCNAME("LinearElasticity::initTimestep()");
+// 
+// }
+
+
+void LinearElasticity::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("LinearElasticity::closeTimestep()");
+
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), displacement, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), displacement, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), displacement, new AMDiS::Vec3WorldVec<double>);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+}
diff --git a/extensions/base_problems/LinearElasticity.h b/extensions/base_problems/LinearElasticity.h
new file mode 100644
index 0000000000000000000000000000000000000000..f757b82eb2a4c6264a460696a327d221739924db
--- /dev/null
+++ b/extensions/base_problems/LinearElasticity.h
@@ -0,0 +1,56 @@
+/** \file LinearElasticity.h */
+
+#ifndef LINEAR_ELASTICITY_H
+#define LINEAR_ELASTICITY_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+#include "ExtendedProblemStat.h"
+
+using namespace AMDiS;
+
+/** \ingroup Elasticity
+ * \brief
+ * Elastodynamics – the wave equation
+ */
+class LinearElasticity : public BaseProblem<ExtendedProblemStat>
+{
+public: // typedefs
+  
+  typedef BaseProblem<ExtendedProblemStat> super;
+  
+public: // methods
+
+  LinearElasticity(const std::string &name_);
+
+  /// if initialVelocityIsSet is true delete initialX and initialY
+  ~LinearElasticity();
+
+  virtual void initData();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+
+//   virtual void initTimestep(AdaptInfo *adaptInfo);
+  /// Implementation of ProblemTimeInterface::closeTimestep().
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  // === getting/setting methods ===
+
+protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+protected: // variables
+
+  double mu;
+  double lambda;
+  double rho;
+
+  WorldVector<double> force;
+  DOFVector<WorldVector<double> >* displacement;
+
+  FileVectorWriter *fileWriter;
+};
+#endif // LINEAR_ELASTICITY_H
diff --git a/extensions/base_problems/LinearElasticityPhase.cc b/extensions/base_problems/LinearElasticityPhase.cc
new file mode 100644
index 0000000000000000000000000000000000000000..7d58b6c52d0871d56c99a475c5316473dd5c1750
--- /dev/null
+++ b/extensions/base_problems/LinearElasticityPhase.cc
@@ -0,0 +1,198 @@
+#include "LinearElasticityPhase.h"
+#include "POperators.h"
+
+using namespace std;
+using namespace AMDiS;
+
+LinearElasticityPhase::LinearElasticityPhase(const std::string &name_) :
+  super(name_),
+  mu(1.0),
+  lambda(1.0),
+  rho(1.0),
+  epsilon(1.e-1),
+  beta(1.0),
+  alpha(3.0),
+  displacement(NULL),
+  phase(NULL),
+  phaseOld(NULL),
+  dirichletPhase(NULL),
+  bcFct(NULL)
+{  
+  for (int i = 0; i < bcDOF.getSize(); ++i)
+    bcDOF[i] = NULL;
+  
+  Parameters::get(name + "->mu", mu);
+  Parameters::get(name + "->lambda", lambda);
+  Parameters::get(name + "->rho", rho);
+  Parameters::get(name + "->epsilon", epsilon);
+
+  Parameters::get(name + "->beta", beta);
+  Parameters::get(name + "->alpha", alpha);
+  
+  force.set(0.0);
+  Parameters::get(name + "->force", force);
+}
+
+
+LinearElasticityPhase::~LinearElasticityPhase() 
+{ FUNCNAME("LinearElasticityPhase::~LinearElasticityPhase()");
+
+  if (displacement != NULL)
+    delete displacement;
+  delete fileWriter;
+}
+
+
+void LinearElasticityPhase::initData()
+{ FUNCNAME("LinearElasticityPhase::initTimeInterface()");
+
+  if (displacement == NULL)
+    displacement = new DOFVector<WorldVector<double> >(getFeSpace(0), "displacement");
+  phaseOld = new DOFVector<double>(getFeSpace(0), "phaseOld");
+  fileWriter = new FileVectorWriter(name + "->displacement->output", getFeSpace()->getMesh(), displacement);
+
+  super::initData();
+
+  dbc_factor = beta/pow(epsilon, alpha);
+  MSG_DBG("dbc_factor = %f\n", dbc_factor);
+}
+
+
+void LinearElasticityPhase::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("LinearElasticityPhase::solveInitialProblem()");
+
+  super::solveInitialProblem(adaptInfo);
+  
+  for (size_t i = 0; i < 2*dow-1; i++)
+    prob->getSolution()->getDOFVector(i)->set(0.0);
+}
+
+
+void LinearElasticityPhase::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("LinearElasticityPhase::transferInitialSolution()");
+
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), displacement, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), displacement, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), displacement, new AMDiS::Vec3WorldVec<double>);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+  
+  // initial parameters for detecting mesh changes
+  oldMeshChangeIdx= getMesh()->getChangeIndex();
+}
+
+
+void LinearElasticityPhase::fillOperators()
+{ FUNCNAME("LinearElasticityPhase::fillOperators()");
+  MSG("LinearElasticityPhase::fillOperators()\n");
+
+  // fill operators for prob
+  for (size_t i = 0; i < dow; ++i) {
+    /// dt(u) - v = 0
+    /// ____________________________________________________________________________
+    
+    if (abs(rho) > DBL_TOL) {
+      // < (1/tau)*u_i , psi >
+      Operator *opTimeU = new Operator(getFeSpace(i+dow), getFeSpace(i));
+      opTimeU->addTerm(new VecAtQP_ZOT(phase));
+      prob->addMatrixOperator(*opTimeU, i+dow, i, getInvTau(), getInvTau());
+      // < (1/tau)*u_i^old , psi >
+      Operator *opTimeUOld = new Operator(getFeSpace(i+dow));
+      opTimeUOld->addTerm(new Vec2AtQP_ZOT(phaseOld, prob->getSolution()->getDOFVector(i)));
+      prob->addVectorOperator(*opTimeUOld, i+dow, getInvTau(), getInvTau());
+    }
+    // < v , psi >
+    Operator *opV = new Operator(getFeSpace(i+dow), getFeSpace(i+dow));
+    opV->addTerm(new Phase_ZOT(phase, -1.0));
+    prob->addMatrixOperator(*opV, i+dow, i+dow);
+    
+    /// dt(v) - mu*div(grad(u)) - (mu+lambda)*grad(div(u)) = F
+    /// ____________________________________________________________________________
+ 
+    
+    if (abs(rho) > DBL_TOL) {
+      // < (1/tau)*v_i , psi >
+      Operator *opTimeV = new Operator(getFeSpace(i), getFeSpace(i+dow));
+      opTimeV->addTerm(new VecAtQP_ZOT(phase, new AMDiS::Factor<double>(rho)));
+      prob->addMatrixOperator(*opTimeV, i, i+dow, getInvTau(), getInvTau());
+      // < (1/tau)*v_i^old , psi >
+      Operator *opTimeVOld = new Operator(getFeSpace(i));
+      opTimeVOld->addTerm(new Vec2AtQP_ZOT(phase, prob->getSolution()->getDOFVector(i+dow), new AMDiS::MultScal<double>(rho)));
+      prob->addVectorOperator(*opTimeVOld, i, getInvTau(), getInvTau());
+    }
+    
+    // < grad(u_i) , grad(psi) >
+    Operator *opDivGradU = new Operator(getFeSpace(i), getFeSpace(i));
+    opDivGradU->addTerm(new Phase_SOT(phase, mu));
+    prob->addMatrixOperator(*opDivGradU, i, i);
+
+    // < d_j(u_j) , d_i(psi) >
+    for (size_t j = 0; j < dow; j++) {
+      Operator *opGradDivU = new Operator(getFeSpace(i), getFeSpace(j));
+      opGradDivU->addTerm(new MatrixIJPhase_SOT(phase, i, j, mu+lambda));
+      prob->addMatrixOperator(*opGradDivU, i, j);
+    }
+  
+    // external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addTerm(new Phase_ZOT(phase, force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+}
+
+
+void LinearElasticityPhase::fillBoundaryConditions()
+{ FUNCNAME("LinearElasticityPhase::fillBoundaryConditions()");
+
+  /// neumann boundary condition
+  for (size_t i = 0; i < dow; i++) {
+    Operator *opNeumannForce = new Operator(getFeSpace(i), getFeSpace(i));
+    if (bcDOF[i] != NULL) {
+      opNeumannForce->addTerm(new VecAndGradVecAtQP_ZOT(bcDOF[i], phase, new NeumannBCDof));
+    } else if (bcFct != NULL) {
+      opNeumannForce->addTerm(new FctGradientCoords_ZOT(phase, new NeumannBCFct(new ComponentExtractor_(bcFct, i))));
+    }
+    prob->addVectorOperator(*opNeumannForce, i);
+  }
+
+  /// dirichlet boundary condition
+  if (dirichletPhase != NULL) {
+  for (size_t i = 0; i < dow; ++i) {
+    /// dirichlet boundary condition
+    /// beta/eps^alpha (1-phase)*(u_i - g_i), with g_i = 0
+    Operator *opDbcPhaseInvU = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opDbcPhaseInvU->addTerm(new Simple_ZOT(dbc_factor));
+    opDbcPhaseInvU->addTerm(new Phase_ZOT(dirichletPhase, -dbc_factor));
+    prob->addMatrixOperator(*opDbcPhaseInvU, i, i);
+  }
+  }
+}
+
+
+void LinearElasticityPhase::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("LinearElasticityPhase::initTimestep()");
+
+  super::initTimestep(adaptInfo);
+  phaseOld->interpol(phase);
+}
+
+
+void LinearElasticityPhase::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("LinearElasticityPhase::closeTimestep()");
+
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), displacement, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), displacement, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), displacement, new AMDiS::Vec3WorldVec<double>);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+}
diff --git a/extensions/base_problems/LinearElasticityPhase.h b/extensions/base_problems/LinearElasticityPhase.h
new file mode 100644
index 0000000000000000000000000000000000000000..6876401c9b68382188dd51c9b1b96c1a6c1d2f68
--- /dev/null
+++ b/extensions/base_problems/LinearElasticityPhase.h
@@ -0,0 +1,147 @@
+/** \file LinearElasticityPhase.h */
+
+#ifndef LINEAR_ELASTICITY_H
+#define LINEAR_ELASTICITY_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+#include "ExtendedProblemStat.h"
+
+using namespace AMDiS;
+
+/** \ingroup Elasticity
+ * \brief
+ * Elastodynamics – the wave equation
+ */
+class LinearElasticityPhase : public BaseProblem<ExtendedProblemStat>
+{
+public: // typedefs
+  
+  typedef BaseProblem<ExtendedProblemStat> super;
+  
+public: // methods
+
+  LinearElasticityPhase(const std::string &name_);
+
+  /// if initialVelocityIsSet is true delete initialX and initialY
+  ~LinearElasticityPhase();
+
+  virtual void initData();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  // === getting/setting methods ===
+
+  DOFVector<double> *getPhase()
+  {
+    return phase;
+  }
+  
+  double getEpsilon()
+  {
+    return epsilon;
+  }
+  
+  void setPhase(DOFVector<double>* phase_)
+  {
+    phase = phase_;
+  }
+
+  void setDirichletPhase(DOFVector<double>* phase_)
+  {
+    dirichletPhase = phase_;
+  }
+  
+  void setBcDOF(DOFVector<double>* bcDOF_i, int i)
+  {
+    bcDOF[i] = bcDOF_i;
+  }
+  
+  void setBcFct(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_)
+  {
+    bcFct = fct_;
+  }
+
+  void setEpsilon(double epsilon_)
+  {
+    epsilon = epsilon_;
+  }
+  
+// protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+protected: // variables
+
+  double mu;
+  double lambda;
+  double rho;
+  double epsilon;
+  double beta;
+  double alpha;
+  double dbc_factor;
+
+  WorldVector<double> force;
+  DOFVector<WorldVector<double> >* displacement;
+
+  DOFVector<double> *phase;
+  DOFVector<double> *phaseOld;
+
+  WorldVector<DOFVector<double>*> bcDOF;
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* bcFct;
+
+  DOFVector<double>* dirichletPhase;
+  
+  FileVectorWriter *fileWriter;
+};
+
+struct NeumannBCDof : BinaryAbstractFunction<double, double, WorldVector<double> >
+{
+  NeumannBCDof() : BinaryAbstractFunction<double, double, WorldVector<double> >(5) {}
+  
+  double operator()(const double& g, const WorldVector<double>& grdPhase) const
+  {
+    return g/* * AMDiS::Norm2<double, WorldVector<double> >()(grdPhase)*/;
+  }
+};
+
+struct NeumannBCFct : BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> >
+{
+  NeumannBCFct(AbstractFunction<double, WorldVector<double> >* g_)
+  : BinaryAbstractFunction<double, WorldVector<double>, WorldVector<double> >(g_->getDegree() + 3), 
+    g(g_) {}
+  
+  double operator()(const WorldVector<double>& grdPhase, const WorldVector<double>& x) const
+  {
+    return (*g)(x)/* * AMDiS::Norm2<double, WorldVector<double> >()(grdPhase)*/;
+  }
+  
+private:
+  AbstractFunction<double, WorldVector<double> >* g;
+};
+
+struct ComponentExtractor_ : AbstractFunction<double, WorldVector<double> >
+{
+  ComponentExtractor_(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_, int comp_, double factor_=1.0)
+  : AbstractFunction<double, WorldVector<double> >(fct_->getDegree()),
+    fct(fct_), 
+    comp(comp_),
+    factor(factor_) {}
+  
+  double operator()(const WorldVector<double>& x) const {
+    WorldVector<double> result = (*fct)(x);
+    return factor*result[comp];
+  }
+  
+private:
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* fct;
+  int comp;
+  double factor;
+};
+
+#endif // LINEAR_ELASTICITY_H
diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.cc b/extensions/base_problems/NavierStokesPhase_Chorin.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4a46db3c5725564443d01ccb7b72cb851de7166a
--- /dev/null
+++ b/extensions/base_problems/NavierStokesPhase_Chorin.cc
@@ -0,0 +1,271 @@
+#include "NavierStokesPhase_Chorin.h"
+
+#define UPDATE_VELOCITY_SYSTEM
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokesPhase_Chorin::NavierStokesPhase_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_, DiffuseDomain* geometryProb_) :
+  super(name_, initialVelocityFcts_),
+  geometryProb(geometryProb_),
+  beta(1.0),
+  epsPhase2(1.0)
+{
+  Initfile::get(name + "->beta", beta); // penalization of boundary condition
+  double exponent = 2.7;
+  Initfile::get(name + "->exponent", exponent); // penalization of boundary condition
+  epsPhase2 = beta/pow(geometryProb->getEpsilon(), exponent);
+
+  writer = new MyFileWriter();
+  writer->initFile("diff");
+};
+
+
+void NavierStokesPhase_Chorin::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokesPhase_Chorin::solveInitialProblem()");
+MSG_DBG("NavierStokesPhase_Chorin::solveInitialProblem()\n");
+
+  NavierStokes_Chorin::solveInitialProblem(adaptInfo);
+
+  if (initialVelocityIsSet) {
+  for (unsigned i = 0; i < dim; ++i) {
+    transformDOF(predictorProb->getSolution()->getDOFVector(i),
+      geometryProb->getPhasefield(), 
+      predictorProb->getSolution()->getDOFVector(i), 
+      new Mult<double>);
+  }
+  }
+  tau = 0.1;
+
+};
+
+
+void NavierStokesPhase_Chorin::fillOperators()
+{ FUNCNAME("NavierStokesPhase_Chorin::fillOperators()");
+  MSG_DBG("NavierStokesPhase_Chorin::fillOperators()\n");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (unsigned i = 0; i < dim; i++)
+    vel[i]= correctorProb->getSolution()->getDOFVector(i);
+
+  // fill operators for predictorProb
+  for (unsigned i = 0; i < dim; ++i) {
+    /// < (1/tau)*u'_i , psi >
+    Operator *opTime = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+    opTime->addZeroOrderTerm(new Phase_ZOT(geometryProb->getPhasefield()));
+    predictorProb->addMatrixOperator(*opTime, i, i, getInvTau());
+    /// < (1/tau)*u_i^old , psi >
+    opTime->setUhOld(correctorProb->getSolution()->getDOFVector(i));
+    predictorProb->addVectorOperator(*opTime, i, getInvTau());
+ 
+    // boundary condition: u=0 on Gamma
+    /// < (beta/eps^3)*(1-phi)*u'_i , psi >
+    Operator *bound0 = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+    bound0->addTerm(new PhaseInverse_ZOT(
+      geometryProb->getPhasefield(),
+      epsPhase2));
+    predictorProb->addMatrixOperator(*bound0, i, i);
+    bound0->setUhOld(boundaryDOF[i]);
+    predictorProb->addVectorOperator(*bound0, i);
+
+    if (nonLinTerm == 0) {
+      /// < phi*u^old*grad(u_i^old) , psi >
+      Operator *opUGradU = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+      opUGradU->addTerm(new WorldVecPhase_FOT(geometryProb->getPhasefield(), vel, -1.0), GRD_PHI);
+      opUGradU->setUhOld(correctorProb->getSolution()->getDOFVector(i));
+      predictorProb->addVectorOperator(*opUGradU, i);
+    } else if (nonLinTerm == 1) {
+      /// < phi*u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU = new Operator(predictorProb->getFeSpace(i),predictorProb->getFeSpace(i));
+        opUGradU->addTerm(new VecAndPartialDerivative_ZOT(
+          geometryProb->getPhasefield(), 
+          correctorProb->getSolution()->getDOFVector(i), j));
+        predictorProb->addMatrixOperator(*opUGradU, i, j);
+      }
+    } else {
+      /// < phi*u^old*grad(u'_i) , psi >
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU = new Operator(predictorProb->getFeSpace(i),predictorProb->getFeSpace(i));
+        opUGradU->addTerm(new Vec2ProductPartial_FOT(
+          geometryProb->getPhasefield(), 
+          correctorProb->getSolution()->getDOFVector(j),
+          j), GRD_PHI);
+        predictorProb->addMatrixOperator(*opUGradU, i, i);
+      }           
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) > TODO: Add boundary-integral for neumann-boundary
+    Operator *opGradP2 = new Operator(predictorProb->getFeSpace(i),pressureProb->getFeSpace(0));
+    opGradP2->addFirstOrderTerm(new VecAndPartialDerivative_FOT(geometryProb->getPhasefield(), i, -1.0), GRD_PHI);
+    opGradP2->setUhOld(pressureProb->getSolution()->getDOFVector(0));
+    predictorProb->addVectorOperator(*opGradP2, i, getPressureStep());
+  
+      
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+      opForce->addZeroOrderTerm(new Phase_ZOT(geometryProb->getPhasefield(),force[i]));
+      predictorProb->addVectorOperator(*opForce, i);
+    }
+  }
+
+  // preassure-calculation: tau*div(phi*grad(p)) = div(phi*u')-grad(phi)*g
+  // ---------------------------------------------------------------------
+  for(unsigned i = 0; i < dim; ++i) {
+    /// < (1/tau)*phi*d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(pressureProb->getFeSpace(0),predictorProb->getFeSpace(i));
+    opDivU->addTerm(new VecAndPartialDerivative_ZOT(
+      geometryProb->getPhasefieldDisturbed(),
+      predictorProb->getSolution()->getDOFVector(i),i));
+    pressureProb->addVectorOperator(opDivU,0);
+    /// < 1/tau*d_i(phi)*u'_i , psi >
+    Operator *gradPhiU = new Operator(pressureProb->getFeSpace(0), predictorProb->getFeSpace(i));
+    gradPhiU->addTerm(new VecAndPartialDerivative_ZOT(
+      predictorProb->getSolution()->getDOFVector(i),
+      geometryProb->getPhasefieldDisturbed(),i));
+    pressureProb->addVectorOperator(gradPhiU,0);
+    /// < 1/tau*d_i(phi)*g , psi >
+    Operator *gradPhiG = new Operator(pressureProb->getFeSpace(0), predictorProb->getFeSpace(i));
+    gradPhiG->addTerm(new VecAndPartialDerivative_ZOT(
+      boundaryDOF[i],
+      geometryProb->getPhasefieldDisturbed(),i,-1.0));
+    pressureProb->addVectorOperator(gradPhiG,0);
+  }
+  /// < -grad(p) , grad(psi) >
+  Operator *laplaceP = new Operator(pressureProb->getFeSpace(0), pressureProb->getFeSpace(0));
+  laplaceP->addSecondOrderTerm(new Phase_SOT(geometryProb->getPhasefieldDisturbed(), -1.0));
+  pressureProb->addMatrixOperator(*laplaceP, 0, 0, getTau());
+
+  // corrector step: u = u' - tau*grad(p)
+  // ---------------------------------------
+  for(unsigned i = 0; i < dim; ++i) {
+    /// < u_i , psi >
+    Operator *opSimple = new Operator(correctorProb->getFeSpace(i),correctorProb->getFeSpace(i));
+    opSimple->addZeroOrderTerm(new Simple_ZOT);
+    correctorProb->addMatrixOperator(*opSimple, i, i);
+    /// < u'_i , psi >
+    opSimple->setUhOld(predictorProb->getSolution()->getDOFVector(i));
+    correctorProb->addVectorOperator(*opSimple, i);
+    /// < -tau*d_i(p) , psi >
+    Operator *opGradQ = new Operator(correctorProb->getFeSpace(i),pressureProb->getFeSpace(0));
+    opGradQ->addFirstOrderTerm(new PartialDerivative_FOT(i, -1.0), GRD_PHI);
+    opGradQ->setUhOld(pressureProb->getSolution()->getDOFVector(0));
+    correctorProb->addVectorOperator(*opGradQ, i, getTau());
+  }
+};
+
+
+void NavierStokesPhase_Chorin::addLaplaceTerm(int i)
+{
+  MSG_DBG("NavierStokesPhase_Chorin::addLaplaceTerm()\n");
+    /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+    if (laplaceType == 1) {
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opLaplaceUi1 = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(j));
+        opLaplaceUi1->addSecondOrderTerm(new MatrixIJPhase_SOT(geometryProb->getPhasefield(), 1-i, 1-j, viscosity));
+        predictorProb->addMatrixOperator(*opLaplaceUi1, i, j);
+      }
+    }
+    
+    /// < alpha*grad(u'_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+      opLaplaceUi->addSecondOrderTerm(new Phase_SOT(geometryProb->getPhasefield(), viscosity));
+    predictorProb->addMatrixOperator(*opLaplaceUi, i, i);
+
+//     Operator *opLaplaceUi_mod = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+//       opLaplaceUi_mod->addFirstOrderTerm(new VectorGradient_FOT(geometryProb->getPhasefield(), new Factor<WorldVector<double> >(viscosity)));
+//     predictorProb->addMatrixOperator(*opLaplaceUi_mod, i, i);
+};
+
+
+void NavierStokesPhase_Chorin::fillBoundaryConditions()
+{ FUNCNAME("NavierStokesPhase_Chorin::fillBoundaryConditions()");
+  MSG_DBG("NavierStokesPhase_Chorin::fillBoundaryConditions()\n");
+
+  DOFVector<double> *zeroDOF = new DOFVector<double>(predictorProb->getFeSpace(0), "zero");
+  zeroDOF->set(0.0);
+
+  /// at rigid wall: no-slip boundary condition
+  for (unsigned j = 0; j < dim; ++j) {
+    predictorProb->addDirichletBC(LINKS, j, j, zeroDOF);
+    predictorProb->addDirichletBC(RECHTS, j, j, zeroDOF);
+  }
+  
+  /// at inflow: prescribed velocity
+  for (unsigned j = 0; j < dim; ++j) {
+    predictorProb->addDirichletBC(UNTEN, j, j, boundaryDOF[j]);
+    //predictorProb->addDirichletBC(OBEN, j, j, boundaryDOF[j]); /// test: Dirichlet-BC at outflow boundary
+  }
+  
+  /// at outflow: constant pressure
+  pressureProb->addDirichletBC(UNTEN, 0,0, zeroDOF);
+  pressureProb->addDirichletBC(OBEN, 0,0, zeroDOF);
+
+
+  /// boundaryManager wird von Diagonale kopiert, wenn MatrixOperator hinzugefuegt wird -> erst MatrixOperatoren, danach erst BoundaryOperatoren
+//   for (unsigned i = 0; i < dim; ++i) {
+//     for (unsigned j = 0; j < dim; ++j) {
+//       Operator *opLaplaceBoundary = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(j));
+//       opLaplaceBoundary->addFirstOrderTerm(new ViscosityPartialDerivativeBoundary_FOT(
+//         chProb.getSolution()->getDOFVector(0), i, j, viscosity1, viscosity2), GRD_PHI);
+//       for (unsigned b= 0; b < nsNeumannBC.size(); ++b) {
+//         if (nsNeumannBC[b] != 0) {
+//           predictorProb->addBoundaryMatrixOperator(nsNeumannBC[b], opLaplaceBoundary, i, j);
+//         }
+//       }
+//     }
+//   }
+};
+
+
+void NavierStokesPhase_Chorin::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokesPhase_Chorin::initTimestep()");
+  MSG_DBG("NavierStokesPhase_Chorin::initTimestep()\n");
+
+  if (adaptInfo->getTimestepNumber() > 1) {
+    WorldVector<DOFVector<double>* > gradPressure;
+    for (int i = 0; i < gradPressure.getSize(); ++i)
+      gradPressure[i] = new DOFVector<double>(correctorProb->getFeSpace(0), "gradPressure_i");
+    DOFVector<WorldVector<double> > gradPressure_temp(correctorProb->getFeSpace(0), "gradPressure");
+  
+    pressureProb->getSolution()->getDOFVector(0)->getRecoveryGradient(&gradPressure_temp);
+    transform(&gradPressure_temp, &gradPressure);
+  
+    for (int i = 0; i < gradPressure.getSize(); ++i) {
+      transformDOF(predictorProb->getExactSolution(i),
+        gradPressure[i],
+        boundaryDOF[i], new AddFactor<double>(*getTau()));
+      transformDOF(boundaryDOF[i],
+        geometryProb->getPhasefield(),
+        boundaryDOF[i], new Mult<double>);
+    } 
+    
+    // delete garbage
+    for(int i= 0; i<gradPressure.getSize(); ++i)
+      delete gradPressure[i];
+  }
+};
+
+
+void NavierStokesPhase_Chorin::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokesPhase_Chorin::closeTimestep()");
+  MSG_DBG("NavierStokesPhase_Chorin::closeTimestep()\n");
+
+  for (int i = 0; i < correctorProb->getNumComponents(); ++i) {
+    transformDOF(correctorProb->getSolution()->getDOFVector(0),
+      geometryProb->getPhasefield(),
+      correctorProb->getSolution()->getDOFVector(0), new Mult<double>);
+  }
+
+  int outputPeriod = 1;
+  Initfile::get("user parameter->write every ith timestep", outputPeriod);
+  if (adaptInfo->getTimestepNumber() % outputPeriod == 0
+    && adaptInfo->getStartTime() < adaptInfo->getEndTime()) {
+    writeFiles(adaptInfo, false);
+  }
+};
+
diff --git a/extensions/base_problems/NavierStokesPhase_Chorin.h b/extensions/base_problems/NavierStokesPhase_Chorin.h
new file mode 100644
index 0000000000000000000000000000000000000000..4900a6b5d36c2446373fb6a5bf84867f57db3126
--- /dev/null
+++ b/extensions/base_problems/NavierStokesPhase_Chorin.h
@@ -0,0 +1,72 @@
+/** \file NavierStokesPhase_Chorin.h */
+
+#ifndef NAVIER_STOKES_PHASE_CHORIN_H
+#define NAVIER_STOKES_PHASE_CHORIN_H
+
+#include "MyGlobal.h"
+#include "NavierStokes_Chorin.h"
+#include "Helpers.h"
+#include "POperators.h"
+#include "BoundaryFunctions.h"
+#include "Refinement.h"
+#include "MeshFunction_Level.h"
+#include "MyFileWriter.h"
+#include "DiffuseDomain.h"
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/mtl/utility/property_map.hpp>
+
+
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokesPhase_Chorin
+ * \brief
+ * Navier-Stokes problem in diffuse domain, using projection method {
+ *       a.) Burgers equation (predictortProb)
+ *       b.) Pressure Poisson problem
+ *       c.) Burgers equation including pressure (predictorProb)
+ *       d.) Pressure Poisson problem
+ *       e.) Velocity update (correctorProb)
+ * }
+ */
+class NavierStokesPhase_Chorin : public NavierStokes_Chorin
+{
+public: // typedefs
+
+  typedef NavierStokes_Chorin super;
+
+public: // methods
+
+  NavierStokesPhase_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_, DiffuseDomain* geometryProb);
+
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  /// Implementation of ProblemTimeInterface::initTimestep().
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+
+  /// Implementation of ProblemTimeInterface::closeTimestep().
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+
+  DiffuseDomain *geometryProb;
+  MyFileWriter *writer;
+
+  double beta;
+  double epsPhase2;
+
+private:
+
+};
+#endif // NAVIER_STOKES_CHORIN_H
diff --git a/extensions/base_problems/NavierStokesPhase_TaylorHood.cc b/extensions/base_problems/NavierStokesPhase_TaylorHood.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b0350dad243d546b1b2b2ed66d7bf69cb28e462a
--- /dev/null
+++ b/extensions/base_problems/NavierStokesPhase_TaylorHood.cc
@@ -0,0 +1,219 @@
+#include "NavierStokesPhase_TaylorHood.h"
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokesPhase_TaylorHood::NavierStokesPhase_TaylorHood(const std::string &name_) :
+  super(name_),
+  phase(NULL),
+  bcFct(NULL),
+  beta(1.0),
+  epsilon(1.e-1),
+  alpha(3.0),
+  fileWriterPhase(NULL)
+{
+  for (int i = 0; i < bcDOF.getSize(); ++i)
+    bcDOF[i] = NULL;
+  
+  Parameters::get(name + "->beta", beta);
+  Parameters::get(name + "->epsilon", epsilon);
+  Parameters::get(name + "->alpha", alpha);
+  
+};
+
+NavierStokesPhase_TaylorHood::~NavierStokesPhase_TaylorHood()
+{
+  if (fileWriterPhase != NULL)
+    delete fileWriterPhase;
+}
+
+void NavierStokesPhase_TaylorHood::initData()
+{
+  super::initData();
+  phaseOld = new DOFVector<double>(getFeSpace(0), "phaseOld");
+
+  dbc_factor = beta/pow(epsilon, alpha);
+  MSG_DBG("dbc_factor = %f\n", dbc_factor);
+}
+
+
+void NavierStokesPhase_TaylorHood::transferInitialSolution(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokesPhase_TaylorHood::transferInitialSolution()");
+
+  fileWriterPhase = new FileWriter(name + "->phase->output", getFeSpace()->getMesh(), phase);
+  for (int i = 0; i < dow; i++)
+    transformDOF(prob->getSolution()->getDOFVector(0), phase, prob->getSolution()->getDOFVector(0), new AMDiS::Mult<double>);
+
+  super::transferInitialSolution(AdaptInfo *adaptInfo);
+  phaseOld->interpol(phase);
+}
+
+
+void NavierStokesPhase_TaylorHood::closeTimestep(AdaptInfo *adaptInfo)
+{
+  super::closeTimestep(adaptInfo);
+  
+  phaseOld->interpol(phase);
+  fileWriterPhase->writeFiles(adaptInfo, false);
+}
+
+
+void NavierStokesPhase_TaylorHood::fillOperators()
+{ FUNCNAME("NavierStokesPhase_TaylorHood::fillOperators()");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (size_t i = 0; i < dow; i++)
+    vel[i] = prob->getSolution()->getDOFVector(i);
+
+  TEST_EXIT(phase!=NULL && phaseOld!=NULL)("PhaseField is not set!\n");
+
+  // fill operators for prob
+  for (size_t i = 0; i < dow; ++i) {
+    /// < (1/tau)*u'_i , psi >
+    Operator *opTime = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opTime->addTerm(new Phase_ZOT(phase, density));
+    prob->addMatrixOperator(*opTime, i, i, getInvTau());
+    /// < (1/tau)*u_i^old , psi >
+    Operator *opTimeOld = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opTimeOld->addTerm(new Phase_ZOT(phaseOld, density));
+    opTimeOld->setUhOld(prob->getSolution()->getDOFVector(i));
+    prob->addVectorOperator(*opTimeOld, i, getInvTau());
+ 
+    /// < u^old*grad(u_i^old) , psi >
+    Operator *opUGradU0 = new Operator(prob->getFeSpace(i),prob->getFeSpace(i));
+    opUGradU0->addTerm(new WorldVecPhase_FOT(phase,vel, -density), GRD_PHI);
+    opUGradU0->setUhOld(prob->getSolution()->getDOFVector(i));
+    if (nonLinTerm == 0) {
+      prob->addVectorOperator(*opUGradU0, i);
+    } else {
+      prob->addVectorOperator(*opUGradU0, i, &theta1);
+    }
+
+    if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU1 = new Operator(prob->getFeSpace(i),prob->getFeSpace(i));
+        opUGradU1->addTerm(new VecAndPartialDerivative_ZOT(
+          phase,
+          prob->getSolution()->getDOFVector(i), j, density));
+        prob->addMatrixOperator(*opUGradU1, i, j, &theta);
+      }
+    } else if (nonLinTerm == 2) {
+      /// < u^old*grad(u'_i) , psi >
+      for(unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU2 = new Operator(prob->getFeSpace(i),prob->getFeSpace(i));
+        opUGradU2->addTerm(new Vec2ProductPartial_FOT(
+          phase,
+          prob->getSolution()->getDOFVector(j), j, density), GRD_PHI);
+        prob->addMatrixOperator(*opUGradU2, i, i, &theta);
+      }
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow));
+    opGradP->addTerm(new VecAndPartialDerivative_FOT(phase,i, -1.0), GRD_PSI);
+    prob->addMatrixOperator(*opGradP, i, dow);
+    Operator *opGradP2 = new Operator(prob->getFeSpace(i),prob->getFeSpace(dow));
+    opGradP2->addTerm(new PartialDerivative_ZOT(phase,i, -1.0));
+    prob->addMatrixOperator(*opGradP2, i, dow);
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+      opForce->addTerm(new Phase_ZOT(phase,force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+
+  /// div(u) = grad(phi)*g
+  for (size_t i = 0; i < dow; ++i) {
+    /// < d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(prob->getFeSpace(dow),prob->getFeSpace(i));
+    opDivU->addTerm(new VecAndPartialDerivative_FOT(phase,i), GRD_PHI);
+    prob->addMatrixOperator(*opDivU, dow, i);
+    Operator *opDivU2 = new Operator(prob->getFeSpace(dow),prob->getFeSpace(i));
+    opDivU2->addTerm(new PartialDerivative_ZOT(phase,i));
+    prob->addMatrixOperator(*opDivU2, dow, i);
+  }
+}
+
+
+void NavierStokesPhase_TaylorHood::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokesPhase_TaylorHood::addLaplaceTerm()");
+
+    /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+    if (laplaceType == 1) {
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opLaplaceUi1 = new Operator(prob->getFeSpace(i), prob->getFeSpace(j));
+        opLaplaceUi1->addTerm(new MatrixIJPhase_SOT(phase, 1-i, 1-j, viscosity));
+        prob->addMatrixOperator(*opLaplaceUi1, i, j, &theta);
+
+        opLaplaceUi1->setUhOld(prob->getSolution()->getDOFVector(j));
+        prob->addVectorOperator(*opLaplaceUi1, i, &minusTheta1);
+      }
+    }
+    
+    /// < alpha*grad(u'_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+      opLaplaceUi->addTerm(new Phase_SOT(phase, viscosity));
+    prob->addMatrixOperator(*opLaplaceUi, i, i, &theta);
+
+    opLaplaceUi->setUhOld(prob->getSolution()->getDOFVector(i));
+    prob->addVectorOperator(*opLaplaceUi, i, &minusTheta1);
+}
+
+
+void NavierStokesPhase_TaylorHood::fillBoundaryConditions()
+{ FUNCNAME("NavierStokesPhase_TaylorHood::fillBoundaryConditions()");
+
+  for (size_t i = 0; i < dow; ++i) {
+    /// dirichlet boundary condition
+    /// beta/eps^alpha (1-phase)*(u_i - g_i)
+    Operator *opDbcPhaseInvU = new Operator(prob->getFeSpace(i), prob->getFeSpace(i));
+    opDbcPhaseInvU->addTerm(new Simple_ZOT(dbc_factor));
+    opDbcPhaseInvU->addTerm(new Phase_ZOT(phase, -dbc_factor));
+    prob->addMatrixOperator(*opDbcPhaseInvU, i, i);
+    
+    if (bcDOF[i] != NULL) {
+      opDbcPhaseInvU->setUhOld(bcDOF[i]);
+      prob->addVectorOperator(*opDbcPhaseInvU, i);
+    } else if (bcFct != NULL) {
+      Operator *opDbcPhaseInvG = new Operator(prob->getFeSpace(i));
+      opDbcPhaseInvG->addTerm(new CoordsAtQP_ZOT(new ComponentExtractor(bcFct, i, dbc_factor)));
+      opDbcPhaseInvG->addTerm(new VecAndCoordsAtQP_ZOT(phase, new VecAndComponentExtractor(bcFct, i, -dbc_factor)));
+      prob->addVectorOperator(*opDbcPhaseInvG, i);
+    }
+  }
+  
+  /// < grad(phi)*G , psi >
+  if (bcDOF[0] != NULL) {
+    Operator *opGradPhiG = new Operator(prob->getFeSpace(dow),prob->getFeSpace(0));
+    opGradPhiG->addTerm(new WorldVec_FOT(bcDOF), GRD_PHI);
+    opGradPhiG->setUhOld(phase);
+    prob->addVectorOperator(*opGradPhiG, dow);
+  }
+    
+  /// < grad(phi)*G(x) , psi >
+  if (bcFct != NULL) {
+    Operator *opGradPhiG = new Operator(prob->getFeSpace(dow),prob->getFeSpace(0));
+    opGradPhiG->addTerm(new VecFctAtQP_FOT(bcFct), GRD_PHI);
+    opGradPhiG->setUhOld(phase);
+    prob->addVectorOperator(*opGradPhiG, dow);
+  }
+  
+  // test for implicit boundary condition
+  if (bcFct == NULL) {
+    bool bcCond = false;
+    for (size_t i = 0; i < dow; i++)
+      bcCond = bcCond || bcDOF[i] != NULL;
+    TEST_EXIT(bcCond)("no implicit boundary condition specified!\n");
+  } else {
+    bool bcCond = false;
+    for (size_t i = 0; i < dow; i++)
+      bcCond = bcCond || bcDOF[i] != NULL;
+    TEST_EXIT(!bcCond)("implicit boundary condition specified twice, by bcFct and bcDOF. This is not allowed!\n");
+  }
+}
diff --git a/extensions/base_problems/NavierStokesPhase_TaylorHood.h b/extensions/base_problems/NavierStokesPhase_TaylorHood.h
new file mode 100644
index 0000000000000000000000000000000000000000..480fc8273de5b7fb02e694ee9aa0b585e1a1cdcf
--- /dev/null
+++ b/extensions/base_problems/NavierStokesPhase_TaylorHood.h
@@ -0,0 +1,136 @@
+/** \file NavierStokesPhase_TaylorHood.h */
+
+#ifndef NAVIER_STOKES_PHASE_TAYLOR_HOOD_H
+#define NAVIER_STOKES_PHASE_TAYLOR_HOOD_H
+
+#include "NavierStokes_TaylorHood.h"
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * Navier-Stokes problem in diffuse domain, using Taylor Hood elements
+ * 
+ * dt(phase*u_j) + phase*u*grad(u_j) = phase*d_j(p) - nu*div(phase*grad(u_j)) - beta/eps^alpha (1-phase)*(u_j - g_j); j=1...d
+ * div(phase*u) = grad(phase)*g
+ */
+class NavierStokesPhase_TaylorHood : public NavierStokes_TaylorHood
+{
+public: // typedefs
+
+  typedef NavierStokes_TaylorHood super;
+
+public: // methods
+
+  NavierStokesPhase_TaylorHood(const std::string &name_);
+  ~NavierStokesPhase_TaylorHood();
+  
+  virtual void initData();
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+  
+  // === getting/setting methods ===
+  
+  DOFVector<double> *getPhase()
+  {
+    return phase;
+  }
+
+  DOFVector<double> *getBcDOF(int i)
+  {
+    return bcDOF[i];
+  }
+  
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* getBcFct()
+  {
+    return bcFct;
+  }
+  
+  double getEpsilon()
+  {
+    return epsilon;
+  }
+  
+  void setPhase(DOFVector<double>* phase_)
+  {
+    phase = phase_;
+  }
+  
+  void setBcDOF(DOFVector<double>* bcDOF_i, int i)
+  {
+    bcDOF[i] = bcDOF_i;
+  }
+  
+  void setBcFct(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_)
+  {
+    bcFct = fct_;
+  }
+
+  void setEpsilon(double epsilon_)
+  {
+    epsilon = epsilon_;
+  }
+
+// protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+  virtual void addLaplaceTerm(int i);
+
+private: // variables
+  
+  double dbc_factor; // beta/epsilon^alpha
+  double beta;
+  double epsilon;
+  double alpha;
+
+  DOFVector<double> *phase;
+  DOFVector<double> *phaseOld;
+
+  WorldVector<DOFVector<double>*> bcDOF;
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* bcFct;
+  
+  FileWriter *fileWriterPhase;
+};
+
+
+struct ComponentExtractor : AbstractFunction<double, WorldVector<double> >
+{
+  ComponentExtractor(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_, int comp_, double factor_=1.0)
+  : AbstractFunction<double, WorldVector<double> >(fct_->getDegree()),
+    fct(fct_), 
+    comp(comp_),
+    factor(factor_) {}
+  
+  double operator()(const WorldVector<double>& x) const {
+    WorldVector<double> result = (*fct)(x);
+    return factor*result[comp];
+  }
+  
+private:
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* fct;
+  int comp;
+  double factor;
+};
+
+
+struct VecAndComponentExtractor : BinaryAbstractFunction<double, double, WorldVector<double> >
+{
+  VecAndComponentExtractor(AbstractFunction<WorldVector<double>, WorldVector<double> >* fct_, int comp_, double factor_=1.0)
+  : BinaryAbstractFunction<double, double, WorldVector<double> >(fct_->getDegree()+1),
+    fct(fct_), 
+    comp(comp_),
+    factor(factor_) {}
+  
+  double operator()(const double& vec, const WorldVector<double>& x) const {
+    WorldVector<double> result = (*fct)(x);
+    return factor*vec*result[comp];
+  }
+  
+private:
+  AbstractFunction<WorldVector<double>, WorldVector<double> >* fct;
+  int comp;
+  double factor;
+};
+
+#endif // NAVIER_STOKES_PHASE_TAYLOR_HOOD_H
diff --git a/extensions/base_problems/NavierStokes_Chorin.cc b/extensions/base_problems/NavierStokes_Chorin.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2547d23dbef28f45e27d192bfa31c367853a62a6
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_Chorin.cc
@@ -0,0 +1,594 @@
+#include "NavierStokes_Chorin.h"
+
+#define UPDATE_VELOCITY_SYSTEM
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokes_Chorin::NavierStokes_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_) :
+  ProblemInstatBase(name_,NULL),
+  initialVelocityFcts(initialVelocityFcts_),
+  predictorProb(NULL), 
+  pressureProb(NULL), 
+  correctorProb(NULL),
+  calcPressure(false),
+  forceDBC(false),
+  initialVelocityIsSet(false),
+  oldMeshChangeIdx(0),
+  nTimesteps(-1),
+  simpleAlg(2),
+  poissonPertubation(0),
+  laplaceType(0),
+  nonLinTerm(2),
+  oldTimestep(0.0),
+  pressureStep(0.0),
+  viscosity(1.0),
+  c(0.0)
+{
+  dim = Global::getGeo(WORLD);
+
+  // create basic problems
+  predictorProb = new ProblemStatType(name + "->predictor");
+  pressureProb = new ProblemStatType(name + "->pressure");
+  correctorProb = new ProblemStatType(name + "->corrector");
+  
+  // set Pointer to main problem
+  nsProb = predictorProb;
+
+  // type of SIMPLE-algorithm
+  Initfile::get(name + "->simple algorithm",simpleAlg);
+//   if (simpleAlg < 1 || simpleAlg > 2)
+//     throw(std::runtime_error("SIMPLE-algorithm: Possible values in {1,2}!"));
+
+  // modification of the neumann-poisson-problem by additional pertubation or
+  // fixing of one dirichlet-node. Can be set to 0 if other dirichlet BC are set
+  Initfile::get(name + "->poisson problem pertubation", poissonPertubation);
+
+  // force the homogeniouse dirichlet BC if combination of dirichlet and neumann BC
+  // are set and AMDiS can not handle this combination automatically
+  Initfile::get(name + "->force dirichlet bc", forceDBC);
+
+
+  // parameters for navier-stokes
+  Initfile::get(name + "->viscosity", viscosity);
+  // type of laplace operator: 0... div(nu*grad(u)), 1... div(0.5*nu*(grad(u)+grad(u)^T))
+  Initfile::get(name + "->laplace operator", laplaceType); 
+  // type of non-linear term: 0... u^old*grad(u_i^old), 1... u'*grad(u_i^old), 2... u^old*grad(u'_i)
+  Initfile::get(name + "->non-linear term", nonLinTerm); 
+
+  force.set(0.0);
+  Initfile::get(name + "->force", force, DEBUG_INFO);
+};
+
+
+NavierStokes_Chorin::~NavierStokes_Chorin() 
+{ FUNCNAME("NavierStokes_Chorin::~NavierStokes_Chorin()");
+
+  if (calcPressure)
+    delete pressure;
+  if (initialVelocityIsSet) {
+    delete initialX;
+    delete initialY;
+  }
+};
+
+
+void NavierStokes_Chorin::initialize( Flag initFlag,
+                                      ProblemStatType *adoptProblem,
+                                      Flag adoptFlag)
+{ FUNCNAME("NavierStokes_Chorin::initialize()");
+
+  Flag localInitFlag = INIT_ALL - INIT_MESH - CREATE_MESH - INIT_FE_SPACE;
+  Flag localAdoptFlag = INIT_MESH + INIT_FE_SPACE;
+
+  predictorProb->initialize(initFlag, adoptProblem, adoptFlag);
+  pressureProb->initialize(localInitFlag, predictorProb, localAdoptFlag);
+  correctorProb->initialize(localInitFlag, predictorProb, localAdoptFlag);
+};
+
+
+void NavierStokes_Chorin::initTimeInterface()
+{
+MSG("NavierStokes_Chorin::initTimeInterface()\n");
+
+  for (int i = 0; i < boundaryDOF.getSize(); ++i)
+    boundaryDOF[i] = new DOFVector<double>(predictorProb->getFeSpace(i), "boundary_i");
+
+  fillOperators();
+  fillBoundaryConditions();
+};
+
+
+void NavierStokes_Chorin::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokes_Chorin::solveInitialProblem()");
+MSG("NavierStokes_Chorin::solveInitialProblem()\n");
+
+  if (initialVelocityFcts.size() > 0) {
+    initialVelocityIsSet = true;
+  
+    MSG("interpol initial velocity fcts (%d)...\n",initialVelocityFcts.size());
+    for (unsigned i = 0; i < dim; ++i) {
+      predictorProb->getSolution()->getDOFVector(i)->interpol(initialVelocityFcts[i]);
+      predictorProb->setExactSolutionFct(initialVelocityFcts[i], i);
+    }
+  }
+
+  // initial pressure
+  MSG("initial pressure...\n");
+  pressureProb->getSolution()->getDOFVector(0)->set(0.0);
+  pressureProb->setExactSolution(pressureProb->getSolution()->getDOFVector(0), 0);
+
+  // initial parameters for detecting mesh changes
+  MSG("oldMeshChangeIdx...\n");
+  oldMeshChangeIdx= predictorProb->getMesh()->getChangeIndex();
+
+  // calc pressure by normalization and correction of the value
+  MSG("pressureDOF...\n");
+  Initfile::get(name + "->calculate pressure", calcPressure);
+  if (calcPressure)
+    pressure= new DOFVector<double>(pressureProb->getFeSpace(0), "pressure");
+  
+  MSG("[finished]\n");
+};
+
+
+void NavierStokes_Chorin::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_Chorin::transferInitialSolution()");
+MSG("NavierStokes_Chorin::transferInitialSolution()\n");
+
+  for (unsigned i = 0; i < boundaryDOF.size(); ++i)
+    boundaryDOF[i]->copy(*predictorProb->getSolution()->getDOFVector(i));
+
+  if (abs(c) > DBL_TOL) {
+    INFO(DEBUG_INFO,2)("correct pressure...\n");
+    solvePressureProb(adaptInfo);
+  
+    INFO(DEBUG_INFO,2)("correct velocity...\n");
+    solveCorrectorProb(adaptInfo);
+  } else
+    correctorProb->getSolution()->copy(*predictorProb->getSolution());
+
+  predictorProb->setExactSolution(correctorProb->getSolution()->getDOFVector(0), 0);
+  predictorProb->setExactSolution(correctorProb->getSolution()->getDOFVector(1), 1);
+
+//   for (unsigned i = 0; i < boundaryDOF.size(); ++i)
+//     boundaryDOF[i]->copy(*correctorProb->getSolution()->getDOFVector(i));
+
+  writeFiles(adaptInfo, false);
+};
+
+
+void NavierStokes_Chorin::beginIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokes_Chorin::beginIteration()");
+MSG("NavierStokes_Chorin::beginIteration()\n");
+	
+  MSG("\n");
+  MSG("[[ Navier-Stokes iteration ]]\n");
+    
+  // assemble some blocks only once, if some conditions are fullfilled
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  bool fixedMatrixCell= false;
+  #else
+  bool fixedMatrixCell= adaptInfo->getTimestepNumber() > 0
+    && std::abs(adaptInfo->getTimestep() - oldTimestep) < DBL_TOL
+    && oldMeshChangeIdx == getMesh()->getChangeIndex();
+  #endif
+  for(unsigned i= 0; i < fixedMatrixTimestep.size(); ++i) {
+    predictorProb->setAssembleMatrixOnlyOnce(
+      fixedMatrixTimestep[i].first, 
+      fixedMatrixTimestep[i].second,
+      fixedMatrixCell);
+  }
+};
+
+
+Flag NavierStokes_Chorin::solvePredictorProb( AdaptInfo *adaptInfo, 
+                                              Flag toDo, 
+                                              bool fixedMatrix)
+{ FUNCNAME("NavierStokes_Chorin::solvePredictorProb()");
+MSG("NavierStokes_Chorin::solvePredictorProb()\n");
+
+  Flag markFlag;
+
+  if (toDo.isSet(BUILD)) {
+    predictorProb->getSolver()->setMultipleRhs(fixedMatrix);
+    predictorProb->buildAfterCoarsen(adaptInfo, markFlag,!fixedMatrix,true);
+  }
+
+  if (toDo.isSet(SOLVE))
+    predictorProb->solve(adaptInfo);
+
+  return markFlag;
+};
+
+
+Flag NavierStokes_Chorin::solvePressureProb(AdaptInfo *adaptInfo, 
+                                            Flag toDo, 
+                                            bool fixedMatrix)
+{ FUNCNAME("NavierStokes_Chorin::solvePressureProb()");
+
+  Flag markFlag;
+
+  if (toDo.isSet(BUILD)) {
+    pressureProb->getSolver()->setMultipleRhs(fixedMatrix);
+    pressureProb->buildAfterCoarsen(adaptInfo, markFlag,!fixedMatrix,true);
+
+    SolverMatrix<Matrix<DOFMatrix*> > solverMatrix;
+    if (!fixedMatrix && poissonPertubation > 0) {
+      INFO(DEBUG_INFO,2)("apply Matrix Pertubation(%d)...\n", poissonPertubation);
+      if (poissonPertubation == 1)
+        applySingularPertubation(pressureProb->getSystemMatrix(0,0)->getBaseMatrix());
+      else if (poissonPertubation == 2) {
+        WorldVector<double> p;
+        p[0]= 0.0;
+        p[1]= -1.0; //dimension[1];
+        getMesh()->dofCompress();
+        DegreeOfFreedom idx;
+	bool inside = pressureProb->getSolution()->getDOFVector(0)->getDofIdxAtPoint(p, idx);
+
+        if (inside) {
+          if (pressureProb->getSystemMatrix(0,0) != NULL)
+            applyDbc(pressureProb->getSystemMatrix(0,0)->getBaseMatrix(), *pressureProb->getRhsVector(0), idx, true, 0.0);
+        }
+      }
+
+      solverMatrix.setMatrix(*pressureProb->getSystemMatrix());
+      pressureProb->setSolverMatrix(solverMatrix);
+    }
+  }
+
+  if (toDo.isSet(SOLVE)) {
+    pressureProb->solve(adaptInfo);
+
+    if (calcPressure == 1) {
+      normalizePressure(pressureProb->getSolution()->getDOFVector(0), 0.0);
+      transformDOF(pressure,
+        pressureProb->getSolution()->getDOFVector(0),
+        pressure, new Add<double>);
+    }
+  }
+
+  return markFlag;
+};
+
+
+Flag NavierStokes_Chorin::solveCorrectorProb( AdaptInfo *adaptInfo, 
+                                              Flag toDo, 
+                                              bool fixedMatrix)
+{ FUNCNAME("NavierStokes_Chorin::solveCorrectorProb()");
+
+  Flag markFlag;
+
+  #if defined UPDATE_VELOCITY_DIRECT
+  DOFVector<double> *pressure_temp;
+  if (pressureProb->getFeSpace(0) != correctorProb->getFeSpace(0)) {
+    INFO(DEBUG_INFO,2)("create new DOFVector for pressure interpolation...\n");
+    pressure_temp = new DOFVector<double>(correctorProb->getFeSpace(0), "pressure");
+    pressure_temp->interpol(pressureProb->getSolution()->getDOFVector(0));
+  } else {
+    INFO(DEBUG_INFO,2)("use exististing DOFVector for pressure...\n");
+    pressure_temp = pressureProb->getSolution()->getDOFVector(0);
+  }
+
+  WorldVector<DOFVector<double>* > gradPressure;
+  for (int i = 0; i < gradPressure.getSize(); ++i)
+    gradPressure[i] = new DOFVector<double>(correctorProb->getFeSpace(0), "gradPressure_i");
+  DOFVector<WorldVector<double> > gradPressure_temp(correctorProb->getFeSpace(0), "gradPressure");
+
+  pressure_temp->getRecoveryGradient(&gradPressure_temp);
+  //     pressure_temp->getGradient(&gradPressure_temp);
+  INFO(DEBUG_INFO,2)("transform gradient of DOFVector...\n");
+  transform(&gradPressure_temp, &gradPressure);
+
+  for (int i = 0; i < gradPressure.getSize(); ++i) {
+    transformDOF(predictorProb->getSolution()->getDOFVector(i),
+      gradPressure[i],
+      correctorProb->getSolution()->getDOFVector(i), new Subtract<double>);
+  }
+  
+  // delete garbage
+  if(pressureProb->getFeSpace(0)!=correctorProb->getFeSpace(0))
+    delete pressure_temp;
+  for(int i= 0; i<gradPressure.getSize(); ++i)
+    delete gradPressure[i];
+  #else
+  correctorProb->getSolver()->setMultipleRhs(fixedMatrix);
+  correctorProb->buildAfterCoarsen(adaptInfo, markFlag,!fixedMatrix,true);
+  correctorProb->solve(adaptInfo);
+  #endif
+
+  return markFlag;
+};
+
+
+Flag NavierStokes_Chorin::oneIteration( AdaptInfo *adaptInfo, 
+                                        Flag toDo) 
+{ FUNCNAME("NavierStokes_Chorin::oneIteration()");
+
+  Flag flag, markFlag;
+
+  for (int i = 0; i < simpleAlg; i++) {
+    MSG("solve predictorProb...\n");
+    pressureStep = std::min(1.0, static_cast<double>(i));
+    bool fixedMatrixPredictor = adaptInfo->getTimestepNumber() > 0
+      && std::abs(adaptInfo->getTimestep() - oldTimestep) < DBL_TOL
+      && oldMeshChangeIdx == getMesh()->getChangeIndex();
+    solvePredictorProb(adaptInfo, toDo, false);
+
+    MSG("solve pressureProb...\n");
+    bool fixedMatrixPressure = oldMeshChangeIdx == getMesh()->getChangeIndex();
+    solvePressureProb(adaptInfo, toDo, false);
+  }
+
+  MSG("solve correctorProb...\n");
+  bool fixedMatrixCorrector = oldMeshChangeIdx == getMesh()->getChangeIndex();
+  solveCorrectorProb(adaptInfo, toDo, false);
+
+  if (calcPressure == 1)
+    pressureProb->getSolution()->getDOFVector(0)->copy(*pressure);
+
+  oldTimestep= adaptInfo->getTimestep();
+  oldMeshChangeIdx= getMesh()->getChangeIndex();
+
+  return flag;
+};
+
+
+void NavierStokes_Chorin::endIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokes_Chorin::endIteration()");
+	
+  MSG("\n");
+  MSG("[[ end of Navier-Stokes iteration ]]\n");
+};
+
+
+void NavierStokes_Chorin::clean()
+{ FUNCNAME("NavierStokes_Chorin::clean()");
+
+  // delete problems that are not necessary any more
+//   Helpers::cleanProblem(predictorProb);
+//   Helpers::cleanProblem(pressureProb);
+//   Helpers::cleanProblem(correctorProb, DELETE_ALL - DELETE_SOLUTION);
+};
+
+
+void NavierStokes_Chorin::normalizePressure(DOFVector<double> *p, 
+                                            double mean)
+{ FUNCNAME("NavierStokes_Chorin::normalizePressure()");
+
+  if (calcPressure != 1)
+    throw(std::runtime_error("Flag 'calc pressure' must be set to 1!"));
+
+  double intP = -1.0;
+  double area = 1.0;
+
+  if (!Helpers::isNumber(area) || area <= 0.0)
+    throw(std::runtime_error("Area must be > 0!\n"));
+
+  int i;
+  for (i= 0; abs(intP-mean) > 1.e-8 && i < 10; ++i) {
+    intP= p->Int();
+    if (!Helpers::isNumber(intP))
+      throw(std::runtime_error("pressureProb containes non-valid values!"));
+    transformDOF(p,(mean-intP)/area,p, new Add<double>);
+  }
+  MSG("normalizePressure... %d steps\n",i+1);
+};
+
+
+void NavierStokes_Chorin::fillOperators()
+{ FUNCNAME("NavierStokes_Chorin::fillOperators()");
+  MSG("NavierStokes_Chorin::fillOperators()\n");
+
+  fillPredictorProb();
+  fillPressureProb();
+  fillCorrectorProb();
+};
+
+
+void NavierStokes_Chorin::fillPredictorProb()
+{ FUNCNAME("NavierStokes_Chorin::fillPredictorProb()");
+  MSG("NavierStokes_Chorin::fillPredictorProb()\n");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (unsigned i = 0; i < dim; i++)
+    vel[i]= correctorProb->getSolution()->getDOFVector(i);
+
+  // fill operators for predictorProb
+  for (unsigned i = 0; i < dim; ++i) {
+    /// < (1/tau)*u'_i , psi >
+    Operator *opTime = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+    opTime->addZeroOrderTerm(new Simple_ZOT);
+    predictorProb->addMatrixOperator(*opTime, i, i, getInvTau());
+    /// < (1/tau)*u_i^old , psi >
+    opTime->setUhOld(correctorProb->getSolution()->getDOFVector(i));
+    predictorProb->addVectorOperator(*opTime, i, getInvTau());
+ 
+    if (nonLinTerm == 0) {
+      /// < u^old*grad(u_i^old) , psi >
+      Operator *opUGradU = new Operator(predictorProb->getFeSpace(i),predictorProb->getFeSpace(i));
+      opUGradU->addFirstOrderTerm(new WorldVec_FOT(vel, -1.0), GRD_PHI);
+      opUGradU->setUhOld(correctorProb->getSolution()->getDOFVector(i));
+      predictorProb->addVectorOperator(*opUGradU, i);
+    } else if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU = new Operator(predictorProb->getFeSpace(i),predictorProb->getFeSpace(i));
+        opUGradU->addZeroOrderTerm(new PartialDerivative_ZOT(
+          correctorProb->getSolution()->getDOFVector(i), j));
+        predictorProb->addMatrixOperator(*opUGradU, i, j);
+      }
+    } else {
+      /// < u^old*grad(u'_i) , psi >
+      for(unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU = new Operator(predictorProb->getFeSpace(i),predictorProb->getFeSpace(i));
+        opUGradU->addFirstOrderTerm(new VecAndPartialDerivative_FOT(
+          correctorProb->getSolution()->getDOFVector(j), j), GRD_PHI);
+        predictorProb->addMatrixOperator(*opUGradU, i, i);
+      }           
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) > TODO: Add boundary-integral for neumann-boundary
+    Operator *opGradP2 = new Operator(predictorProb->getFeSpace(i),pressureProb->getFeSpace(0));
+    opGradP2->addFirstOrderTerm(new PartialDerivative_FOT(i, -1.0), GRD_PHI);
+    opGradP2->setUhOld(pressureProb->getSolution()->getDOFVector(0));
+    predictorProb->addVectorOperator(*opGradP2, i, getPressureStep());
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+      opForce->addZeroOrderTerm(new Simple_ZOT(force[i]));
+      predictorProb->addVectorOperator(*opForce, i);
+    }
+  }
+};
+
+
+void NavierStokes_Chorin::fillPressureProb()
+{ FUNCNAME("NavierStokes_Chorin::fillPressureProb()");
+  MSG("NavierStokes_Chorin::fillPressureProb()\n");
+
+  // preassure-calculation: div(grad(p)) = 1/tau*div(u')
+  // -------------------------------------------------------------
+  for(unsigned i = 0; i < dim; ++i) {
+    /// < (1/tau)*d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(pressureProb->getFeSpace(0),predictorProb->getFeSpace(i));
+    opDivU->addZeroOrderTerm(new PartialDerivative_ZOT(
+      predictorProb->getSolution()->getDOFVector(i), i));
+    pressureProb->addVectorOperator(*opDivU, 0, getInvTau());
+  }
+  /// < -grad(p) , grad(psi) >
+  Operator *laplaceP = new Operator(pressureProb->getFeSpace(0), pressureProb->getFeSpace(0));
+  laplaceP->addSecondOrderTerm(new Simple_SOT(-1.0));
+  pressureProb->addMatrixOperator(*laplaceP, 0, 0);
+};
+
+
+void NavierStokes_Chorin::fillCorrectorProb()
+{ FUNCNAME("NavierStokes_Chorin::fillCorrectorProb()");
+  MSG("NavierStokes_Chorin::fillCorrectorProb()\n");
+
+  // corrector step: u = u' - tau*grad(p)
+  // ---------------------------------------
+  for(unsigned i = 0; i < dim; ++i) {
+    /// < u_i , psi >
+    Operator *opSimple = new Operator(correctorProb->getFeSpace(i),correctorProb->getFeSpace(i));
+    opSimple->addZeroOrderTerm(new Simple_ZOT);
+    correctorProb->addMatrixOperator(*opSimple, i, i);
+    /// < u'_i , psi >
+    opSimple->setUhOld(predictorProb->getSolution()->getDOFVector(i));
+    correctorProb->addVectorOperator(*opSimple, i);
+    /// < -tau*d_i(p) , psi >
+    Operator *opGradQ = new Operator(correctorProb->getFeSpace(i),pressureProb->getFeSpace(0));
+    opGradQ->addFirstOrderTerm(new PartialDerivative_FOT(i, -1.0), GRD_PHI);
+    opGradQ->setUhOld(pressureProb->getSolution()->getDOFVector(0));
+    correctorProb->addVectorOperator(*opGradQ, i, getTau());
+  }
+};
+
+
+void NavierStokes_Chorin::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokes_Chorin::addLaplaceTerm()");
+  MSG("NavierStokes_Chorin::addLaplaceTerm(%d)\n",i);
+
+    /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+    if (laplaceType == 1) {
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opLaplaceUi1 = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(j));
+        opLaplaceUi1->addSecondOrderTerm(new MatrixIJ_SOT(1-i, 1-j, viscosity));
+        predictorProb->addMatrixOperator(*opLaplaceUi1, i, j);
+      }
+    }
+    
+    /// < alpha*grad(u'_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(i));
+      opLaplaceUi->addSecondOrderTerm(new Simple_SOT(viscosity));
+    predictorProb->addMatrixOperator(*opLaplaceUi, i, i);
+};
+
+
+/// TODO: Boundary-Conditions verallgemeinern
+void NavierStokes_Chorin::fillBoundaryConditions()
+{ FUNCNAME("NavierStokes_Chorin::fillBoundaryConditions()");
+  MSG("NavierStokes_Chorin::fillBoundaryConditions()\n");
+
+  DOFVector<double> *zeroDOF = new DOFVector<double>(predictorProb->getFeSpace(0), "zero");
+  zeroDOF->set(0.0);
+
+  /// at rigid wall: no-slip boundary condition
+  for (unsigned j = 0; j < dim; ++j) {
+    predictorProb->addDirichletBC(LINKS, j, j, boundaryDOF[j]);
+    predictorProb->addDirichletBC(RECHTS, j, j, boundaryDOF[j]);
+  }
+  
+  /// at inflow: prescribed velocity
+  for (unsigned j = 0; j < dim; ++j) {
+   predictorProb->addDirichletBC(OBEN, j, j, boundaryDOF[j]);
+//    predictorProb->addDirichletBC(OBEN, j, j, predictorProb->getExactSolution(j)); /// test: Dirichlet-BC at outflow boundary
+  }
+  
+  /// at outflow: constant pressure
+  pressureProb->addDirichletBC(UNTEN, 0,0, zeroDOF);
+//   pressureProb->addDirichletBC(OBEN, 0,0, zeroDOF);
+
+
+  /// boundaryManager wird von Diagonale kopiert, wenn MatrixOperator hinzugefuegt wird -> erst MatrixOperatoren, danach erst BoundaryOperatoren
+//   for (unsigned i = 0; i < dim; ++i) {
+//     for (unsigned j = 0; j < dim; ++j) {
+//       Operator *opLaplaceBoundary = new Operator(predictorProb->getFeSpace(i), predictorProb->getFeSpace(j));
+//       opLaplaceBoundary->addFirstOrderTerm(new ViscosityPartialDerivativeBoundary_FOT(
+//         chProb.getSolution()->getDOFVector(0), i, j, viscosity1, viscosity2), GRD_PHI);
+//       for (unsigned b= 0; b < nsNeumannBC.size(); ++b) {
+//         if (nsNeumannBC[b] != 0) {
+//           predictorProb->addBoundaryMatrixOperator(nsNeumannBC[b], opLaplaceBoundary, i, j);
+//         }
+//       }
+//     }
+//   }
+};
+
+
+void NavierStokes_Chorin::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_Chorin::initTimestep()");
+
+  WorldVector<DOFVector<double>* > gradPressure;
+  for (int i = 0; i < gradPressure.getSize(); ++i)
+    gradPressure[i] = new DOFVector<double>(correctorProb->getFeSpace(0), "gradPressure_i");
+  DOFVector<WorldVector<double> > gradPressure_temp(correctorProb->getFeSpace(0), "gradPressure");
+
+  pressureProb->getSolution()->getDOFVector(0)->getRecoveryGradient(&gradPressure_temp);
+  transform(&gradPressure_temp, &gradPressure);
+
+  for (int i = 0; i < gradPressure.getSize(); ++i) {
+    transformDOF(predictorProb->getExactSolution(i),
+      gradPressure[i],
+      boundaryDOF[i], new AddFactor<double>(*getTau()));
+  }
+  
+  // delete garbage
+  for(int i= 0; i<gradPressure.getSize(); ++i)
+    delete gradPressure[i];
+};
+
+
+void NavierStokes_Chorin::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_Chorin::closeTimestep()");
+
+  int outputPeriod = 1;
+  Initfile::get("user parameter->write every ith timestep", outputPeriod, DEBUG_INFO);
+  if (adaptInfo->getTimestepNumber() % outputPeriod == 0
+    && adaptInfo->getStartTime() < adaptInfo->getEndTime()) {
+    writeFiles(adaptInfo, false);
+  }
+};
+
+
+void NavierStokes_Chorin::writeFiles(AdaptInfo *adaptInfo, bool force)
+{
+  predictorProb->writeFiles(adaptInfo, force);
+  pressureProb->writeFiles(adaptInfo, force);
+  correctorProb->writeFiles(adaptInfo, force);
+};
diff --git a/extensions/base_problems/NavierStokes_Chorin.h b/extensions/base_problems/NavierStokes_Chorin.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e3dff2fdff9c0d808b559fa871db90b710bdd0b
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_Chorin.h
@@ -0,0 +1,216 @@
+/** \file NavierStokes_Chorin.h */
+
+#ifndef NAVIER_STOKES_CHORIN_H
+#define NAVIER_STOKES_CHORIN_H
+
+#include "MyGlobal.h"
+#include "Helpers.h"
+#include "POperators.h"
+#include "BoundaryFunctions.h"
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/mtl/utility/property_map.hpp>
+
+
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_Chorin
+ * \brief
+ * Navier-Stokes problem, using projection method {
+ *       a.) Burgers equation (predictortProb)
+ *       b.) Pressure Poisson problem
+ *       c.) Burgers equation including pressure (predictorProb)
+ *       d.) Pressure Poisson problem
+ *       e.) Velocity update (correctorProb)
+ * }
+ */
+class NavierStokes_Chorin : public ProblemIterationInterface,
+                            public ProblemInstatBase
+{
+public:
+
+  NavierStokes_Chorin(const std::string &name_, WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts_);
+  ~NavierStokes_Chorin();
+
+  /// Initialisation of the problem.
+  virtual void initialize(Flag initFlag,
+                  ProblemStatType *adoptProblem = NULL,
+                  Flag adoptFlag = INIT_NOTHING);
+
+  virtual void initTimeInterface();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+
+  /// Implementation of ProblemTimeInterface::initTimestep().
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+
+  /// Implementation of ProblemTimeInterface::closeTimestep().
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  virtual void beginIteration(AdaptInfo *adaptInfo);
+  virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo= FULL_ITERATION);
+  virtual void endIteration(AdaptInfo *adaptInfo);
+
+  void clean();
+
+  // === getting methods ===
+
+  SystemVector *getSolution()
+  {
+    return correctorProb->getSolution();
+  }
+
+  double* getPressureStep() { return &pressureStep; }
+
+  inline Mesh* getMesh(int comp = 0) 
+  { FUNCNAME("NavierStokes_Chorin::getMesh()");
+
+    return predictorProb->getMesh(comp); 
+  }
+
+  std::string getName() { return name; };
+
+  int getNumProblems() { return 3; };
+
+  ProblemStatType *getProblem(int number= 0)
+  { FUNCNAME("NavierStokes_Chorin::getProblem()");
+
+    if (number == 0)
+      return predictorProb;
+    else if (number == 1)
+      return pressureProb;
+    else if (number == 2)
+      return correctorProb;
+    else
+      throw(std::runtime_error("problem with given number does not exist"));
+  };
+
+  ProblemStatType *getProblem(std::string name)
+  { FUNCNAME("NavierStokes_Chorin::getProblem()");
+
+    if (name == "correctorProb")
+      return correctorProb;
+    else if (name == "predictorProb")
+      return predictorProb;
+    else if (name == "pressureProb")
+      return pressureProb;
+    else
+      throw(std::runtime_error("problem with given name '" + name + "' does not exist"));
+  };
+
+  /// setting methods
+
+  void setAssembleMatrixOnlyOnce_butTimestepChange(int i, int j)
+  { FUNCNAME("NavierStokes_Chorin::setAssembleMatrixOnlyOnce_butTimestepChange()");
+
+    fixedMatrixTimestep.push_back(std::make_pair(i,j));
+  }
+
+  void setNumberOfTimesteps(int nTimesteps_)
+  { FUNCNAME("NavierStokes_Chorin::setNumberOfTimesteps()");
+
+    nTimesteps= nTimesteps_;
+  }
+
+  void writeFiles(AdaptInfo *adaptInfo, bool force);
+  void serialize(std::ostream&) {};
+  void deserialize(std::istream&) {};
+
+protected:
+
+  virtual Flag solvePredictorProb(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION, bool fixedMatrix = false);
+  virtual Flag solvePressureProb(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION, bool fixedMatrix = false);
+  virtual Flag solveCorrectorProb(AdaptInfo *adaptInfo, Flag toDo = FULL_ITERATION, bool fixedMatrix = false);
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+  
+  virtual void fillPredictorProb();
+  virtual void fillPressureProb();
+  virtual void fillCorrectorProb();
+  virtual void addLaplaceTerm(int i);
+
+private:
+
+  void normalizePressure(DOFVector<double> *p, double mean);
+
+  template <typename Matrix>
+  void applySingularPertubation(Matrix& m)
+  {
+	  using namespace mtl;
+	  typedef typename mtl::Collection<Matrix>::value_type value_type;
+	  int nnz= m.nnz_local(m.num_rows() - 1);
+	  matrix::inserter<Matrix, update_times<value_type> > ins(m, nnz);
+	  
+	  ins[m.num_rows() - 1][m.num_rows() - 1] << 1.0 + 1.e-5;
+  }
+
+
+  template <typename Matrix, typename Vector>
+  void applyDbc(Matrix& m, Vector& vec, DegreeOfFreedom idx, bool setDiagonal, double value)
+  {
+    using namespace mtl;
+    typename Matrix::size_type idx_= idx;
+
+    typename traits::row<Matrix>::type r(m);
+    typename traits::col<Matrix>::type c(m);
+    typename traits::value<Matrix>::type v(m);
+    typedef typename traits::range_generator<tag::row, Matrix>::type c_type;
+    typedef typename traits::range_generator<tag::nz, c_type>::type  ic_type;
+
+    for (c_type cursor(begin<tag::row>(m)+idx_), cend(begin<tag::row>(m) + idx_ + 1); cursor != cend; ++cursor) {
+        for (ic_type icursor(begin<tag::nz>(cursor)), icend(end<tag::nz>(cursor)); icursor != icend; ++icursor) {
+          v(*icursor, (r(*icursor) == c(*icursor) && setDiagonal ? 1.0 : 0.0));
+        }
+        break;
+    }
+
+    if (setDiagonal)
+      vec[idx]= value;
+  }
+
+protected:
+
+  ProblemStatType *predictorProb;
+  ProblemStatType *pressureProb;
+  ProblemStatType *correctorProb;
+
+  ProblemStatType *nsProb;
+
+  DOFVector<double> *pressure;
+  WorldVector<DOFVector<double>*> boundaryDOF;
+  AbstractFunction<double, WorldVector<double> > *initialX, *initialY;
+  WorldVector<AbstractFunction<double, WorldVector<double> >* > initialVelocityFcts;
+  WorldVector<DOFVector<double>*> initialVel;
+
+  bool forceDBC;
+  bool calcPressure;
+  bool initialVelocityIsSet;
+
+  unsigned dim;
+
+  int simpleAlg;
+  int nTimesteps;
+  int oldMeshChangeIdx;
+  int poissonPertubation;
+  int laplaceType;
+  int nonLinTerm;
+
+  double pressureStep;
+  double oldTimestep;
+  double viscosity;
+  double c;
+
+  WorldVector<double> force;
+
+  std::vector<std::pair<int,int> > fixedMatrixTimestep;
+
+private:
+
+};
+#endif // NAVIER_STOKES_CHORIN_H
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.cc b/extensions/base_problems/NavierStokes_TH_MultiPhase.cc
new file mode 100644
index 0000000000000000000000000000000000000000..93509542c5130c403d552d5eb73e58998e9f6303
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.cc
@@ -0,0 +1,159 @@
+#include "NavierStokes_TH_MultiPhase.h"
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokes_TH_MultiPhase::NavierStokes_TH_MultiPhase(const std::string &name_) :
+  super(name_),
+  multiPhase(NULL),
+  densityPhase(NULL),
+  viscosityPhase(NULL),
+  viscosity1(-1.0),
+  viscosity2(1.0),
+  density1(1.0),
+  density2(1.0)
+{
+  Initfile::get(name + "->viscosity1", viscosity1); // viscosity of fluid 1
+  Initfile::get(name + "->viscosity2", viscosity2); // viscosity of fluid 2
+  Initfile::get(name + "->density1", density1); // density of fluid 1
+  Initfile::get(name + "->density2", density2); // density of fluid 2
+
+  if (viscosity1 <= 0.0)
+    viscosity1 = viscosity;
+};
+
+
+NavierStokes_TH_MultiPhase::~NavierStokes_TH_MultiPhase()
+{ FUNCNAME("NavierStokes_TH_MultiPhase::~NavierStokes_TH_MultiPhase()");
+
+  delete multiPhase;
+  delete densityPhase;
+  delete viscosityPhase;
+};
+
+
+void NavierStokes_TH_MultiPhase::initData()
+{ FUNCNAME("NavierStokes_TH_MultiPhase::initTimeInterface()");
+
+  multiPhase = new DOFVector<double>(prob->getFeSpace(0), "multiPhase");
+  densityPhase = new DOFVector<double>(prob->getFeSpace(0), "densityPhase");
+  viscosityPhase = new DOFVector<double>(prob->getFeSpace(0), "viscosityPhase");
+
+  multiPhase->set(1.0);
+  densityPhase->set(density1);
+  viscosityPhase->set(viscosity1);
+
+  super::initData();
+};
+
+void NavierStokes_TH_MultiPhase::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TH_MultiPhase::initTimestep()");
+
+  super::initTimestep(adaptInfo);
+
+  transformDOF(multiPhase, densityPhase, new LinearInterpolation(density1, density2));
+  transformDOF(multiPhase, viscosityPhase, new LinearInterpolation(viscosity1, viscosity2));
+};
+
+
+void NavierStokes_TH_MultiPhase::fillOperators()
+{ FUNCNAME("NavierStokes_TH_MultiPhase::fillOperators()");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (unsigned i = 0; i < dim; i++)
+    vel[i]= prob->getSolution()->getDOFVector(i);
+
+  // fill operators for prob
+  for (unsigned i = 0; i < dim; ++i) {
+    /// < (1/tau)*rho*u'_i , psi >
+    Operator *opTime = new Operator(getFeSpace(i), getFeSpace(i));
+    opTime->addTerm(new VecAtQP_ZOT(densityPhase, NULL));
+    prob->addMatrixOperator(*opTime, i, i, getInvTau(), getInvTau());
+    /// < (1/tau)*rho*u_i^old , psi >
+    Operator *opTimeOld = new Operator(getFeSpace(i), getFeSpace(i));
+    opTimeOld->addTerm(new Vec2AtQP_ZOT(densityPhase, prob->getSolution()->getDOFVector(i), NULL));
+    prob->addVectorOperator(*opTimeOld, i, getInvTau(), getInvTau());
+ 
+    /// < u^old*grad(u_i^old) , psi >
+    Operator *opUGradU0 = new Operator(getFeSpace(i),getFeSpace(i));
+    opUGradU0->addTerm(new WorldVecPhase_FOT(densityPhase, vel, -1.0), GRD_PHI);
+    opUGradU0->setUhOld(prob->getSolution()->getDOFVector(i));
+    if (nonLinTerm == 0) {
+      prob->addVectorOperator(*opUGradU0, i);
+    } else {
+      prob->addVectorOperator(*opUGradU0, i, &theta1, &theta1);
+    }
+
+    if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU1 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU1->addTerm(new VecAndPartialDerivative_ZOT(
+          densityPhase,
+          prob->getSolution()->getDOFVector(i), j));
+        prob->addMatrixOperator(*opUGradU1, i, j, &theta, &theta);
+      }
+    } else if (nonLinTerm == 2) {
+      /// < u^old*grad(u'_i) , psi >
+      for(unsigned j = 0; j < dim; ++j) {
+        Operator *opUGradU2 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU2->addTerm(new Vec2ProductPartial_FOT(
+          densityPhase,
+          prob->getSolution()->getDOFVector(j), j), GRD_PHI);
+        prob->addMatrixOperator(*opUGradU2, i, i, &theta, &theta);
+      }
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(getFeSpace(i),getFeSpace(dim));
+    opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI);
+    prob->addMatrixOperator(*opGradP, i, dim);
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addZeroOrderTerm(new Phase_ZOT(densityPhase, force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+
+  /// div(u) = 0
+  for (unsigned i = 0; i < dim; ++i) {
+    /// < d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(getFeSpace(dim),getFeSpace(i));
+    opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI);
+    prob->addMatrixOperator(*opDivU, dim, i);
+  }
+};
+
+
+void NavierStokes_TH_MultiPhase::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokes_TH_MultiPhase::addLaplaceTerm()");
+
+  /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+  if (laplaceType == 1) {
+    for (unsigned j = 0; j < dim; ++j) {
+      Operator *opLaplaceUi1 = new Operator(getFeSpace(i), getFeSpace(j));
+      opLaplaceUi1->addTerm(new VecAtQP_IJ_SOT(
+        viscosityPhase, NULL, 1-i, 1-j));
+      prob->addMatrixOperator(*opLaplaceUi1, i, j, &theta, &theta);
+
+      Operator *opLaplaceUi1_rhs = new Operator(getFeSpace(i), getFeSpace(j));
+      opLaplaceUi1_rhs->addTerm(new Vec2AtQP_IJ_SOT(
+        viscosityPhase, prob->getSolution()->getDOFVector(j), NULL, 1-i, 1-j));
+      prob->addVectorOperator(*opLaplaceUi1_rhs, i, &minusTheta1, &minusTheta1);
+    }
+  }
+  
+  /// < alpha*grad(u'_i) , grad(psi) >
+  Operator *opLaplaceUi = new Operator(getFeSpace(i), getFeSpace(i));
+    opLaplaceUi->addTerm(new VecAtQP_SOT(viscosityPhase, NULL));
+  prob->addMatrixOperator(*opLaplaceUi, i, i, &theta, &theta);
+
+  Operator *opLaplaceUi_rhs = new Operator(getFeSpace(i), getFeSpace(i));
+    opLaplaceUi_rhs->addTerm(new Vec2AtQP_SOT(viscosityPhase, prob->getSolution()->getDOFVector(i), NULL));
+  prob->addVectorOperator(*opLaplaceUi_rhs, i, &minusTheta1, &minusTheta1);
+};
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase.h b/extensions/base_problems/NavierStokes_TH_MultiPhase.h
new file mode 100644
index 0000000000000000000000000000000000000000..780c331f0d3ec73e27634a383000a45852c9e8a3
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase.h
@@ -0,0 +1,126 @@
+/** \file NavierStokes_TH_MultiPhase.h */
+
+#ifndef NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
+#define NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
+
+#include "NavierStokes_TaylorHood.h"
+
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * Navier-Stokes multi-phase problem, using Taylor Hood elements
+ * Standard implementation for two phases, but can be extended to
+ * many more, by defining the multiPhase variable and overloading
+ * the initTimestep, where densityPhase and viscosityPhase are defined
+ * depending on the phases
+ */
+class NavierStokes_TH_MultiPhase : public NavierStokes_TaylorHood
+{
+public: // typedefs
+
+  typedef NavierStokes_TaylorHood super;
+
+public: // methods
+
+  NavierStokes_TH_MultiPhase(const std::string &name_);
+
+  /// deletes multiPhase, viscosityPhase and densityPhase
+  ~NavierStokes_TH_MultiPhase();
+
+  /** definition of constant multiPhase and const
+   * viscosity/density DOFVectors,
+   * initTimeInterface of super
+   **/
+  virtual void initData();
+
+  /** initTimestep of super and
+   * initialization of densityPhase and viscosityPhase
+   **/
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+
+  /** pointer to the multiPhase DOFVector, that
+   * indicates the different phases. Will be initialized
+   * in \ref initTimeInterface with const 1
+   **/
+  DOFVector<double> *getMultiPhase() { return multiPhase; }
+
+protected: // methods
+
+  virtual void fillOperators();
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+
+  ///viscosity of phase 1
+  double viscosity1;
+  
+  ///viscosity of phase 2
+  double viscosity2;
+  
+  ///density of phase 1
+  double density1;
+  
+  ///density of phase 2
+  double density2;
+
+  /// phase dependent density
+  DOFVector<double> *densityPhase;
+  
+  /// phase dependent viscosity
+  DOFVector<double> *viscosityPhase;
+  
+  /// phase inticator
+  DOFVector<double> *multiPhase;
+
+};
+
+
+/** linear interpolation between two values (like density, viscosity)
+ *  using a phase-field variable in [-1,1]
+ **/
+class LinearInterpolation : public AbstractFunction<double, double>
+{
+public:
+
+  LinearInterpolation(double val1_, double val2_) :
+    AbstractFunction<double, double>(1),
+    val1(val1_), val2(val2_) {}
+
+  double operator()(const double &phase) const { 
+    return 0.5*(phase+1.0)*val1 - 0.5*(phase-1.0)*val2;
+  }
+
+private:
+  
+  double val1;
+  double val2;
+};
+
+/** linear interpolation between two values (like density, viscosity)
+ *  using a phase-field variable in [0,1]
+ **/
+class LinearInterpolation0 : public AbstractFunction<double, double>
+{
+public:
+
+  LinearInterpolation0(double val1_, double val2_) :
+    AbstractFunction<double, double>(1),
+    val1(val1_), val2(val2_) {}
+
+  double operator()(const double &phase) const { 
+    return phase*val1 + (1.0-phase)*val2;
+  }
+
+private:
+  
+  double val1;
+  double val2;
+};
+
+#endif // NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc
new file mode 100644
index 0000000000000000000000000000000000000000..aaeee0fbf7486b36dfc6225d485f23f244b8a101
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.cc
@@ -0,0 +1,151 @@
+#include "NavierStokes_TH_MultiPhase_RB.h"
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokes_TH_MultiPhase_RB::NavierStokes_TH_MultiPhase_RB(const std::string &name_) :
+  super(name_),
+  multiPhase(NULL),
+  densityPhase(NULL),
+  viscosityPhase(NULL),
+  viscosity1(-1.0),
+  viscosity2(1.0),
+  density1(1.0),
+  density2(1.0)
+{
+  Initfile::get(name + "->viscosity1", viscosity1); // viscosity of fluid 1
+  Initfile::get(name + "->viscosity2", viscosity2); // viscosity of fluid 2
+  Initfile::get(name + "->density1", density1); // density of fluid 1
+  Initfile::get(name + "->density2", density2); // density of fluid 2
+
+  if (viscosity1 <= 0.0)
+    viscosity1 = viscosity;
+};
+
+
+NavierStokes_TH_MultiPhase_RB::~NavierStokes_TH_MultiPhase_RB()
+{ FUNCNAME("NavierStokes_TH_MultiPhase_RB::~NavierStokes_TH_MultiPhase_RB()");
+
+  delete multiPhase;
+  delete densityPhase;
+  delete viscosityPhase;
+};
+
+
+void NavierStokes_TH_MultiPhase_RB::initData()
+{ FUNCNAME("NavierStokes_TH_MultiPhase_RB::initTimeInterface()");
+
+  multiPhase = new DOFVector<double>(prob->getFeSpace(0), "multiPhase");
+  densityPhase = new DOFVector<double>(prob->getFeSpace(0), "densityPhase");
+  viscosityPhase = new DOFVector<double>(prob->getFeSpace(0), "viscosityPhase");
+
+  multiPhase->set(1.0);
+  densityPhase->set(density1);
+  viscosityPhase->set(viscosity1);
+
+  super::initData();
+};
+
+void NavierStokes_TH_MultiPhase_RB::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TH_MultiPhase_RB::initTimestep()");
+
+  super::initTimestep(adaptInfo);
+
+  transformDOF(multiPhase, densityPhase, new LinearInterpolation(density1, density2));
+  transformDOF(multiPhase, viscosityPhase, new LinearInterpolation(viscosity1, viscosity2));
+};
+
+
+void NavierStokes_TH_MultiPhase_RB::fillOperators()
+{ FUNCNAME("NavierStokes_TH_MultiPhase_RB::fillOperators()");
+
+  WorldVector<DOFVector<double>* > vel;
+  for (unsigned i = 0; i < dim; i++)
+    vel[i]= prob->getSolution()->getDOFVector(i);
+
+  WorldVector<DOFVector<double>*> stage_velocity;
+  WorldVector<DOFVector<double>*> un_velocity;
+  for (unsigned i = 0; i < dow; ++i) {
+    stage_velocity[i] = prob->getStageSolution(i);
+    un_velocity[i] = prob->getUnVec(i);
+  }
+  
+  // fill operators for prob
+  for (unsigned i = 0; i < dim; ++i) {
+    /// < d_t(u_i) , psi >
+    Operator *opTime = new Operator(getFeSpace(i), getFeSpace(i));
+    opTime->addZeroOrderTerm(new VecAtQP_ZOT(densityPhase, NULL));
+    prob->addMatrixOperator(opTime, i, i, prob->getInvTauGamma(), prob->getInvTauGamma());
+
+    Operator *opTimeOld = new Operator(getFeSpace(i));
+    opTimeOld->addZeroOrderTerm(new Vec2AtQP_ZOT(densityPhase, prob->getTimeRhsVec(i), NULL));
+    prob->addVectorOperator(opTimeOld, i, &minus1, &minus1);
+
+    /// < u*grad(u_i) , psi >
+    Operator *opUGradU = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradU->addTerm(new WorldVecPhase_FOT(densityPhase, stage_velocity, -1.0), GRD_PHI);
+    opUGradU->setUhOld(stage_velocity[i]);
+    prob->addVectorOperator(*opUGradU, i);
+
+    Operator *opUGradV = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradV->addTerm(new WorldVecPhase_FOT(densityPhase, un_velocity, -1.0), GRD_PHI);
+    prob->addMatrixOperator(*opUGradV, i, i, &minus1, &minus1);
+
+    for (unsigned j = 0; j < dow; ++j) {
+      Operator *opVGradU = new Operator(getFeSpace(i), getFeSpace(j));
+      opVGradU->addTerm(new VecAndPartialDerivative_ZOT(densityPhase, un_velocity[i], j, -1.0));
+      prob->addMatrixOperator(*opVGradU, i, j, &minus1, &minus1);
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(getFeSpace(i),getFeSpace(dow));
+    opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI);
+    opGradP->setUhOld(prob->getStageSolution(dow));
+    prob->addVectorOperator(*opGradP, i);
+    prob->addMatrixOperator(*opGradP, i, dow, &minus1, &minus1);
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addZeroOrderTerm(new Phase_ZOT(densityPhase, force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+
+  /// div(u) = 0
+  for (unsigned i = 0; i < dow; ++i) {
+    /// < d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(getFeSpace(dow),getFeSpace(i));
+    opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI);
+    opDivU->setUhOld(stage_velocity[i]);
+    prob->addVectorOperator(*opDivU, dow);
+    prob->addMatrixOperator(*opDivU, dow, i, &minus1, &minus1);
+  }
+};
+
+
+void NavierStokes_TH_MultiPhase_RB::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokes_TH_MultiPhase_RB::addLaplaceTerm()");
+
+  /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+  if (laplaceType == 1) {
+    for (unsigned j = 0; j < dim; ++j) {
+      Operator *opLaplaceUi1 = new Operator(getFeSpace(i), getFeSpace(j));
+      opLaplaceUi1->addTerm(new VecAtQP_IJ_SOT(
+        viscosityPhase, NULL, 1-i, 1-j));
+      opLaplaceUi1->setUhOld(prob->getStageSolution(j));
+      prob->addVectorOperator(*opLaplaceUi1, i, &minus1, &minus1);
+      prob->addMatrixOperator(*opLaplaceUi1, i, j);
+    }
+  }
+  
+  /// < alpha*grad(u'_i) , grad(psi) >
+  Operator *opLaplaceUi = new Operator(getFeSpace(i), getFeSpace(i));
+    opLaplaceUi->addTerm(new VecAtQP_SOT(viscosityPhase, NULL));
+  opLaplaceUi->setUhOld(prob->getStageSolution(i));
+  prob->addVectorOperator(*opLaplaceUi, i, &minus1, &minus1);
+  prob->addMatrixOperator(*opLaplaceUi, i, i);
+};
diff --git a/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h
new file mode 100644
index 0000000000000000000000000000000000000000..95e335d8fc9d5a606efbcdb92fc23053ed9f16a8
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TH_MultiPhase_RB.h
@@ -0,0 +1,126 @@
+/** \file NavierStokes_TH_MultiPhase.h */
+
+#ifndef NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
+#define NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
+
+#include "NavierStokes_TaylorHood_RB.h"
+
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * Navier-Stokes multi-phase problem, using Taylor Hood elements
+ * Standard implementation for two phases, but can be extended to
+ * many more, by defining the multiPhase variable and overloading
+ * the initTimestep, where densityPhase and viscosityPhase are defined
+ * depending on the phases
+ */
+class NavierStokes_TH_MultiPhase_RB : public NavierStokes_TaylorHood_RB
+{
+public: // typedefs
+
+  typedef NavierStokes_TaylorHood_RB super;
+
+public: // methods
+
+  NavierStokes_TH_MultiPhase_RB(const std::string &name_);
+
+  /// deletes multiPhase, viscosityPhase and densityPhase
+  ~NavierStokes_TH_MultiPhase_RB();
+
+  /** definition of constant multiPhase and const
+   * viscosity/density DOFVectors,
+   * initTimeInterface of super
+   **/
+  virtual void initData();
+
+  /** initTimestep of super and
+   * initialization of densityPhase and viscosityPhase
+   **/
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+
+  /** pointer to the multiPhase DOFVector, that
+   * indicates the different phases. Will be initialized
+   * in \ref initTimeInterface with const 1
+   **/
+  DOFVector<double> *getMultiPhase() { return multiPhase; }
+
+protected: // methods
+
+  virtual void fillOperators();
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+
+  ///viscosity of phase 1
+  double viscosity1;
+  
+  ///viscosity of phase 2
+  double viscosity2;
+  
+  ///density of phase 1
+  double density1;
+  
+  ///density of phase 2
+  double density2;
+
+  /// phase dependent density
+  DOFVector<double> *densityPhase;
+  
+  /// phase dependent viscosity
+  DOFVector<double> *viscosityPhase;
+  
+  /// phase inticator
+  DOFVector<double> *multiPhase;
+
+};
+
+
+/** linear interpolation between two values (like density, viscosity)
+ *  using a phase-field variable in [-1,1]
+ **/
+class LinearInterpolation : public AbstractFunction<double, double>
+{
+public:
+
+  LinearInterpolation(double val1_, double val2_) :
+    AbstractFunction<double, double>(1),
+    val1(val1_), val2(val2_) {}
+
+  double operator()(const double &phase) const { 
+    return 0.5*(phase+1.0)*val1 - 0.5*(phase-1.0)*val2;
+  }
+
+private:
+  
+  double val1;
+  double val2;
+};
+
+/** linear interpolation between two values (like density, viscosity)
+ *  using a phase-field variable in [0,1]
+ **/
+class LinearInterpolation0 : public AbstractFunction<double, double>
+{
+public:
+
+  LinearInterpolation0(double val1_, double val2_) :
+    AbstractFunction<double, double>(1),
+    val1(val1_), val2(val2_) {}
+
+  double operator()(const double &phase) const { 
+    return phase*val1 + (1.0-phase)*val2;
+  }
+
+private:
+  
+  double val1;
+  double val2;
+};
+
+#endif // NAVIER_STOKES_TAYLOR_HOOD_MULTIPHASE_H
diff --git a/extensions/base_problems/NavierStokes_TaylorHood.cc b/extensions/base_problems/NavierStokes_TaylorHood.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b8d676bf1297324afba8ed8cc3eeadcbd7df67fc
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TaylorHood.cc
@@ -0,0 +1,249 @@
+#include "NavierStokes_TaylorHood.h"
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokes_TaylorHood::NavierStokes_TaylorHood(const std::string &name_) :
+  super(name_),
+  forceDBC(false),
+  initialVelocityIsSet(false),
+  laplaceType(0),
+  nonLinTerm(2),
+  oldTimestep(0.0),
+  viscosity(1.0),
+  density(1.0),
+  c(0.0),
+  theta(0.5),
+  theta1(0.5),
+  minusTheta1(-0.5),
+  velocity(NULL)
+{  
+  // force the homogeniouse dirichlet BC if combination of dirichlet and neumann BC
+  // are set and AMDiS can not handle this combination automatically
+  Initfile::get(name + "->force dirichlet bc", forceDBC);
+  if (forceDBC) {
+    int numDirichletPoints = 0;
+    Initfile::get("number of dirichlet points", numDirichletPoints);
+    dirichletPoints.resize(numDirichletPoints);
+    for (int i = 0; i < numDirichletPoints; i++)
+      Initfile::get("dirichlet point[" + Helpers::toString(i) + "]",dirichletPoints[i]);
+  }
+
+  // parameters for navier-stokes
+  Initfile::get(name + "->viscosity", viscosity);
+  Initfile::get(name + "->density", density);
+  // type of laplace operator: 0... div(nu*grad(u)), 1... div(0.5*nu*(grad(u)+grad(u)^T))
+  Initfile::get(name + "->laplace operator", laplaceType); 
+  // type of non-linear term: 0... u^old*grad(u_i^old), 1... u'*grad(u_i^old), 2... u^old*grad(u'_i)
+  Initfile::get(name + "->non-linear term", nonLinTerm); 
+
+  Initfile::get(name + "->theta", theta); 
+  theta1 = 1.0-theta;
+  minusTheta1 = -theta1;
+
+  force.set(0.0);
+  Initfile::get(name + "->force", force);
+
+  bool scaleMesh = false;
+  Initfile::get("mesh->scale mesh",scaleMesh);
+  if (scaleMesh) {
+    Initfile::get("mesh->scale",dimension);
+  } else
+    dimension.set(1.0);
+}
+
+
+NavierStokes_TaylorHood::~NavierStokes_TaylorHood() 
+{ FUNCNAME("NavierStokes_TaylorHood::~NavierStokes_TaylorHood()");
+
+  if (initialVelocityIsSet) {
+    delete initialX;
+    delete initialY;
+  }
+  if (velocity != NULL)
+    delete velocity;
+  delete fileWriter;
+}
+
+
+void NavierStokes_TaylorHood::initData()
+{ FUNCNAME("NavierStokes_TaylorHood::initTimeInterface()");
+
+  if (velocity == NULL)
+    velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
+  fileWriter = new FileVectorWriter(name + "->velocity->output", getFeSpace()->getMesh(), velocity);
+
+  super::initData();
+}
+
+
+void NavierStokes_TaylorHood::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokes_TaylorHood::solveInitialProblem()");
+
+  int initialVelocity = 0, flowDirection = 1;
+  Initfile::get(name + "->initial velocity", initialVelocity);
+  Initfile::get(name + "->initial velocity->value", c);
+  Initfile::get(name + "->initial velocity->flow direction", flowDirection);
+
+  std::vector<AbstractFunction<double, WorldVector<double> >*> initialFcts(2);
+  if (initialVelocity == 0) { // no initial velocity
+    initialFcts[0]= new ConstantFct(0.0);
+    initialFcts[1]= new ConstantFct(0.0);
+  } else if(initialVelocity == 1) { // constant inflow
+      initialFcts[flowDirection] = new ConstantFct(c);
+      initialFcts[1-flowDirection] = new ConstantFct(0.0);
+  } else if(initialVelocity == 2) { // parabolic inflow
+    double dist = -1.0;
+    Initfile::get(name + "->initial velocity->parabolic inflow->boundary dist", dist);
+    if (dist <= 0.0)
+      dist = 2.0*dimension[1-flowDirection];
+    initialFcts[flowDirection] = new ParabolicInflow(dist/2.0, c, flowDirection);
+    initialFcts[1-flowDirection] = new ConstantFct(0.0);
+  } else
+    throw(std::runtime_error("Unknown initial velocity."));
+
+  initialX = initialFcts[0];
+  initialY = initialFcts[1];
+  initialVelocityIsSet = true;
+  
+  MSG("solve initial problem...\n");
+  for (unsigned i = 0; i < dow; ++i) {
+    prob->getSolution()->getDOFVector(i)->interpol(initialFcts[i]);
+    prob->setExactSolutionFct(initialFcts[i], i);
+  }
+
+}
+
+
+void NavierStokes_TaylorHood::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood::transferInitialSolution()");
+
+  calcVelocity();
+  
+  for (int i = 0; i < dow; i++)
+    prob->setExactSolution(prob->getSolution()->getDOFVector(i), i);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+
+  // initial parameters for detecting mesh changes
+  oldMeshChangeIdx= getMesh()->getChangeIndex();
+}
+
+
+void NavierStokes_TaylorHood::fillOperators()
+{ FUNCNAME("NavierStokes_TaylorHood::fillOperators()");
+
+  // fill operators for prob
+  for (unsigned i = 0; i < dow; ++i) {
+    /// < (1/tau)*u'_i , psi >
+    Operator *opTime = new Operator(getFeSpace(i), getFeSpace(i));
+    opTime->addTerm(new Simple_ZOT(density));
+    prob->addMatrixOperator(*opTime, i, i, getInvTau(), getInvTau());
+    /// < (1/tau)*u_i^old , psi >
+    opTime->setUhOld(prob->getSolution()->getDOFVector(i));
+    prob->addVectorOperator(*opTime, i, getInvTau(), getInvTau());
+ 
+    /// < u^old*grad(u_i^old) , psi >
+    Operator *opUGradU0 = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradU0->addTerm(new WorldVector_FOT(velocity, -density), GRD_PHI);
+    opUGradU0->setUhOld(prob->getSolution()->getDOFVector(i));
+    if (nonLinTerm == 0) {
+      prob->addVectorOperator(*opUGradU0, i);
+    } else if (abs(theta1) > DBL_TOL) {
+      prob->addVectorOperator(*opUGradU0, i, &theta1, &theta1);
+    }
+
+    if (nonLinTerm == 1) {
+      /// < u'*grad(u_i^old) , psi >
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU1 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU1->addTerm(new PartialDerivative_ZOT(
+          prob->getSolution()->getDOFVector(i), j, density));
+        prob->addMatrixOperator(*opUGradU1, i, j, &theta, &theta);
+      }
+    } else if (nonLinTerm == 2) {
+      /// < u^old*grad(u'_i) , psi >
+      for(unsigned j = 0; j < dow; ++j) {
+        Operator *opUGradU2 = new Operator(getFeSpace(i),getFeSpace(i));
+        opUGradU2->addTerm(new VecAndPartialDerivative_FOT(
+          prob->getSolution()->getDOFVector(j), j, density), GRD_PHI);
+        prob->addMatrixOperator(*opUGradU2, i, i, &theta, &theta);
+      }
+    }
+
+    for (int j = 0; j < dow; ++j) {
+      Operator *opNull = new Operator(getFeSpace(i), getFeSpace(j));
+      opNull->addTerm(new Simple_ZOT(0.0));
+      prob->addMatrixOperator(*opNull, i, j);
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(getFeSpace(i),getFeSpace(dow));
+    opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI);
+    prob->addMatrixOperator(*opGradP, i, dow);
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addTerm(new Simple_ZOT(force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+
+  /// div(u) = 0
+  for (unsigned i = 0; i < dow; ++i) {
+    /// < d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(getFeSpace(dow),getFeSpace(i));
+    opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI);
+    prob->addMatrixOperator(*opDivU, dow, i);
+  }
+}
+
+
+void NavierStokes_TaylorHood::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokes_TaylorHood::addLaplaceTerm()");
+
+    /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+    if (laplaceType == 1) {
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opLaplaceUi1 = new Operator(getFeSpace(i), getFeSpace(j));
+        opLaplaceUi1->addTerm(new MatrixIJ_SOT(1-i, 1-j, viscosity));
+        prob->addMatrixOperator(*opLaplaceUi1, i, j, &theta, &theta);
+
+	if (abs(minusTheta1) > DBL_TOL) {
+	  opLaplaceUi1->setUhOld(prob->getSolution()->getDOFVector(j));
+	  prob->addVectorOperator(*opLaplaceUi1, i, &minusTheta1, &minusTheta1);
+	}
+      }
+    }
+    
+    /// < alpha*grad(u'_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(getFeSpace(i), getFeSpace(i));
+      opLaplaceUi->addTerm(new Simple_SOT(viscosity));
+    prob->addMatrixOperator(*opLaplaceUi, i, i, &theta, &theta);
+
+    if (abs(minusTheta1) > DBL_TOL) {
+      opLaplaceUi->setUhOld(prob->getSolution()->getDOFVector(i));
+      prob->addVectorOperator(*opLaplaceUi, i, &minusTheta1, &minusTheta1);
+    }
+}
+
+
+void NavierStokes_TaylorHood::fillBoundaryConditions()
+{ FUNCNAME("NavierStokes_TaylorHood::fillBoundaryConditions()");
+
+  ERROR("You have to implement some boundary conditions!\n");
+}
+
+
+void NavierStokes_TaylorHood::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood::closeTimestep()");
+
+  calcVelocity();
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+}
diff --git a/extensions/base_problems/NavierStokes_TaylorHood.h b/extensions/base_problems/NavierStokes_TaylorHood.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e78ae0215c9b42a3b855db947f1e80bb3bf9666
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TaylorHood.h
@@ -0,0 +1,103 @@
+/** \file NavierStokes_TaylorHood.h */
+
+#ifndef NAVIER_STOKES_TAYLOR_HOOD_H
+#define NAVIER_STOKES_TAYLOR_HOOD_H
+
+#include "AMDiS.h"
+#include "Helpers.h"
+#include "POperators.h"
+#include "BoundaryFunctions.h"
+#include "BaseProblem.h"
+#include "ExtendedProblemStat.h"
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/mtl/utility/property_map.hpp>
+
+// boundary numbers
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * Navier-Stokes problem, using Taylor Hood elements
+ */
+class NavierStokes_TaylorHood : public BaseProblem<ExtendedProblemStat>
+{
+public: // typedefs
+  
+  typedef BaseProblem<ExtendedProblemStat> super;
+  
+public: // methods
+
+  NavierStokes_TaylorHood(const std::string &name_);
+
+  /// if initialVelocityIsSet is true delete initialX and initialY
+  ~NavierStokes_TaylorHood();
+
+  virtual void initData();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  // === getting/setting methods ===
+
+  /// set dimension of the macro-mesh
+  void setDimension(WorldVector<double> dimension_) { dimension = dimension_; }
+
+  DOFVector<WorldVector<double> >* getVelocity()
+  {
+    if (velocity == NULL)
+      velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
+    return velocity;
+  }
+
+// protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+  
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+
+  AbstractFunction<double, WorldVector<double> > *initialX, *initialY;
+  WorldVector<DOFVector<double>*> initialVel;
+  std::vector<WorldVector<double> > dirichletPoints;
+
+  DOFVector<WorldVector<double> >* velocity;
+
+  void calcVelocity()
+  {
+    if (dow == 1)
+      transformDOF(prob->getSolution()->getDOFVector(0), velocity, new AMDiS::Vec1WorldVec<double>);
+    else if (dow == 2)
+      transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), velocity, new AMDiS::Vec2WorldVec<double>);
+    else if (dow == 3)
+      transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), velocity, new AMDiS::Vec3WorldVec<double>);
+  }
+
+  bool forceDBC;
+  bool initialVelocityIsSet;
+
+  int laplaceType;
+  int nonLinTerm;
+
+  double oldTimestep;
+  double viscosity;
+  double density;
+  double c;
+  double theta;
+  double theta1;
+  double minusTheta1;
+
+  WorldVector<double> force;
+  WorldVector<double> dimension;
+
+  FileVectorWriter *fileWriter;
+};
+#endif // NAVIER_STOKES_TAYLOR_HOOD_H
diff --git a/extensions/base_problems/NavierStokes_TaylorHood_RB.cc b/extensions/base_problems/NavierStokes_TaylorHood_RB.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c6bf53f7b9ec57d4516584dcc00c5d3e4e53917d
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TaylorHood_RB.cc
@@ -0,0 +1,265 @@
+#include "NavierStokes_TaylorHood_RB.h"
+
+using namespace std;
+using namespace AMDiS;
+
+NavierStokes_TaylorHood_RB::NavierStokes_TaylorHood_RB(const std::string &name_) :
+  super(name_),
+  forceDBC(false),
+  initialVelocityIsSet(false),
+  laplaceType(0),
+  nonLinTerm(2),
+  oldTimestep(0.0),
+  viscosity(1.0),
+  c(0.0),
+  minus1(-1.0),
+  velocity(NULL)
+{  
+  // force the homogeniouse dirichlet BC if combination of dirichlet and neumann BC
+  // are set and AMDiS can not handle this combination automatically
+  Initfile::get(name + "->force dirichlet bc", forceDBC);
+  if (forceDBC) {
+    int numDirichletPoints = 0;
+    Initfile::get("number of dirichlet points", numDirichletPoints);
+    dirichletPoints.resize(numDirichletPoints);
+    for (int i = 0; i < numDirichletPoints; i++)
+      Initfile::get("dirichlet point[" + Helpers::toString(i) + "]",dirichletPoints[i]);
+  }
+
+  // parameters for navier-stokes
+  Initfile::get(name + "->viscosity", viscosity);
+  // type of laplace operator: 0... div(nu*grad(u)), 1... div(0.5*nu*(grad(u)+grad(u)^T))
+  Initfile::get(name + "->laplace operator", laplaceType); 
+  // type of non-linear term: 0... u^old*grad(u_i^old), 1... u'*grad(u_i^old), 2... u^old*grad(u'_i)
+  Initfile::get(name + "->non-linear term", nonLinTerm); 
+
+  force.set(0.0);
+  Initfile::get(name + "->force", force);
+
+  bool scaleMesh = false;
+  Initfile::get("mesh->scale mesh",scaleMesh);
+  if (scaleMesh) {
+    Initfile::get("mesh->scale",dimension);
+  } else
+    dimension.set(1.0);
+}
+
+
+NavierStokes_TaylorHood_RB::~NavierStokes_TaylorHood_RB()
+{ FUNCNAME("NavierStokes_TaylorHood_RB::~NavierStokes_TaylorHood_RB()");
+
+  if (initialVelocityIsSet) {
+    delete initialX;
+    delete initialY;
+  }
+  if (velocity != NULL)
+    delete velocity;
+  delete fileWriter;
+}
+
+
+void NavierStokes_TaylorHood_RB::initData()
+{ FUNCNAME("NavierStokes_TaylorHood_RB::initTimeInterface()");
+
+  if (velocity == NULL)
+    velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
+  fileWriter = new FileVectorWriter(name + "->velocity->output", getFeSpace()->getMesh(), velocity);
+
+  super::initData();
+}
+
+
+void NavierStokes_TaylorHood_RB::solveInitialProblem(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood_RB::solveInitialProblem()");
+
+  int initialVelocity = 0, flowDirection = 1;
+  Initfile::get(name + "->initial velocity", initialVelocity);
+  Initfile::get(name + "->initial velocity->value", c);
+  Initfile::get(name + "->initial velocity->flow direction", flowDirection);
+
+  std::vector<AbstractFunction<double, WorldVector<double> >*> initialFcts(2);
+  if (initialVelocity == 0) { // no initial velocity
+    initialFcts[0]= new ConstantFct(0.0);
+    initialFcts[1]= new ConstantFct(0.0);
+  } else if(initialVelocity == 1) { // constant inflow
+      initialFcts[flowDirection] = new ConstantFct(c);
+      initialFcts[1-flowDirection] = new ConstantFct(0.0);
+  } else if(initialVelocity == 2) { // parabolic inflow
+    double dist = -1.0;
+    Initfile::get(name + "->initial velocity->parabolic inflow->boundary dist", dist);
+    if (dist <= 0.0)
+      dist = 2.0*dimension[1-flowDirection];
+    initialFcts[flowDirection] = new ParabolicInflow(dist/2.0, c, flowDirection);
+    initialFcts[1-flowDirection] = new ConstantFct(0.0);
+  } else
+    throw(std::runtime_error("Unknown initial velocity."));
+
+  initialX = initialFcts[0];
+  initialY = initialFcts[1];
+  initialVelocityIsSet = true;
+  
+  for (unsigned i = 0; i < dow; ++i) {
+    prob->setExactSolutionFct(initialFcts[i], i);
+  }
+}
+
+
+void NavierStokes_TaylorHood_RB::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood_RB::transferInitialSolution()");
+
+  MSG("solve initial problem...\n");
+  for (unsigned i = 0; i < dow; ++i) {
+    prob->getSolution()->getDOFVector(i)->interpol(prob->getExactSolutionFct(i));
+  }
+    
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), velocity, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), velocity, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), velocity, new AMDiS::Vec3WorldVec<double>);
+
+  for (int i = 0; i < dow; i++)
+    prob->setExactSolution(prob->getSolution()->getDOFVector(i), i);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+
+  // initial parameters for detecting mesh changes
+  oldMeshChangeIdx= getMesh()->getChangeIndex();
+}
+
+
+void NavierStokes_TaylorHood_RB::fillOperators()
+{ FUNCNAME("NavierStokes_TaylorHood_RB::fillOperators()");
+  MSG("NavierStokes_TaylorHood_RB::fillOperators()\n");
+
+  WorldVector<DOFVector<double>*> stage_velocity;
+  WorldVector<DOFVector<double>*> un_velocity;
+  for (unsigned i = 0; i < dow; ++i) {
+    stage_velocity[i] = prob->getStageSolution(i);
+    un_velocity[i] = prob->getUnVec(i);
+  }
+  
+  // fill operators for prob
+  for (unsigned i = 0; i < dow; ++i) {
+    /// < d_t(u_i) , psi >
+    prob->addTimeOperator(i, i);
+ 
+    /// < u*grad(u_i) , psi >
+    Operator *opUGradU = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradU->addTerm(new WorldVec_FOT(stage_velocity, -1.0), GRD_PHI);
+    opUGradU->setUhOld(stage_velocity[i]);
+    prob->addVectorOperator(*opUGradU, i);
+
+    Operator *opUGradV = new Operator(getFeSpace(i), getFeSpace(i));
+    opUGradV->addTerm(new WorldVec_FOT(un_velocity, -1.0), GRD_PHI);
+    prob->addMatrixOperator(*opUGradV, i, i, &minus1, &minus1);
+
+    for (unsigned j = 0; j < dow; ++j) {
+      Operator *opVGradU = new Operator(getFeSpace(i), getFeSpace(j));
+      opVGradU->addTerm(new PartialDerivative_ZOT(un_velocity[i], j, -1.0));
+      prob->addMatrixOperator(*opVGradU, i, j, &minus1, &minus1);
+    }
+
+    /// Diffusion-Operator (including Stress-Tensor for space-dependent viscosity)
+    addLaplaceTerm(i);
+  
+    /// < p , d_i(psi) >
+    Operator *opGradP = new Operator(getFeSpace(i),getFeSpace(dow));
+    opGradP->addTerm(new PartialDerivative_FOT(i, -1.0), GRD_PSI);
+    opGradP->setUhOld(prob->getStageSolution(dow));
+    prob->addVectorOperator(*opGradP, i);
+    prob->addMatrixOperator(*opGradP, i, dow, &minus1, &minus1);
+  
+    /// external force, i.e. gravitational force
+    if (norm(force) > DBL_TOL) {
+      Operator *opForce = new Operator(getFeSpace(i), getFeSpace(i));
+      opForce->addTerm(new Simple_ZOT(force[i]));
+      prob->addVectorOperator(*opForce, i);
+    }
+  }
+
+  /// div(u) = 0
+  for (unsigned i = 0; i < dow; ++i) {
+    /// < d_i(u'_i) , psi >
+    Operator *opDivU = new Operator(getFeSpace(dow),getFeSpace(i));
+    opDivU->addTerm(new PartialDerivative_FOT(i), GRD_PHI);
+    opDivU->setUhOld(stage_velocity[i]);
+    prob->addVectorOperator(*opDivU, dow);
+    prob->addMatrixOperator(*opDivU, dow, i, &minus1, &minus1);
+  }
+}
+
+
+void NavierStokes_TaylorHood_RB::addLaplaceTerm(int i)
+{ FUNCNAME("NavierStokes_TaylorHood_RB::addLaplaceTerm()");
+  MSG("NavierStokes_TaylorHood_RB::addLaplaceTerm(%d)\n",i);
+
+    /// < alpha*[grad(u)+grad(u)^t] , grad(psi) >
+    if (laplaceType == 1) {
+      for (unsigned j = 0; j < dow; ++j) {
+        Operator *opLaplaceUi1 = new Operator(getFeSpace(i), getFeSpace(j));
+        opLaplaceUi1->addTerm(new MatrixIJ_SOT(1-i, 1-j, viscosity));
+	opLaplaceUi1->setUhOld(prob->getStageSolution(j));
+	prob->addVectorOperator(*opLaplaceUi1, i, &minus1, &minus1);
+        prob->addMatrixOperator(*opLaplaceUi1, i, j);
+      }
+    }
+    
+    /// < alpha*grad(u'_i) , grad(psi) >
+    Operator *opLaplaceUi = new Operator(getFeSpace(i), getFeSpace(i));
+      opLaplaceUi->addTerm(new Simple_SOT(viscosity));
+    opLaplaceUi->setUhOld(prob->getStageSolution(i));
+    prob->addVectorOperator(*opLaplaceUi, i, &minus1, &minus1);
+    prob->addMatrixOperator(*opLaplaceUi, i, i);
+}
+
+
+void NavierStokes_TaylorHood_RB::fillBoundaryConditions()
+{ FUNCNAME("NavierStokes_TaylorHood_RB::fillBoundaryConditions()");
+
+  ERROR("You have to implement some boundary conditions!\n");
+
+//   DOFVector<double> *zeroDOF = new DOFVector<double>(prob->getFeSpace(0), "zero");
+//   zeroDOF->set(0.0);
+// 
+//   /// at rigid wall: no-slip boundary condition
+//   for (unsigned j = 0; j < dow; ++j) {
+//     prob->addDirichletBC(LINKS, j, j, boundaryDOF[j]);
+//     prob->addDirichletBC(RECHTS, j, j, boundaryDOF[j]);
+//   }
+//   
+//   /// at inflow: prescribed velocity
+//   for (unsigned j = 0; j < dow; ++j) {
+//    prob->addDirichletBC(OBEN, j, j, boundaryDOF[j]);
+// //    prob->addDirichletBC(OBEN, j, j, prob->getExactSolution(j)); /// test: Dirichlet-BC at outflow boundary
+//   }
+// 
+//   for (unsigned i = 0; i < dirichletPoints.size(); ++i) {
+//     for (unsigned row = 0; row < dow; row++) {
+//       prob->addSingularDirichletBC(dirichletPoints[i], row, row, 0.0);
+//     }
+//   }
+}
+
+
+void NavierStokes_TaylorHood_RB::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood_RB::initTimestep()");
+
+}
+
+
+void NavierStokes_TaylorHood_RB::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("NavierStokes_TaylorHood_RB::closeTimestep()");
+
+  if (dow == 1)
+    transformDOF(prob->getSolution()->getDOFVector(0), velocity, new AMDiS::Vec1WorldVec<double>);
+  else if (dow == 2)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), velocity, new AMDiS::Vec2WorldVec<double>);
+  else if (dow == 3)
+    transformDOF(prob->getSolution()->getDOFVector(0), prob->getSolution()->getDOFVector(1), prob->getSolution()->getDOFVector(2), velocity, new AMDiS::Vec3WorldVec<double>);
+
+  fileWriter->writeFiles(adaptInfo, false);
+  writeFiles(adaptInfo, false);
+}
diff --git a/extensions/base_problems/NavierStokes_TaylorHood_RB.h b/extensions/base_problems/NavierStokes_TaylorHood_RB.h
new file mode 100644
index 0000000000000000000000000000000000000000..56834b4fa24458dcaa8dafd4a226d4f50cabea60
--- /dev/null
+++ b/extensions/base_problems/NavierStokes_TaylorHood_RB.h
@@ -0,0 +1,109 @@
+/** \file NavierStokes_TaylorHood.h */
+
+#ifndef NAVIER_STOKES_TAYLOR_HOOD_H
+#define NAVIER_STOKES_TAYLOR_HOOD_H
+
+#include "AMDiS.h"
+#include "Helpers.h"
+#include "POperators.h"
+#include "BoundaryFunctions.h"
+#include "BaseProblem.h"
+#include "time/ExtendedRosenbrockStationary.h"
+#include <boost/numeric/mtl/mtl.hpp>
+#include <boost/numeric/mtl/utility/property_map.hpp>
+
+// boundary numbers
+#define LINKS 1
+#define RECHTS 2
+#define UNTEN 3
+#define OBEN 4
+
+using namespace AMDiS;
+
+/** \ingroup NavierStokes_TaylorHood
+ * \brief
+ * Navier-Stokes problem, using Taylor Hood elements
+ */
+class NavierStokes_TaylorHood_RB : public BaseProblem<ExtendedRosenbrockStationary>
+{
+public: // typedefs
+  
+  typedef BaseProblem<ExtendedRosenbrockStationary> super;
+  
+public: // methods
+
+  NavierStokes_TaylorHood_RB(const std::string &name_);
+
+  /// if initialVelocityIsSet is true delete initialX and initialY
+  ~NavierStokes_TaylorHood_RB();
+
+  virtual void initData();
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);  
+
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+  /// Implementation of ProblemTimeInterface::closeTimestep().
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  // === getting/setting methods ===
+
+  /// set dimension of the macro-mesh
+  void setDimension(WorldVector<double> dimension_) { dimension = dimension_; }
+
+  DOFVector<WorldVector<double> >* getVelocity()
+  {
+    if (velocity == NULL)
+      velocity = new DOFVector<WorldVector<double> >(getFeSpace(0), "velocity");
+    return velocity;
+  }
+
+// Rosenbrock methods
+//_________________________________________________________________________
+
+public:
+
+  void acceptTimestep() { prob->acceptTimestep(); }
+  void reset() { prob->reset(); }
+
+  void setRosenbrockMethod(RosenbrockMethod *method) { prob->setRosenbrockMethod(method); }
+  void setTau(double *ptr) { prob->setTau(ptr); }
+  void setTauGamma(double *ptr0, double *ptr1, double *ptr2, double *ptr3) { prob->setTauGamma(ptr0,ptr1,ptr2,ptr3); }
+
+  double* getTauGamma() { return prob->getTauGamma(); }
+  double* getMinusTauGamma() { return prob->getMinusTauGamma(); }
+  double* getInvTauGamma() { return prob->getInvTauGamma(); }
+  double* getMinusInvTauGamma() { return prob->getMinusInvTauGamma(); }
+  
+protected: // methods
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+  
+  virtual void addLaplaceTerm(int i);
+
+protected: // variables
+
+  AbstractFunction<double, WorldVector<double> > *initialX, *initialY;
+  WorldVector<DOFVector<double>*> initialVel;
+  std::vector<WorldVector<double> > dirichletPoints;
+
+  DOFVector<WorldVector<double> >* velocity;
+  
+  bool forceDBC;
+  bool initialVelocityIsSet;
+
+  int laplaceType;
+  int nonLinTerm;
+
+  double minus1;
+  double oldTimestep;
+  double viscosity;
+  double c;
+
+  WorldVector<double> force;
+  WorldVector<double> dimension;
+
+  FileVectorWriter *fileWriter;
+};
+#endif // NAVIER_STOKES_TAYLOR_HOOD_H
diff --git a/extensions/base_problems/PhaseFieldCrystal.cc b/extensions/base_problems/PhaseFieldCrystal.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b18b31560671a703a880036c3490543ef7fe3579
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal.cc
@@ -0,0 +1,266 @@
+#include "PhaseFieldCrystal.h"
+
+using namespace std;
+using namespace AMDiS;
+
+PhaseFieldCrystal::PhaseFieldCrystal(const std::string &name_) :
+  ProblemInstatBase(name_,NULL),
+  prob(NULL), 
+  useMobility(false),
+  oldMeshChangeIdx(0),
+  nTimesteps(-1),
+  oldTimestep(0.0),
+  tempParameter(-0.6),
+  r(-0.4),
+  rho0(1.0),
+  density(-0.1),
+  two(2.0),
+  minus2(-2.0)
+{
+  // create basic problems
+  prob = new ProblemStat(name + "->space");
+  
+  dow = Global::getGeo(WORLD);
+  
+  Parameters::get(name + "->r",r);
+  Parameters::get(name + "->rho0", rho0);
+  Parameters::get(name + "->density", density);
+  Parameters::get(name + "->use mobility", useMobility);
+  tempParameter= -(1.0+r);
+};
+
+
+PhaseFieldCrystal::~PhaseFieldCrystal() 
+{ FUNCNAME("PhaseFieldCrystal::~PhaseFieldCrystal()");
+};
+
+
+void PhaseFieldCrystal::initialize(Flag initFlag,
+                              ProblemStat *adoptProblem,
+                              Flag adoptFlag)
+{ FUNCNAME("PhaseFieldCrystal::initialize()");
+
+  prob->initialize(initFlag, adoptProblem, adoptFlag);
+  dim = getMesh()->getDim();
+};
+
+
+void PhaseFieldCrystal::initTimeInterface()
+{
+  fillOperators();
+  fillBoundaryConditions();
+};
+
+
+Flag PhaseFieldCrystal::initDataFromFile(AdaptInfo *adaptInfo)
+{ FUNCNAME("PhaseFieldCrystal::initDataFromFile()");
+
+  Flag initFlag;
+  int readDataFromFile = 0, readArhFiles = 0; 
+  Initfile::get("user parameter->read data from file", readDataFromFile);
+  Initfile::get("user parameter->read arh files", readArhFiles);
+  if (readDataFromFile == 0) return initFlag;
+          
+  std::string pfc_file = "";  
+  Initfile::get("user parameter->data file[pfc]", pfc_file);
+  // read data and mesh from arh-files
+  
+  if (pfc_file.length() > 0) { MSG_DBG("pfc...\n");
+    ArhReader::read(pfc_file, prob->getMesh(), 
+      prob->getSolution()->getDOFVector(0), 
+      prob->getSolution()->getDOFVector(1), 
+      prob->getSolution()->getDOFVector(2));
+    initFlag.setFlag(PFC_ADOPTED);
+    initFlag.setFlag(PFC_MESH_ADOPTED); }
+
+  return initFlag;
+};
+
+
+void PhaseFieldCrystal::solveInitialProblem(AdaptInfo *adaptInfo) 
+{ FUNCNAME("PhaseFieldCrystal::solveInitialProblem()");
+  MSG_DBG("PhaseFieldCrystal::solveInitialProblem()\n");
+
+  Flag initFlag = initDataFromFile(adaptInfo);
+};
+
+
+void PhaseFieldCrystal::transferInitialSolution(AdaptInfo *adaptInfo)
+{ FUNCNAME("PhaseFieldCrystal::transferInitialSolution()");
+
+  writeFiles(adaptInfo, false);
+};
+
+
+void PhaseFieldCrystal::beginIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("PhaseFieldCrystal::beginIteration()");
+	
+  MSG("\n");
+  MSG("[[ PFC iteration ]]\n");
+    
+  // assemble some blocks only once, if some conditions are fullfilled
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  bool fixedMatrixCell= false;
+  #else
+  bool fixedMatrixCell= adaptInfo->getTimestepNumber() > 0
+    && std::abs(adaptInfo->getTimestep() - oldTimestep) < DBL_TOL
+    && oldMeshChangeIdx == getMesh()->getChangeIndex();
+  #endif
+  for(unsigned i= 0; i < fixedMatrixTimestep.size(); ++i) {
+    prob->setAssembleMatrixOnlyOnce(
+      fixedMatrixTimestep[i].first, 
+      fixedMatrixTimestep[i].second,
+      fixedMatrixCell);
+  }
+};
+
+
+Flag PhaseFieldCrystal::oneIteration( AdaptInfo *adaptInfo, 
+                                      Flag toDo) 
+{ FUNCNAME("PhaseFieldCrystal::oneIteration()");
+
+  Flag flag, markFlag;
+  
+  if (toDo.isSet(MARK))
+    markFlag = prob->markElements(adaptInfo);
+  else
+    markFlag = 3;
+
+  // refine
+  if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_REFINED))
+    flag = prob->refineMesh(adaptInfo);  
+  // coarsen
+  if (toDo.isSet(ADAPT) && markFlag.isSet(MESH_COARSENED))
+    flag |= prob->coarsenMesh(adaptInfo);
+
+  #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+  MPI::COMM_WORLD.Barrier();
+  #endif
+
+  #ifndef NONLIN_PROBLEM
+  if (toDo.isSet(BUILD)) {    
+    prob->getSolver()->setMultipleRhs(false);
+    prob->buildAfterCoarsen(adaptInfo, markFlag, true, true);
+  }
+  #endif
+
+  if (toDo.isSet(SOLVE)) {
+    try {
+      MSG("solve prob..\n");
+      prob->solve(adaptInfo, false);
+    } catch(std::exception &e) {
+      WARNING(("Could not solve system. Simulation will be stoped here! UMFPACK-ERROR: " 
+        + std::string(e.what()) + "\n").c_str());
+      adaptInfo->setTime(adaptInfo->getEndTime());
+      adaptInfo->setTimestepNumber(adaptInfo->getNumberOfTimesteps());
+      return flag;
+    } catch(...) {
+      WARNING("Could not solve system. Simulation will be stoped here! Unknown ERROR\n");
+      adaptInfo->setTime(adaptInfo->getEndTime());
+      adaptInfo->setTimestepNumber(adaptInfo->getNumberOfTimesteps());
+      return flag;
+    }
+  }
+
+  if (toDo.isSet(ESTIMATE))
+    prob->estimate(adaptInfo);
+
+  oldTimestep = adaptInfo->getTimestep();
+  oldMeshChangeIdx = prob->getMesh()->getChangeIndex();
+
+  return flag;
+};
+
+
+void PhaseFieldCrystal::endIteration(AdaptInfo *adaptInfo) 
+{ FUNCNAME("NavierStokes_Chorin::endIteration()");
+	
+  MSG("\n");
+  MSG("[[ end of PFC iteration ]]\n");
+};
+
+
+void PhaseFieldCrystal::fillOperators()
+{ FUNCNAME("PhaseFieldCrystal::fillOperators()");
+  MSG_DBG("PhaseFieldCrystal::fillOperators()\n");
+  
+  // phi*rho
+  Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMnew->addTerm(new Simple_ZOT);
+  Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMold->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0), NULL));
+
+  // -nabla*(phi*grad(rho))
+  Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opL->addTerm(new Simple_SOT);
+  
+  Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  if (useMobility) // non-constant mobility
+    opLM->addTerm(new VecAtQP_SOT(
+      prob->getSolution()->getDOFVector(0),
+      new MobilityPfc(density, rho0)));
+  else // constant mobility
+    opLM->addTerm(new Simple_SOT);
+  
+  // -(1+r)*phi*rho
+  Operator *opMTemp = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMTemp->addZeroOrderTerm(new Simple_ZOT());
+  // -2*rho_old^3
+  Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowExpl->addZeroOrderTerm(new Pow3_ZOT(prob->getSolution()->getDOFVector(0),-2.0));
+  // -3*rho_old^2
+  Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowImpl->addZeroOrderTerm(new Pow2_ZOT(prob->getSolution()->getDOFVector(0),-3.0));
+  
+  // 0 = nu-laplace(rho)
+  // -------------------
+  prob->addMatrixOperator(opL, 0, 0); // -laplace(rho)
+  prob->addMatrixOperator(opMnew, 0, 2); // nu
+  
+  // dt(rho) = laplace(mu) - u*grad(rho)
+  // -----------------------------------
+  prob->addMatrixOperator(opMnew, 1, 0, getInvTau());
+  prob->addMatrixOperator(opLM, 1, 1); // -laplace(mu)
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(opMold, 1, getInvTau());
+  
+  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
+  // ----------------------------------------------------------------------
+  prob->addMatrixOperator(opMTemp, 2, 0, getTempParameter()); // -phi*(1+r)*rho
+  prob->addMatrixOperator(opMPowImpl, 2, 0); // -3*rho*rho_old^2
+  prob->addMatrixOperator(opL, 2, 0, &two); // -2*phi*laplace(rho) * psi
+  prob->addMatrixOperator(opMnew, 2, 1); // phi*mu * psi
+  prob->addMatrixOperator(opL, 2, 2); // phi*grad(nu) * grad(psi)
+  // prob.addMatrixOperator(opMnew,2,2,&minus2);
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(opMPowExpl, 2); // -2*phi^old*rho_old^3
+};
+
+
+void PhaseFieldCrystal::fillBoundaryConditions()
+{ FUNCNAME("PhaseFieldCrystal::fillBoundaryConditions()");
+  MSG_DBG("PhaseFieldCrystal::fillBoundaryConditions()\n");
+};
+
+
+void PhaseFieldCrystal::initTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("PhaseFieldCrystal::initTimestep()");
+};
+
+
+void PhaseFieldCrystal::closeTimestep(AdaptInfo *adaptInfo)
+{ FUNCNAME("PhaseFieldCrystal::closeTimestep()");
+
+  int outputPeriod = 1;
+  Initfile::get("user parameter->write every ith timestep", outputPeriod);
+  if (adaptInfo->getTimestepNumber() % outputPeriod == 0
+    && adaptInfo->getStartTime() < adaptInfo->getEndTime()) {
+    writeFiles(adaptInfo, false);
+  }
+};
+
+
+void PhaseFieldCrystal::writeFiles(AdaptInfo *adaptInfo, bool force)
+{
+  prob->writeFiles(adaptInfo, force);
+};
diff --git a/extensions/base_problems/PhaseFieldCrystal.h b/extensions/base_problems/PhaseFieldCrystal.h
new file mode 100644
index 0000000000000000000000000000000000000000..e277b7b9401c749f75028370a301148c6e0371fa
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal.h
@@ -0,0 +1,173 @@
+/** \file PhaseFieldCrystal.h */
+
+#ifndef PHASE_FIELD_CRYSTAL_H
+#define PHASE_FIELD_CRYSTAL_H
+
+#include "AMDiS.h"
+#include "MyProblemVec.h"
+#include "Helpers.h"
+#include "POperators.h"
+
+using namespace AMDiS;
+
+const Flag PFC_MESH_ADOPTED = 1<<2;
+const Flag PFC_ADOPTED = 1<<3;
+
+/** Phase-field Crystal problem
+ */
+class PhaseFieldCrystal : public ProblemIterationInterface,
+                          public ProblemInstatBase
+{
+public:
+
+  PhaseFieldCrystal(const std::string &name_);
+  ~PhaseFieldCrystal();
+
+  /// Initialisation of the problem.
+  virtual void initialize(Flag initFlag,
+                  ProblemStat *adoptProblem = NULL,
+                  Flag adoptFlag = INIT_NOTHING);
+  virtual void initTimeInterface();
+
+  virtual Flag initDataFromFile(AdaptInfo *adaptInfo);
+  virtual void solveInitialProblem(AdaptInfo *adaptInfo);
+  virtual void transferInitialSolution(AdaptInfo *adaptInfo);
+
+  /// Implementation of ProblemTimeInterface::initTimestep().
+  virtual void initTimestep(AdaptInfo *adaptInfo);
+
+  /// Implementation of ProblemTimeInterface::closeTimestep().
+  virtual void closeTimestep(AdaptInfo *adaptInfo);
+
+  virtual void beginIteration(AdaptInfo *adaptInfo);
+  virtual Flag oneIteration(AdaptInfo *adaptInfo, Flag toDo= FULL_ITERATION);
+  virtual void endIteration(AdaptInfo *adaptInfo);
+
+  /// getting methods
+  SystemVector *getSolution()
+  {
+    return prob->getSolution();
+  }
+
+  double *getTempParameter() { return &tempParameter; }
+
+  inline Mesh* getMesh(int comp = 0) 
+  {
+    return prob->getMesh(comp); 
+  }
+
+  inline FiniteElemSpace* getFeSpace(int comp = 0) 
+  {
+    return prob->getFeSpace(comp); 
+  }
+
+  std::string getName()
+  {
+    return name;
+  };
+
+  int getNumProblems() 
+  {
+    return 1;
+  };
+
+  ProblemStat *getProblem(int number= 0)
+  {
+    if (number<0 || number >= getNumProblems())
+      throw(std::runtime_error("problem with given number does not exist"));
+    if (number == 0)
+      return prob;
+  };
+
+  ProblemStat *getProblem(std::string name)
+  {
+    if (name == "pfc")
+      return prob;
+    else
+      throw(std::runtime_error("problem with given name '" + name + "' does not exist"));
+  };
+
+  /// setting methods
+
+  void setAssembleMatrixOnlyOnce_butTimestepChange(int i, int j)
+  {
+    fixedMatrixTimestep.push_back(std::make_pair(i,j));
+  }
+
+  void setNumberOfTimesteps(int nTimesteps_)
+  {
+    nTimesteps= nTimesteps_;
+  }
+
+  void writeFiles(AdaptInfo *adaptInfo, bool force);
+  void serialize(std::ostream&) {};
+  void deserialize(std::istream&) {};
+
+protected:
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+protected:
+
+  ProblemStat *prob;
+
+  bool useMobility;
+
+  unsigned dim;
+  unsigned dow;
+
+  int nTimesteps;
+  int oldMeshChangeIdx;
+
+  double oldTimestep;
+  double tempParameter;
+  double r;
+  double rho0;
+  double density;
+  double two;
+  double minus2;
+
+private:
+
+  std::vector<std::pair<int,int> > fixedMatrixTimestep;
+
+};
+
+
+/** \ingroup MainInstat
+ * \brief
+ * Abstract function to calculate the pure PFC-Energy
+ */
+class Energy : public BinaryAbstractFunction<double,double,double>
+{
+  public:
+    Energy() : BinaryAbstractFunction<double,double,double>(4) { }
+
+    double operator()(const double &rho, const double &mu) const {
+      return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; }
+};
+
+
+class MobilityPfc : public AbstractFunction<double,double>
+{
+  public:
+    MobilityPfc(double density_ = -0.3, double factor_ = 1.0) : 
+      AbstractFunction<double,double>(1),
+      density(density_),
+      factor(factor_),
+      delta(1.e-6) { }
+
+    double operator()(const double &rho) const 
+    {
+      double mobility= abs(rho - 3.0*density)*factor;
+      return std::max(mobility, delta);
+    }
+  
+  protected:
+    double density;
+    double factor;
+    double delta;
+};
+
+#endif // PHASE_FIELD_CRYSTAL_H
diff --git a/extensions/base_problems/PhaseFieldCrystal_Base.cc b/extensions/base_problems/PhaseFieldCrystal_Base.cc
new file mode 100644
index 0000000000000000000000000000000000000000..295c22df104ed9c040bbeefac14c0d88fba69789
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_Base.cc
@@ -0,0 +1,90 @@
+#include "PhaseFieldCrystal_Base.h"
+
+using namespace std;
+using namespace AMDiS;
+
+PhaseFieldCrystal::PhaseFieldCrystal(const std::string &name_) :
+  super(name_),
+  useMobility(false),
+  tempParameter(-0.6),
+  r(-0.4),		// temperature deviation
+  rho0(1.0),		// liquid density
+  density(-0.3),	// mean density
+  two(2.0),
+  minus2(-2.0)
+{  
+  Parameters::get(name + "->r",r);
+  Parameters::get(name + "->rho0", rho0);
+  Parameters::get(name + "->density", density);
+  Parameters::get(name + "->use mobility", useMobility);
+  tempParameter= -(1.0+r);
+};
+
+
+void PhaseFieldCrystal::fillOperators()
+{ FUNCNAME("PhaseFieldCrystal::fillOperators()");
+  
+  // phi*rho
+  Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMnew->addTerm(new Simple_ZOT);
+  Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMold->addTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0), NULL));
+
+  // -nabla*(phi*grad(rho))
+  Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opL->addTerm(new Simple_SOT);
+  
+  Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  if (useMobility) // non-constant mobility
+    opLM->addTerm(new VecAtQP_SOT(
+      prob->getSolution()->getDOFVector(0),
+      new MobilityPfc(density, rho0)));
+  else // constant mobility
+    opLM->addTerm(new Simple_SOT);
+  
+  // -(1+r)*phi*rho
+  Operator *opMTemp = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMTemp->addZeroOrderTerm(new Simple_ZOT());
+  // -2*rho_old^3
+  Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new Pow3Functor(-2.0)));
+  // -3*rho_old^2
+  Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(prob->getSolution()->getDOFVector(0),new Pow2Functor(-3.0)));
+  
+  // 0 = nu-laplace(rho)
+  // -------------------
+  prob->addMatrixOperator(opL, 0, 0); // -laplace(rho)
+  prob->addMatrixOperator(opMnew, 0, 2); // nu
+  setAssembleMatrixOnlyOnce_butTimestepChange(0,0);
+  setAssembleMatrixOnlyOnce_butTimestepChange(0,2);
+  
+  // dt(rho) = laplace(mu) - u*grad(rho)
+  // -----------------------------------
+  prob->addMatrixOperator(opMnew, 1, 0, getInvTau(), getInvTau());
+  prob->addMatrixOperator(opLM, 1, 1); // -laplace(mu)
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(opMold, 1, getInvTau(), getInvTau());
+  setAssembleMatrixOnlyOnce_butTimestepChange(1,0);
+  if (!useMobility)
+    setAssembleMatrixOnlyOnce_butTimestepChange(1,1);
+  
+  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
+  // ----------------------------------------------------------------------
+  prob->addMatrixOperator(opMTemp, 2, 0, getTempParameter(), getTempParameter()); // -phi*(1+r)*rho
+  prob->addMatrixOperator(opMPowImpl, 2, 0); // -3*rho*rho_old^2
+  prob->addMatrixOperator(opL, 2, 0, &two, &two); // -2*phi*laplace(rho) * psi
+  prob->addMatrixOperator(opMnew, 2, 1); // phi*mu * psi
+  prob->addMatrixOperator(opL, 2, 2); // phi*grad(nu) * grad(psi)
+  // prob.addMatrixOperator(opMnew,2,2,&minus2);
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(opMPowExpl, 2); // -2*phi^old*rho_old^3
+  
+  setAssembleMatrixOnlyOnce_butTimestepChange(2,1);
+  setAssembleMatrixOnlyOnce_butTimestepChange(2,2);
+};
+
+
+void PhaseFieldCrystal::fillBoundaryConditions()
+{ FUNCNAME("PhaseFieldCrystal::fillBoundaryConditions()");
+};
diff --git a/extensions/base_problems/PhaseFieldCrystal_Base.h b/extensions/base_problems/PhaseFieldCrystal_Base.h
new file mode 100644
index 0000000000000000000000000000000000000000..7e3937838e67a4d928b6f5ca848ac9a1c58ab465
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_Base.h
@@ -0,0 +1,109 @@
+/** \file PhaseFieldCrystal.h */
+
+#ifndef PHASE_FIELD_CRYSTAL_H
+#define PHASE_FIELD_CRYSTAL_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+
+using namespace AMDiS;
+
+/** Phase-field Crystal problem
+ */
+class PhaseFieldCrystal : public StandardBaseProblem
+{
+public: // typedefs
+
+  typedef StandardBaseProblem super;
+
+public:
+
+  PhaseFieldCrystal(const std::string &name_);
+  ~PhaseFieldCrystal() {};
+
+  double *getTempParameter() { return &tempParameter; }
+
+protected:
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+protected:
+
+  bool useMobility;
+
+  double tempParameter;
+  double r;
+  double rho0;
+  double density;
+  double two;
+  double minus2;
+};
+
+
+/** \ingroup MainInstat
+ * \brief
+ * Abstract function to calculate the pure PFC-Energy
+ */
+class Energy : public BinaryAbstractFunction<double,double,double>
+{
+  public:
+    Energy() : BinaryAbstractFunction<double,double,double>(4) { }
+
+    double operator()(const double &rho, const double &mu) const {
+      return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; }
+};
+
+
+class MobilityPfc : public AbstractFunction<double,double>
+{
+  public:
+    MobilityPfc(double density_ = -0.3, double factor_ = 1.0) : 
+      AbstractFunction<double,double>(1),
+      density(density_),
+      factor(factor_),
+      delta(1.e-6) { }
+
+    double operator()(const double &rho) const 
+    {
+      double mobility= abs(rho - 3.0*density)*factor;
+      return std::max(mobility, delta);
+    }
+  
+  protected:
+    double density;
+    double factor;
+    double delta;
+};
+
+class Pow2Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow2Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(2),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch);
+    }
+
+  protected:
+    double factor;
+};
+
+class Pow3Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow3Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(3),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch) * ch;
+    }
+
+  protected:
+    double factor;
+};
+
+#endif // PHASE_FIELD_CRYSTAL_H
diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.cc b/extensions/base_problems/PhaseFieldCrystal_Phase.cc
new file mode 100644
index 0000000000000000000000000000000000000000..96978b149dceef1132e2cb30abac37b20d1df2c7
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_Phase.cc
@@ -0,0 +1,83 @@
+#include "PhaseFieldCrystal_Phase.h"
+
+using namespace std;
+using namespace AMDiS;
+
+PhaseFieldCrystal_Phase::PhaseFieldCrystal_Phase(const std::string &name_) :
+  PhaseFieldCrystal(name_),
+  phase(NULL),
+  phaseDisturbed(NULL)
+{};
+
+
+PhaseFieldCrystal_Phase::~PhaseFieldCrystal_Phase()
+{
+  delete phase;
+  delete phaseDisturbed;
+}
+
+
+void PhaseFieldCrystal_Phase::initTimeInterface()
+{ FUNCNAME("PhaseFieldCrystal_Phase::initTimeInterface()");
+
+  PhaseFieldCrystal::initTimeInterface();
+};
+
+
+void PhaseFieldCrystal_Phase::fillOperators()
+{ FUNCNAME("PhaseFieldCrystal_Phase::fillOperators()");
+  MSG_DBG("PhaseFieldCrystal_Phase::fillOperators()\n");
+  
+  // phi*rho
+  Operator *opMnew = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMnew->addTerm(new Phase_ZOT(phaseDisturbed));
+  Operator *opMold = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMold->addTerm(new Phase_ZOT(phaseDisturbed));
+
+  // -nabla*(phi*grad(rho))
+  Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opL->addTerm(new Phase_SOT(phaseDisturbed));
+  
+  Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  if (useMobility) // non-constant mobility
+      opLM->addTerm(new Vec2AtQP_SOT(
+        phaseDisturbed,
+        prob->getSolution()->getDOFVector(0),
+        new MobilityPhasePfc(density, rho0)));
+  else // constant mobility
+      opLM->addTerm(new Phase_SOT(phaseDisturbed));
+  
+  // -(1+r)*phi*rho
+  Operator *opMTemp = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMTemp->addZeroOrderTerm(new Phase_ZOT(phaseDisturbed));
+  // -2*rho_old^3
+  Operator *opMPowExpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowExpl->addZeroOrderTerm(new Pow3Phase_ZOT(phaseDisturbed,prob->getSolution()->getDOFVector(0),-2.0));
+  // -3*rho_old^2
+  Operator *opMPowImpl = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opMPowImpl->addZeroOrderTerm(new Pow2Phase_ZOT(phaseDisturbed,prob->getSolution()->getDOFVector(0),-3.0));
+  
+  // 0 = nu-laplace(rho)
+  // -------------------
+  prob->addMatrixOperator(opL, 0, 0); // -laplace(rho)
+  prob->addMatrixOperator(opMnew, 0, 2); // nu
+
+  // dt(rho) = laplace(mu) - u*grad(rho)
+  // -----------------------------------
+  prob->addMatrixOperator(opMnew, 1, 0, getInvTau());
+  prob->addMatrixOperator(opLM, 1, 1); // -laplace(mu)
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  opMold->setUhOld(prob->getSolution()->getDOFVector(0));
+  prob->addVectorOperator(opMold, 1, getInvTau());
+  
+  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
+  // ----------------------------------------------------------------------
+  prob->addMatrixOperator(opMTemp, 2, 0, getTempParameter()); // -phi*(1+r)*rho
+  prob->addMatrixOperator(opMPowImpl, 2, 0); // -3*rho*rho_old^2
+  prob->addMatrixOperator(opL, 2, 0, &two); // -2*phi*laplace(rho) * psi
+  prob->addMatrixOperator(opMnew, 2, 1); // phi*mu * psi
+  prob->addMatrixOperator(opL, 2, 2); // phi*grad(nu) * grad(psi)
+  // prob.addMatrixOperator(opMnew,2,2,&minus2);
+  // . . . vectorOperators . . . . . . . . . . . . . . .
+  prob->addVectorOperator(opMPowExpl, 2); // -2*phi^old*rho_old^3
+};
diff --git a/extensions/base_problems/PhaseFieldCrystal_Phase.h b/extensions/base_problems/PhaseFieldCrystal_Phase.h
new file mode 100644
index 0000000000000000000000000000000000000000..38bb9ef72bdb53a1121f769d3a500aa4d96af917
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_Phase.h
@@ -0,0 +1,85 @@
+/** \file PhaseFieldCrystal_Phase.h */
+
+#ifndef PHASE_FIELD_CRYSTAL_PHASE_H
+#define PHASE_FIELD_CRYSTAL_PHASE_H
+
+#include "PhaseFieldCrystal.h"
+#include "PhaseFieldConvert.h"
+
+using namespace AMDiS;
+
+/** Phase-field Crystal problem in diffuse domain
+ */
+class PhaseFieldCrystal_Phase : public PhaseFieldCrystal
+{
+public: // typedefs
+
+  typedef NavierStokes_Chorin super;
+
+public: // methods
+
+  PhaseFieldCrystal_Phase(const std::string &name_);
+  ~PhaseFieldCrystal_Phase();
+
+  void initTimeInterface();
+
+  DOFVector<double> *getPhase()
+  {
+    return phase;
+  }
+
+  void setPhase(DOFVector<double>* phase_)
+  {
+    if (phase == NULL)
+      phase = new DOFVector<double>(prob->getFeSpace(0), "phase");
+    if (phaseDisturbed == NULL)
+      phaseDisturbed = new DOFVector<double>(prob->getFeSpace(0), "phaseDisturbed");
+
+    phase->interpol(phase_);
+    transformDOF(phase, 1.e-6, phaseDisturbed, new Max<double>);
+  };
+
+protected: // methods
+
+  void fillOperators();
+
+private: // variables
+
+  DOFVector<double> *phase;
+  DOFVector<double> *phaseDisturbed;
+};
+
+
+///Abstract function to calculate the pure PFC-Energy
+class EnergyPhase : public TertiaryAbstractFunction<double,double,double,double>
+{
+  public:
+    EnergyPhase() : TertiaryAbstractFunction<double,double,double,double>(5) { }
+
+    double operator()(const double &phase, const double &rho, const double &mu) const {
+      return phase * (-0.25*sqr(sqr(rho)) + 0.5*rho*mu); }
+};
+
+/// AbstractFunction that defines the pfc-mobility, depending on the density an minimal density
+class MobilityPhasePfc : public BinaryAbstractFunction<double,double,double>
+{
+  public:
+    MobilityPhasePfc(double density_ = -0.3, double factor_ = 1.0) : 
+      BinaryAbstractFunction<double,double,double>(2),
+      density(density_),
+      factor(factor_),
+      delta(1.e-6) { }
+
+    double operator()(const double &phase, const double &rho) const 
+    {
+      double mobility= abs(rho - 3.0*density)*factor;
+      return std::max(phase*mobility, delta);
+    }
+  
+  protected:
+    double density;
+    double factor;
+    double delta;
+};
+
+#endif // PHASE_FIELD_CRYSTAL_PHASE_H
diff --git a/extensions/base_problems/PhaseFieldCrystal_RB.cc b/extensions/base_problems/PhaseFieldCrystal_RB.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9f2935c93391ecbb5b0ee05d8163dc118713b9ae
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_RB.cc
@@ -0,0 +1,105 @@
+#include "PhaseFieldCrystal_RB.h"
+
+using namespace std;
+using namespace AMDiS;
+
+PhaseFieldCrystal::PhaseFieldCrystal(const std::string &name_) :
+  super(name_),
+  useMobility(false),
+  tempParameter(-0.6),
+  r(-0.4),		// temperature deviation
+  rho0(1.0),		// liquid density
+  density(-0.3),	// mean density
+  two(2.0),
+  minus2(-2.0),
+  minus1(-1.0)
+{  
+  Parameters::get(name + "->r",r);
+  Parameters::get(name + "->rho0", rho0);
+  Parameters::get(name + "->density", density);
+  Parameters::get(name + "->use mobility", useMobility);
+  tempParameter= -(1.0+r);
+};
+
+
+void PhaseFieldCrystal::fillOperators()
+{ FUNCNAME("PhaseFieldCrystal::fillOperators()");
+  
+  // rho
+  Operator *opMnu = new Operator(prob->getFeSpace(0), prob->getFeSpace(2));
+  opMnu->addTerm(new Simple_ZOT);
+  Operator *opMmu = new Operator(prob->getFeSpace(2), prob->getFeSpace(1));
+  opMmu->addTerm(new Simple_ZOT);
+  Operator *opMr = new Operator(prob->getFeSpace(2), prob->getFeSpace(0));
+  opMr->addTerm(new Simple_ZOT(tempParameter));
+
+  // -nabla*(grad(rho))
+  Operator *opL = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  opL->addTerm(new Simple_SOT);
+  Operator *opL2 = new Operator(prob->getFeSpace(2), prob->getFeSpace(0));
+  opL2->addTerm(new Simple_SOT(2.0));
+  Operator *opLnu = new Operator(prob->getFeSpace(2), prob->getFeSpace(2));
+  opLnu->addTerm(new Simple_SOT);
+  
+  Operator *opLM = new Operator(prob->getFeSpace(0), prob->getFeSpace(0));
+  if (useMobility) // non-constant mobility
+    opLM->addTerm(new VecAtQP_SOT(
+      prob->getSolution()->getDOFVector(0),
+      new MobilityPfc(density, rho0)));
+  else // constant mobility
+    opLM->addTerm(new Simple_SOT);
+  
+  // -rho_old^3
+  Operator *opMPowExpl = new Operator(prob->getFeSpace(2), prob->getFeSpace(0));
+  opMPowExpl->addZeroOrderTerm(new VecAtQP_ZOT(
+    prob->getStageSolution(0), new Pow3Functor(-1.0)));
+  // 3*rho_old^2
+  Operator *opMPowImpl = new Operator(prob->getFeSpace(2), prob->getFeSpace(0));
+  opMPowImpl->addZeroOrderTerm(new VecAtQP_ZOT(
+    prob->getUnVec(0), new Pow2Functor(3.0)));
+  
+  // 0 = nu-laplace(rho)
+  // -------------------
+  opL->setUhOld(prob->getStageSolution(0));
+  prob->addVectorOperator(opL, 0); 		// -laplace(rho)
+  prob->addMatrixOperator(opL, 0, 0, &minus1); 	// -laplace(rho)
+
+  opMnu->setUhOld(prob->getStageSolution(2));
+  prob->addVectorOperator(opMnu, 0); 			// nu
+  prob->addMatrixOperator(opMnu, 0, 2, &minus1); 	// nu
+  
+  // dt(rho) = laplace(mu) - u*grad(rho)
+  // -----------------------------------
+  prob->addTimeOperator(1, 0);	// dt(rho)
+
+  opLM->setUhOld(prob->getStageSolution(1));
+  prob->addVectorOperator(opLM, 1, &minus1); 	// -laplace(mu)
+  prob->addMatrixOperator(opLM, 1, 1); 		// -laplace(mu)
+  
+  // mu-2*nu-laplace(nu)-(1+r)*rho = (rho_old^3) + ExtPot - eps^2/(rho_old+0.9)
+  // ----------------------------------------------------------------------
+  opMr->setUhOld(prob->getStageSolution(0));
+  prob->addVectorOperator(opMr, 2); 		// -(1+r)*rho
+  prob->addMatrixOperator(opMr, 2, 0, &minus1); // -(1+r)*rho
+  
+  opL2->setUhOld(prob->getStageSolution(0));
+  prob->addVectorOperator(opL2, 2); 		// -2*laplace(rho)
+  prob->addMatrixOperator(opL2, 2, 0, &minus1); // -2*laplace(rho)
+
+  opMmu->setUhOld(prob->getStageSolution(1));
+  prob->addVectorOperator(opMmu, 2); 			// mu
+  prob->addMatrixOperator(opMmu, 2, 1, &minus1); 	// mu
+
+  opLnu->setUhOld(prob->getStageSolution(2));
+  prob->addVectorOperator(opLnu, 2); 			// -laplace(nu)
+  prob->addMatrixOperator(opLnu, 2, 2, &minus1); 	// -laplace(nu)
+
+  // . . . nonlinear terms . . . . . . . . . . . . . . .
+  prob->addMatrixOperator(opMPowImpl, 2, 0); 	// 3*rho*rho_old^2
+  prob->addVectorOperator(opMPowExpl, 2); 	// -rho'^3
+};
+
+
+void PhaseFieldCrystal::fillBoundaryConditions()
+{ FUNCNAME("PhaseFieldCrystal::fillBoundaryConditions()");
+};
diff --git a/extensions/base_problems/PhaseFieldCrystal_RB.h b/extensions/base_problems/PhaseFieldCrystal_RB.h
new file mode 100644
index 0000000000000000000000000000000000000000..5765706eb8cd0bc5d71647aa638b22cd3a1c5e9f
--- /dev/null
+++ b/extensions/base_problems/PhaseFieldCrystal_RB.h
@@ -0,0 +1,126 @@
+/** \file PhaseFieldCrystal.h */
+
+#ifndef PHASE_FIELD_CRYSTAL_H
+#define PHASE_FIELD_CRYSTAL_H
+
+#include "AMDiS.h"
+#include "BaseProblem.h"
+#include "time/RosenbrockStationary.h"
+
+using namespace AMDiS;
+
+/** Phase-field Crystal problem
+ */
+class PhaseFieldCrystal : public BaseProblem<RosenbrockStationary>
+{
+public: // typedefs
+
+  typedef BaseProblem<RosenbrockStationary> super;
+
+public:
+
+  PhaseFieldCrystal(const std::string &name_);
+  ~PhaseFieldCrystal() {};
+
+protected:
+
+  virtual void fillOperators();
+  virtual void fillBoundaryConditions();
+
+protected:
+
+  bool useMobility;
+
+  double tempParameter;
+  double r;
+  double rho0;
+  double density;
+  double two;
+  double minus2;
+  double minus1;
+
+// Rosenbrock methods
+//_________________________________________________________________________
+
+public:
+  
+  void acceptTimestep() { prob->acceptTimestep(); }
+  void reset() { prob->reset(); }
+  
+  void setRosenbrockMethod(RosenbrockMethod *method) { prob->setRosenbrockMethod(method); }
+  void setTau(double *ptr) { prob->setTau(ptr); }
+  void setTauGamma(double *ptr0, double *ptr1, double *ptr2, double *ptr3) { prob->setTauGamma(ptr0,ptr1,ptr2,ptr3); }
+
+  double* getTauGamma() { return prob->getTauGamma(); }
+  double* getMinusTauGamma() { return prob->getMinusTauGamma(); }
+  double* getInvTauGamma() { return prob->getInvTauGamma(); }
+  double* getMinusInvTauGamma() { return prob->getMinusInvTauGamma(); }
+};
+
+
+/** \ingroup MainInstat
+ * \brief
+ * Abstract function to calculate the pure PFC-Energy
+ */
+class Energy : public BinaryAbstractFunction<double,double,double>
+{
+  public:
+    Energy() : BinaryAbstractFunction<double,double,double>(4) { }
+
+    double operator()(const double &rho, const double &mu) const {
+      return -0.25*sqr(sqr(rho)) + 0.5*rho*mu; }
+};
+
+
+class MobilityPfc : public AbstractFunction<double,double>
+{
+  public:
+    MobilityPfc(double density_ = -0.3, double factor_ = 1.0) : 
+      AbstractFunction<double,double>(1),
+      density(density_),
+      factor(factor_),
+      delta(1.e-6) { }
+
+    double operator()(const double &rho) const 
+    {
+      double mobility= abs(rho - 3.0*density)*factor;
+      return std::max(mobility, delta);
+    }
+  
+  protected:
+    double density;
+    double factor;
+    double delta;
+};
+
+class Pow2Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow2Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(2),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch);
+    }
+
+  protected:
+    double factor;
+};
+
+class Pow3Functor : public AbstractFunction<double,double>
+{
+  public:
+    Pow3Functor(double factor_=1.0) :
+      AbstractFunction<double,double>(3),
+      factor(factor_) { }
+    double operator()(const double &ch) const
+    {
+      return factor * sqr(ch) * ch;
+    }
+
+  protected:
+    double factor;
+};
+
+#endif // PHASE_FIELD_CRYSTAL_H
diff --git a/extensions/kdtree_nanoflann.h b/extensions/kdtree_nanoflann.h
new file mode 100644
index 0000000000000000000000000000000000000000..97c882d970f6c9567097a4ad03ca260459e31ba9
--- /dev/null
+++ b/extensions/kdtree_nanoflann.h
@@ -0,0 +1,139 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2011 Jose Luis Blanco (joseluisblancoc@gmail.com).
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#include <nanoflann.hpp>
+
+#include <cstdlib>
+#include <iostream>
+
+#include "FixVec.h"
+
+using namespace nanoflann;
+using namespace AMDiS;
+
+namespace experimental {
+
+// =====================================================================================
+typedef std::vector<WorldVector<double> > my_vector_of_vectors_t;
+// =====================================================================================
+
+
+/** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage.
+  *  The i'th vector represents a point in the state space.
+  *
+  *  \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality for the points in the data set, allowing more compiler optimizations.
+  *  \tparam num_t The type of the point coordinates (typically, double or float).
+  *  \tparam Distance The distance metric to use: nanoflann::metric_L1, nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
+  *  \tparam IndexType The type for indices in the KD-tree index (typically, size_t of int)
+  */
+template <class VectorOfVectorsType, typename num_t = double, int DIM = -1, class Distance = nanoflann::metric_L2_Simple, typename IndexType = size_t>
+struct KDTreeVectorOfWorldVectorsAdaptor
+{
+	typedef KDTreeVectorOfWorldVectorsAdaptor<VectorOfVectorsType,num_t,DIM,Distance> self_t;
+	typedef typename Distance::template traits<num_t,self_t>::distance_t metric_t;
+	typedef KDTreeSingleIndexAdaptor< metric_t,self_t,DIM,IndexType>  index_t;
+
+	index_t* index; //! The kd-tree index for the user to call its methods as usual with any other FLANN index.
+
+	/// Constructor: takes a const ref to the vector of vectors object with the data points
+	KDTreeVectorOfWorldVectorsAdaptor(const int dimensionality, const VectorOfVectorsType &mat, const int leaf_max_size = 10) : m_data(mat)
+	{
+		assert(mat.size()!=0 && mat[0].getSize()!=0);
+		const size_t dims = mat[0].getSize();
+		if (DIM>0 && static_cast<int>(dims)!=DIM)
+			throw std::runtime_error("Data set dimensionality does not match the 'DIM' template argument");
+		index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+		index->buildIndex();
+	}
+
+	~KDTreeVectorOfWorldVectorsAdaptor() {
+		delete index;
+	}
+
+	const VectorOfVectorsType &m_data;
+
+	/** Query for the \a num_closest closest points to a given point (entered as query_point[0:dim-1]).
+	  *  Note that this is a short-cut method for index->findNeighbors().
+	  *  The user can also call index->... methods as desired.
+	  * \note nChecks_IGNORED is ignored but kept for compatibility with the original FLANN interface.
+	  */
+	inline void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int nChecks_IGNORED = 10) const
+	{
+		nanoflann::KNNResultSet<typename VectorOfVectorsType::Scalar,IndexType> resultSet(num_closest);
+		resultSet.init(out_indices, out_distances_sq);
+		index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
+	}
+
+	/** @name Interface expected by KDTreeSingleIndexAdaptor
+	  * @{ */
+
+	const self_t & derived() const {
+		return *this;
+	}
+	self_t & derived()       {
+		return *this;
+	}
+
+	// Must return the number of data points
+	inline size_t kdtree_get_point_count() const {
+		return m_data.size();
+	}
+
+	// Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
+	inline num_t kdtree_distance(const num_t *p1, const size_t idx_p2,size_t size) const
+	{
+		num_t s=0;
+		for (size_t i=0; i<size; i++) {
+			const num_t d= p1[i]-m_data[idx_p2][i];
+			s+=d*d;
+		}
+		return s;
+	}
+
+	// Returns the dim'th component of the idx'th point in the class:
+	inline num_t kdtree_get_pt(const size_t idx, int dim) const {
+		return m_data[idx][dim];
+	}
+
+	// Optional bounding-box computation: return false to default to a standard bbox computation loop.
+	//   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
+	//   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
+	template <class BBOX>
+	bool kdtree_get_bbox(BBOX &bb) const {
+		return false;
+	}
+
+	/** @} */
+
+}; // end of KDTreeVectorOfVectorsAdaptor
+
+typedef KDTreeVectorOfWorldVectorsAdaptor< my_vector_of_vectors_t, double >  KD_Tree;
+
+} // end namespace experimental
+
+
diff --git a/extensions/kdtree_nanoflann_dof.h b/extensions/kdtree_nanoflann_dof.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e0f25454c0f1971256a4e87b808b065ceab3709
--- /dev/null
+++ b/extensions/kdtree_nanoflann_dof.h
@@ -0,0 +1,213 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2011 Jose Luis Blanco (joseluisblancoc@gmail.com).
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+/** \file kdtree_nanoflann_dof.h */
+
+#ifndef KDTREE_NANOFLANN_DOF_H
+#define KDTREE_NANOFLANN_DOF_H
+
+#include <nanoflann.hpp>
+
+#include <cstdlib>
+#include <iostream>
+
+#include "AMDiS.h"
+
+using namespace nanoflann;
+using namespace AMDiS;
+
+namespace experimental {
+
+// =====================================================================================
+typedef WorldVector<double> PointType;
+typedef DOFVector<PointType> my_vector_of_vectors_t;
+// =====================================================================================
+
+
+  /** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage.
+    *  The i'th vector represents a point in the state space.
+    *
+    *  \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality for the points in the data set, allowing more compiler optimizations.
+    *  \tparam value_type The type of the point coordinates (typically, double or float).
+    *  \tparam Distance The distance metric to use: nanoflann::metric_L1, nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
+    *  \tparam index_type The type for indices in the KD-tree index (typically, size_t of int)
+    */
+  template < class VectorOfVectorsType, 
+	    typename value_type = double, 
+	    int DIM = -1, 
+	    class Distance = nanoflann::metric_L2_Simple, 
+	    typename index_type = DegreeOfFreedom >
+  struct KDTreeVectorOfWorldVectorsAdaptor
+  {
+    typedef KDTreeVectorOfWorldVectorsAdaptor< VectorOfVectorsType, 
+						value_type, 
+						DIM, 
+						Distance > self_t;
+    typedef typename Distance::template traits<value_type, self_t>::distance_t metric_t;
+    typedef KDTreeSingleIndexAdaptor< metric_t, 
+				      self_t, 
+				      DIM, 
+				      index_type > index_t;
+
+    index_t* index; //! The kd-tree index for the user to call its methods as usual with any other FLANN index.
+
+    /// Constructor: takes a const ref to the vector of vectors object with the data points
+    KDTreeVectorOfWorldVectorsAdaptor(const int dimensionality, 
+				      VectorOfVectorsType &mat, 
+				      const int leaf_max_size = 10) : m_data(mat)
+    {
+      const size_t dims = (*mat.begin()).getSize();
+      assert(mat.getUsedSize() != 0 && dims != 0);
+      if (DIM > 0 && static_cast<int>(dims) != DIM)
+	throw std::runtime_error("Data set dimensionality does not match the 'DIM' template argument");
+      index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+      index->buildIndex();
+    }
+
+    ~KDTreeVectorOfWorldVectorsAdaptor() {
+      delete index;
+    }
+    
+    void reinit(const int leaf_max_size = 10)
+    {
+      delete index;
+      const size_t dims = (*m_data.begin()).getSize();
+      index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+      index->buildIndex();
+    }
+
+    VectorOfVectorsType &m_data;
+
+    /** Query for the \a num_closest closest points to a given point (entered as query_point[0:dim-1]).
+      *  Note that this is a short-cut method for index->findNeighbors().
+      *  The user can also call index->... methods as desired.
+      * \note nChecks_IGNORED is ignored but kept for compatibility with the original FLANN interface.
+      */
+    inline void query(const value_type *query_point, 
+		      const size_t num_closest, 
+		      index_type *out_indices, 
+		      value_type *out_distances_sq, 
+		      const int nChecks_IGNORED = 10) const
+    {
+      nanoflann::KNNResultSet<value_type, index_type> resultSet(num_closest);
+      resultSet.init(out_indices, out_distances_sq);
+      index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
+    }
+
+    /** @name Interface expected by KDTreeSingleIndexAdaptor
+      * @{ */
+
+    const self_t & derived() const {
+      return *this;
+    }
+    self_t & derived() {
+      return *this;
+    }
+
+    // Must return the number of data points
+    inline size_t kdtree_get_point_count() const {
+      return m_data.getUsedSize();
+    }
+
+    // Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
+    inline value_type kdtree_distance(const value_type *p1, 
+				      const index_type idx_p2, 
+				      size_t size) const
+    {
+      value_type s = 0.0;
+      for (size_t i = 0; i < size; i++) {
+	const value_type d = p1[i] - m_data[idx_p2][i];
+	s += d*d;
+      }
+      return s;
+    }
+
+    // Returns the dim'th component of the idx'th point in the class:
+    inline value_type kdtree_get_pt(const index_type idx, size_t dim) const {
+      return m_data[idx][dim];
+    }
+
+    // Optional bounding-box computation: return false to default to a standard bbox computation loop.
+    //   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
+    //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
+    template <class BBOX>
+    bool kdtree_get_bbox(BBOX &bb) const {
+      return false;
+    }
+
+    /** @} */
+    
+    
+    /**
+    * strategy and nrOfPoints are ignored
+    *  == evalAtPoint_simple
+    **/
+    template<typename T>
+    T evalAtPoint(DOFVector<T>& vec, PointType& x, int strategy = 0, int nrOfPoints = -1)
+    {
+      const size_t nnp = 1;
+      std::vector<DegreeOfFreedom> ret_indexes(nnp);
+      std::vector<double> out_dists_sqr(nnp);
+      nanoflann::KNNResultSet<double, DegreeOfFreedom> resultSet(nnp);
+      
+      double eps = 0.0;
+      Parameters::get("KD-Tree->eps",eps);
+      resultSet.init(&ret_indexes[0], &out_dists_sqr[0]);
+      index->findNeighbors(resultSet, x.begin(), nanoflann::SearchParams(10, eps));
+      
+      T value; nullify(value);
+      value = vec[ret_indexes[0]];
+      return value;
+    }
+
+  }; // end of KDTreeVectorOfVectorsAdaptor
+
+  typedef KDTreeVectorOfWorldVectorsAdaptor< my_vector_of_vectors_t, double >  KD_Tree;
+  static std::map<const FiniteElemSpace*, std::pair<int, KD_Tree*> > kdtreeMap;
+
+  inline KD_Tree* provideKDTree(const FiniteElemSpace* feSpace)
+  {
+    if (kdtreeMap.find(feSpace) != kdtreeMap.end()) {
+      if (kdtreeMap[feSpace].first != feSpace->getMesh()->getChangeIndex()) {
+	feSpace->getMesh()->getDofIndexCoords(feSpace, kdtreeMap[feSpace].second->m_data);
+	kdtreeMap[feSpace].second->reinit();
+	kdtreeMap[feSpace].first = feSpace->getMesh()->getChangeIndex();
+      }
+    } else {
+      DOFVector<WorldVector<double> >* coords = new DOFVector<WorldVector<double> >(feSpace, "coords");
+      feSpace->getMesh()->getDofIndexCoords(feSpace, *coords);
+      
+      KD_Tree* kdtree = new KD_Tree(Global::getGeo(WORLD), *coords);
+      kdtreeMap[feSpace] = std::make_pair(feSpace->getMesh()->getChangeIndex(), kdtree);
+    }
+
+    return kdtreeMap[feSpace].second;
+  }
+  
+} // end namespace
+
+#endif
diff --git a/extensions/kdtree_nanoflann_mesh.h b/extensions/kdtree_nanoflann_mesh.h
new file mode 100644
index 0000000000000000000000000000000000000000..dce0514ff9dbc98e61f6c2b02273bfe5aedf688b
--- /dev/null
+++ b/extensions/kdtree_nanoflann_mesh.h
@@ -0,0 +1,272 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2011 Jose Luis Blanco (joseluisblancoc@gmail.com).
+ *   All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+/** \file kdtree_nanoflann_mesh.h */
+
+#ifndef KDTREE_NANOFLANN_MESH_H
+#define KDTREE_NANOFLANN_MESH_H
+
+#include <nanoflann.hpp>
+
+#include <cstdlib>
+#include <iostream>
+
+#include "AMDiS.h"
+
+using namespace nanoflann;
+using namespace AMDiS;
+
+namespace experimental {
+
+// =====================================================================================
+typedef WorldVector<double> PointType;
+typedef boost::tuple<const MacroElement*, int, unsigned long> DataType;
+typedef std::vector<PointType> VectorOfPointsType;
+typedef std::vector<DataType> VectorOfDataType;
+// =====================================================================================
+
+
+  /** A simple vector-of-vectors adaptor for nanoflann, without duplicating the storage.
+    *  The i'th vector represents a point in the state space.
+    *
+    *  \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality for the points in the data set, allowing more compiler optimizations.
+    *  \tparam value_type The type of the point coordinates (typically, double or float).
+    *  \tparam Distance The distance metric to use: nanoflann::metric_L1, nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
+    *  \tparam index_type The type for indices in the KD-tree index (typically, size_t of int)
+    */
+  template < class VectorOfPointsType_, 
+	     class VectorOfDataType_,
+	     typename value_type = double, 
+	     int DIM = -1, 
+	     class Distance = nanoflann::metric_L2_Simple, 
+	     typename index_type = DegreeOfFreedom >
+  struct KDTreeMeshAdaptor
+  {
+    typedef KDTreeMeshAdaptor<  VectorOfPointsType_, 
+				value_type, 
+				DIM, 
+				Distance > self_t;
+    typedef typename Distance::template traits<value_type, self_t>::distance_t metric_t;
+    typedef KDTreeSingleIndexAdaptor< metric_t, 
+				      self_t, 
+				      DIM, 
+				      index_type > index_t;
+
+    index_t* index; //! The kd-tree index for the user to call its methods as usual with any other FLANN index.
+
+    /// Constructor: takes a const ref to the vector of vectors object with the data points
+    KDTreeVectorOfWorldVectorsAdaptor(const int dimensionality, 
+				      Mesh* mesh_,
+				      const int leaf_max_size = 10)
+    : mesh(mesh_)
+    {
+      const size_t dims = Global::getGeo(WORLD);
+      if (mesh->getNumberOfLeaves() == 0)
+	mesh->updateNumberOfLeaves();
+      
+      assert(mesh->getNumberOfLeaves() != 0 && dims != 0);
+      if (DIM > 0 && static_cast<int>(dims) != DIM)
+	throw std::runtime_error("Point dimensionality does not match the 'DIM' template argument");
+      
+      init();
+      
+      index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+      index->buildIndex();
+    }
+
+    ~KDTreeVectorOfWorldVectorsAdaptor() {
+      delete index;
+    }
+    
+    void init()
+    {
+      TraverseStack stack;
+      ElInfo *elInfo = stack.traverseFirst(mesh, -1, Mesh::CALL_LEAF_EL | Mesh::FILL_COORDS);
+
+      int dim = mesh->getDim();
+      while (elInfo) {
+	ElInfo* macroElInfo = mesh->createNewElInfo();
+	macroElInfo->fillMacroInfo(elInfo->getMacroElement());
+	stack.fillRefinementPath(*elInfo, *macroElInfo);
+
+	DataType elInfoData = boost::tuples::make_tuple(elInfo->getMacroElement(), elInfo->getRefinementPathLength(), elInfo->getRefinementPath());
+
+	WorldVector<double> centroid = elInfo->getCoord(0);
+	for (int i = 1; i < dim+1; i++)
+	  centroid += elInfo->getCoord(i);
+	centroid *= 1.0/(dim+1.0);
+
+	m_points.push_back(centroid);
+	m_data.push_back(elInfoData);
+
+	elInfo = stack.traverseNext(elInfo);
+      }
+    }
+    
+    void reinit(const int leaf_max_size = 10)
+    {
+      delete index;
+      const size_t dims = Global::getGeo(WORLD);
+      m_points.clear();
+      m_data.clear();
+      init();
+      index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+      index->buildIndex();
+    }
+
+    VectorOfPointsType_ &m_points;
+    VectorOfDataType_ &m_data;
+
+    /** Query for the \a num_closest closest points to a given point (entered as query_point[0:dim-1]).
+      *  Note that this is a short-cut method for index->findNeighbors().
+      *  The user can also call index->... methods as desired.
+      * \note nChecks_IGNORED is ignored but kept for compatibility with the original FLANN interface.
+      */
+    inline void query(const value_type *query_point, 
+		      const size_t num_closest, 
+		      index_type *out_indices, 
+		      value_type *out_distances_sq, 
+		      const int nChecks_IGNORED = 10) const
+    {
+      nanoflann::KNNResultSet<value_type, index_type> resultSet(num_closest);
+      resultSet.init(out_indices, out_distances_sq);
+      index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
+    }
+
+    /** @name Interface expected by KDTreeSingleIndexAdaptor
+      * @{ */
+
+    const self_t & derived() const {
+      return *this;
+    }
+    self_t & derived() {
+      return *this;
+    }
+
+    // Must return the number of data points
+    inline size_t kdtree_get_point_count() const {
+      return m_points.getUsedSize();
+    }
+
+    // Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
+    inline value_type kdtree_distance(const value_type *p1, 
+				      const index_type idx_p2, 
+				      size_t size) const
+    {
+      value_type s = 0.0;
+      for (size_t i = 0; i < size; i++) {
+	const value_type d = p1[i] - m_points[idx_p2][i];
+	s += d*d;
+      }
+      return s;
+    }
+
+    // Returns the dim'th component of the idx'th point in the class:
+    inline value_type kdtree_get_pt(const index_type idx, size_t dim) const {
+      return m_points[idx][dim];
+    }
+
+    // Optional bounding-box computation: return false to default to a standard bbox computation loop.
+    //   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
+    //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
+    template <class BBOX>
+    bool kdtree_get_bbox(BBOX &bb) const {
+      return false;
+    }
+
+    /** @} */
+    
+    
+    /**
+    * strategy and nrOfPoints are ignored
+    *  == evalAtPoint_simple
+    **/
+    template<typename T>
+    T evalAtPoint(DOFVector<T>& vec, PointType& x, int strategy = 0, int nrOfPoints = -1)
+    {
+      ElInfo* elInfo = vec.getFeSpace()->getMesh()->createNewElInfo();
+      elInfo->setFillFlag(Mesh::FILL_COORDS);
+      T value; nullify(value);
+      if (getNearestElInfo(x, elInfo)) {
+	int dim = vec.getFeSpace()->getMesh()->getDim();
+	DimVec<double> lambda(dim, NO_INIT);
+	for (int i = 0; i < dim+1; i++)
+	  lambda[i] = 1.0/std::max(1.e-8, norm(x - elInfo->getCoord(i)));
+	// normalize barycentric coords
+	double sum = 0.0;
+	for (int i = 0; i < dim+1; i++)
+	  sum += lambda[i];
+	for (int i = 0; i < dim+1; i++)
+	  lambda[i] *= 1.0/sum;
+
+	ElementFunctionDOFVec<T> elFct(&vec);
+	elFct.setElInfo(elInfo);
+	value = elFct(lambda);
+      }
+      return value;
+    }
+    
+    
+    bool getNearestElInfo(PointType &x, ElInfo*& elInfo)
+    {
+      const size_t nnp = 1;
+      std::vector<DegreeOfFreedom> ret_indexes(nnp);
+      std::vector<double> out_dists_sqr(nnp);
+      nanoflann::KNNResultSet<double, DegreeOfFreedom> resultSet(nnp);
+      
+      resultSet.init(&ret_indexes[0], &out_dists_sqr[0]);
+      index->findNeighbors(resultSet, x.begin(), nanoflann::SearchParams());
+      
+      DataType data = m_data[ret_indexes[0]];
+      elInfo->fillElInfo(data.get<0>(), data.get<1>(), data.get<2>());
+      
+      return true;
+    }
+
+  }; // end of KDTreeMeshAdaptor
+
+  typedef KDTreeMeshAdaptor< VectorOfPointsType, VectorOfDataType, double >  KD_Tree;
+  static std::map<const FiniteElemSpace*, std::pair<int, KD_Tree*> > kdtreeMap;
+
+  inline KD_Tree* provideKDTree(const FiniteElemSpace* feSpace)
+  {
+    if (kdtreeMap.find(feSpace) != kdtreeMap.end()) {
+      if (kdtreeMap[feSpace].first != feSpace->getMesh()->getChangeIndex()) {
+	kdtreeMap[feSpace].second->reinit();
+	kdtreeMap[feSpace].first = feSpace->getMesh()->getChangeIndex();
+      }
+    } else {
+      KD_Tree* kdtree = new KD_Tree(Global::getGeo(WORLD), feSpace->getMesh());
+      kdtreeMap[feSpace] = std::make_pair(feSpace->getMesh()->getChangeIndex(), kdtree);
+    }
+
+    return kdtreeMap[feSpace].second;
+  }
+  
+} // end namespace
+
+#endif
diff --git a/extensions/nanoflann/CHANGELOG.txt b/extensions/nanoflann/CHANGELOG.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a33f5b632d4ff7ebe7c9787a68c328fd339dcf6b
--- /dev/null
+++ b/extensions/nanoflann/CHANGELOG.txt
@@ -0,0 +1,36 @@
+nanoflann 1.1.3: Released Jun 6, 2012
+  * GTest sources are now embedded, due to the changes in newer Ubuntu packages which don't carry the precompiled libs.
+  * Added asserts to detect whether the user passes NULL as query points.
+  * New method RadiusResultSet::worst_item()
+  * New method RadiusResultSet::set_radius_and_clear()
+  * Avoid potential collision of min/max macros with <windows.h>
+  * Removed unneeded #include's of std headers. 
+  * New sample code for vectors of vectors.
+  * Fixed building of tests for MSVC in Windows.
+  * Allow manually setting the path to Eigen3 (mainly for building examples under Windows).
+
+nanoflann 1.1.2: Released May 2, 2012
+  * Better documentation and added graphs of a benchmarking for helping choosing "leaf_max_size".
+  * Now KDTreeSingleIndexAdaptor::buildIndex() can be called several times 
+     even when the dataset size changes (Thanks to Rob McDonald for reporting!)
+
+nanoflann 1.1.1: Released Feb 1, 2012
+  * Some fixes to kd_tree index and L1/L2 metrics to allow distinct types 
+     in data elements and in the distances. This is mainly to permit elements 
+	 being vectors of integers (e.g. uint8_t) but distances being real numbers.
+  * Examples and unit tests have been corrected to use template arguments 
+     instead of being hard-wired to "float" data types (Thanks Thomas Vincent 
+	 for noticing!).
+
+nanoflann 1.1.0: Released Dec 15, 2011
+  * Fixed warnings for MSVC and for GCC with "-Wall -pedantic"
+  * Updated performance tests to work with the final nanoflann code (they were 
+     written for a very early version).
+  * All main classes now have new template arguments for the type of indice, 
+     which now defaults to "size_t" instead of "int". In case this breaks 
+     backward compatibility in user code, especify "int" to override the default 
+     template arguments, although "size_t" it's recommended.
+
+nanoflann 1.0.0: Released Aug 30, 2011
+  * Initial version
+
diff --git a/extensions/nanoflann/COPYING b/extensions/nanoflann/COPYING
new file mode 100644
index 0000000000000000000000000000000000000000..bdc4cfec258c46e93604320b80c59cfaa42156e7
--- /dev/null
+++ b/extensions/nanoflann/COPYING
@@ -0,0 +1,29 @@
+Software License Agreement (BSD License)
+
+Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+Copyright 2011 Jose L. Blanco (joseluisblancoc@gmail.com). All rights reserved.
+
+THE BSD LICENSE
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
diff --git a/extensions/nanoflann/nanoflann.hpp b/extensions/nanoflann/nanoflann.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b997a69ba49bdf977ec8c5d47054c44f6737fa6
--- /dev/null
+++ b/extensions/nanoflann/nanoflann.hpp
@@ -0,0 +1,1302 @@
+/***********************************************************************
+ * Software License Agreement (BSD License)
+ *
+ * Copyright 2008-2009  Marius Muja (mariusm@cs.ubc.ca). All rights reserved.
+ * Copyright 2008-2009  David G. Lowe (lowe@cs.ubc.ca). All rights reserved.
+ * Copyright 2011 Jose Luis Blanco (joseluisblancoc@gmail.com).
+ *   All rights reserved.
+ *
+ * THE BSD LICENSE
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *************************************************************************/
+
+#ifndef  NANOFLANN_HPP_
+#define  NANOFLANN_HPP_
+
+#include <vector>
+#include <cassert>
+#include <algorithm>
+#include <stdexcept>
+#include <cstdio>  // for fwrite()
+#include <cmath>   // for fabs(),...
+#include <limits>
+
+// Avoid conflicting declaration of min/max macros in windows headers
+#if !defined(NOMINMAX) && (defined(_WIN32) || defined(_WIN32_)  || defined(WIN32) || defined(_WIN64))
+# define NOMINMAX
+# ifdef max
+#  undef   max
+#  undef   min
+# endif
+#endif
+
+namespace nanoflann
+{
+/** @addtogroup nanoflann_grp nanoflann C++ library for ANN
+  *  @{ */
+
+  	/** Library version: 0xMmP (M=Major,m=minor,P=path) */
+	#define NANOFLANN_VERSION 0x113
+
+	/** @addtogroup result_sets_grp Result set classes
+	  *  @{ */
+	template <typename DistanceType, typename IndexType = size_t, typename CountType = size_t>
+	class KNNResultSet
+	{
+		IndexType * indices;
+		DistanceType* dists;
+		CountType capacity;
+		CountType count;
+
+	public:
+		inline KNNResultSet(CountType capacity_) : capacity(capacity_), count(0)
+		{
+		}
+
+		inline void init(IndexType* indices_, DistanceType* dists_)
+		{
+			indices = indices_;
+			dists = dists_;
+			count = 0;
+			dists[capacity-1] = (std::numeric_limits<DistanceType>::max)();
+		}
+
+		inline CountType size() const
+		{
+			return count;
+		}
+
+		inline bool full() const
+		{
+			return count == capacity;
+		}
+
+
+		inline void addPoint(DistanceType dist, IndexType index)
+		{
+			CountType i;
+			for (i=count; i>0; --i) {
+#ifdef NANOFLANN_FIRST_MATCH   // If defined and two poins have the same distance, the one with the lowest-index will be returned first.
+				if ( (dists[i-1]>dist) || ((dist==dists[i-1])&&(indices[i-1]>index)) ) {
+#else
+				if (dists[i-1]>dist) {
+#endif
+					if (i<capacity) {
+						dists[i] = dists[i-1];
+						indices[i] = indices[i-1];
+					}
+				}
+				else break;
+			}
+			if (i<capacity) {
+				dists[i] = dist;
+				indices[i] = index;
+			}
+			if (count<capacity) count++;
+		}
+
+		inline DistanceType worstDist() const
+		{
+			return dists[capacity-1];
+		}
+	};
+
+
+	/**
+	 * A result-set class used when performing a radius based search.
+	 */
+	template <typename DistanceType, typename IndexType = size_t>
+	class RadiusResultSet
+	{
+	public:
+		const DistanceType radius;
+
+		std::vector<std::pair<IndexType,DistanceType> >& m_indices_dists;
+
+		inline RadiusResultSet(DistanceType radius_, std::vector<std::pair<IndexType,DistanceType> >& indices_dists) : radius(radius_), m_indices_dists(indices_dists)
+		{
+			init();
+		}
+
+		inline ~RadiusResultSet() { }
+
+		inline void init() { clear(); }
+		inline void clear() { m_indices_dists.clear(); }
+
+		inline size_t size() const { return m_indices_dists.size(); }
+
+		inline bool full() const { return true; }
+
+		inline void addPoint(DistanceType dist, IndexType index)
+		{
+			if (dist<radius)
+				m_indices_dists.push_back(std::make_pair<IndexType,DistanceType>(index,dist));
+		}
+
+		inline DistanceType worstDist() const { return radius; }
+
+		/** Clears the result set and adjusts the search radius. */
+		inline void set_radius_and_clear( const DistanceType r )
+		{
+			radius = r;
+			clear();
+		}
+
+		/**
+		 * Find the worst result (furtherest neighbor) without copying or sorting
+		 * Pre-conditions: size() > 0
+		 */
+		std::pair<IndexType,DistanceType> worst_item() const
+		{
+		   if (m_indices_dists.empty()) throw std::runtime_error("Cannot invoke RadiusResultSet::worst_item() on an empty list of results.");
+		   typedef typename std::vector<std::pair<IndexType,DistanceType> >::const_iterator DistIt;
+		   DistIt it = std::max_element(m_indices_dists.begin(), m_indices_dists.end());
+		   return *it;
+		}
+	};
+
+	/** operator "<" for std::sort() */
+	struct IndexDist_Sorter
+	{
+		/** PairType will be typically: std::pair<IndexType,DistanceType> */
+		template <typename PairType>
+		inline bool operator()(const PairType &p1, const PairType &p2) const {
+			return p1.second < p2.second;
+		}
+	};
+
+	/** @} */
+
+
+	/** @addtogroup loadsave_grp Load/save auxiliary functions
+	  * @{ */
+	template<typename T>
+	void save_value(FILE* stream, const T& value, size_t count = 1)
+	{
+		fwrite(&value, sizeof(value),count, stream);
+	}
+
+	template<typename T>
+	void save_value(FILE* stream, const std::vector<T>& value)
+	{
+		size_t size = value.size();
+		fwrite(&size, sizeof(size_t), 1, stream);
+		fwrite(&value[0], sizeof(T), size, stream);
+	}
+
+	template<typename T>
+	void load_value(FILE* stream, T& value, size_t count = 1)
+	{
+		size_t read_cnt = fread(&value, sizeof(value), count, stream);
+		if (read_cnt != count) {
+			throw std::runtime_error("Cannot read from file");
+		}
+	}
+
+
+	template<typename T>
+	void load_value(FILE* stream, std::vector<T>& value)
+	{
+		size_t size;
+		size_t read_cnt = fread(&size, sizeof(size_t), 1, stream);
+		if (read_cnt!=1) {
+			throw std::runtime_error("Cannot read from file");
+		}
+		value.resize(size);
+		read_cnt = fread(&value[0], sizeof(T), size, stream);
+		if (read_cnt!=size) {
+			throw std::runtime_error("Cannot read from file");
+		}
+	}
+	/** @} */
+
+
+	/** @addtogroup metric_grp Metric (distance) classes
+	  * @{ */
+
+	template<typename T> inline T abs(T x) { return (x<0) ? -x : x; }
+	template<> inline int abs<int>(int x) { return ::abs(x); }
+	template<> inline float abs<float>(float x) { return fabsf(x); }
+	template<> inline double abs<double>(double x) { return fabs(x); }
+	template<> inline long double abs<long double>(long double x) { return fabsl(x); }
+
+	/** Manhattan distance functor (generic version, optimized for high-dimensionality data sets).
+	  *  Corresponding distance traits: nanoflann::metric_L1
+	  * \tparam T Type of the elements (e.g. double, float, uint8_t)
+	  * \tparam DistanceType Type of distance variables (must be signed) (e.g. float, double, int64_t)
+	  */
+	template<class T, class DataSource, typename _DistanceType = T>
+	struct L1_Adaptor
+	{
+		typedef T ElementType;
+		typedef _DistanceType DistanceType;
+
+		const DataSource &data_source;
+
+		L1_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
+
+		inline DistanceType operator()(const T* a, const size_t b_idx, size_t size, DistanceType worst_dist = -1) const
+		{
+			DistanceType result = DistanceType();
+			const T* last = a + size;
+			const T* lastgroup = last - 3;
+			size_t d = 0;
+
+			/* Process 4 items with each loop for efficiency. */
+			while (a < lastgroup) {
+				const DistanceType diff0 = nanoflann::abs(a[0] - data_source.kdtree_get_pt(b_idx,d++));
+				const DistanceType diff1 = nanoflann::abs(a[1] - data_source.kdtree_get_pt(b_idx,d++));
+				const DistanceType diff2 = nanoflann::abs(a[2] - data_source.kdtree_get_pt(b_idx,d++));
+				const DistanceType diff3 = nanoflann::abs(a[3] - data_source.kdtree_get_pt(b_idx,d++));
+				result += diff0 + diff1 + diff2 + diff3;
+				a += 4;
+				if ((worst_dist>0)&&(result>worst_dist)) {
+					return result;
+				}
+			}
+			/* Process last 0-3 components.  Not needed for standard vector lengths. */
+			while (a < last) {
+				result += nanoflann::abs( *a++ - data_source.kdtree_get_pt(b_idx,d++) );
+			}
+			return result;
+		}
+
+		template <typename U, typename V>
+		inline DistanceType accum_dist(const U a, const V b, int dim) const
+		{
+			return (a-b)*(a-b);
+		}
+	};
+
+	/** Squared Euclidean distance functor (generic version, optimized for high-dimensionality data sets).
+	  *  Corresponding distance traits: nanoflann::metric_L2
+	  * \tparam T Type of the elements (e.g. double, float, uint8_t)
+	  * \tparam DistanceType Type of distance variables (must be signed) (e.g. float, double, int64_t)
+	  */
+	template<class T, class DataSource, typename _DistanceType = T>
+	struct L2_Adaptor
+	{
+		typedef T ElementType;
+		typedef _DistanceType DistanceType;
+
+		const DataSource &data_source;
+
+		L2_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
+
+		inline DistanceType operator()(const T* a, const size_t b_idx, size_t size, DistanceType worst_dist = -1) const
+		{
+			DistanceType result = DistanceType();
+			const T* last = a + size;
+			const T* lastgroup = last - 3;
+			size_t d = 0;
+
+			/* Process 4 items with each loop for efficiency. */
+			while (a < lastgroup) {
+				const DistanceType diff0 = a[0] - data_source.kdtree_get_pt(b_idx,d++);
+				const DistanceType diff1 = a[1] - data_source.kdtree_get_pt(b_idx,d++);
+				const DistanceType diff2 = a[2] - data_source.kdtree_get_pt(b_idx,d++);
+				const DistanceType diff3 = a[3] - data_source.kdtree_get_pt(b_idx,d++);
+				result += diff0 * diff0 + diff1 * diff1 + diff2 * diff2 + diff3 * diff3;
+				a += 4;
+				if ((worst_dist>0)&&(result>worst_dist)) {
+					return result;
+				}
+			}
+			/* Process last 0-3 components.  Not needed for standard vector lengths. */
+			while (a < last) {
+				const DistanceType diff0 = *a++ - data_source.kdtree_get_pt(b_idx,d++);
+				result += diff0 * diff0;
+			}
+			return result;
+		}
+
+		template <typename U, typename V>
+		inline DistanceType accum_dist(const U a, const V b, int dim) const
+		{
+			return (a-b)*(a-b);
+		}
+	};
+
+	/** Squared Euclidean distance functor (suitable for low-dimensionality datasets, like 2D or 3D point clouds)
+	  *  Corresponding distance traits: nanoflann::metric_L2_Simple
+	  * \tparam T Type of the elements (e.g. double, float, uint8_t)
+	  * \tparam DistanceType Type of distance variables (must be signed) (e.g. float, double, int64_t)
+	  */
+	template<class T, class DataSource, typename _DistanceType = T>
+	struct L2_Simple_Adaptor
+	{
+		typedef T ElementType;
+		typedef _DistanceType DistanceType;
+
+		const DataSource &data_source;
+
+		L2_Simple_Adaptor(const DataSource &_data_source) : data_source(_data_source) { }
+
+		inline DistanceType operator()(const T* a, const size_t b_idx, size_t size) const {
+			return data_source.kdtree_distance(a,b_idx,size);
+		}
+
+		template <typename U, typename V>
+		inline DistanceType accum_dist(const U a, const V b, int dim) const
+		{
+			return (a-b)*(a-b);
+		}
+	};
+
+	/** Metaprogramming helper traits class for the L1 (Manhattan) metric */
+	struct metric_L1 {
+		template<class T, class DataSource>
+		struct traits {
+			typedef L1_Adaptor<T,DataSource> distance_t;
+		};
+	};
+	/** Metaprogramming helper traits class for the L2 (Euclidean) metric */
+	struct metric_L2 {
+		template<class T, class DataSource>
+		struct traits {
+			typedef L2_Adaptor<T,DataSource> distance_t;
+		};
+	};
+	/** Metaprogramming helper traits class for the L2_simple (Euclidean) metric */
+	struct metric_L2_Simple {
+		template<class T, class DataSource>
+		struct traits {
+			typedef L2_Simple_Adaptor<T,DataSource> distance_t;
+		};
+	};
+
+	/** @} */
+
+
+
+	/** @addtogroup param_grp Parameter structs
+	  * @{ */
+
+	/**  Parameters (see http://code.google.com/p/nanoflann/ for help choosing the parameters)
+	  */
+	struct KDTreeSingleIndexAdaptorParams
+	{
+		KDTreeSingleIndexAdaptorParams(size_t _leaf_max_size = 10, int dim_ = -1) :
+			leaf_max_size(_leaf_max_size), dim(dim_)
+		{}
+
+		size_t leaf_max_size;
+		int dim;
+	};
+
+	/** Search options for KDTreeSingleIndexAdaptor::findNeighbors() */
+	struct SearchParams
+	{
+		/** Note: The first argument (checks_IGNORED_) is ignored, but kept for compatibility with the FLANN interface */
+		SearchParams(int checks_IGNORED_ = 32, float eps_ = 0, bool sorted_ = true ) :
+			eps(eps_), sorted(sorted_) {}
+
+		int   checks;  //!< Ignored parameter (Kept for compatibility with the FLANN interface).
+		float eps;  //!< search for eps-approximate neighbours (default: 0)
+		bool sorted; //!< only for radius search, require neighbours sorted by distance (default: true)
+	};
+	/** @} */
+
+
+	/** @addtogroup memalloc_grp Memory allocation
+	  * @{ */
+
+	/**
+	 * Allocates (using C's malloc) a generic type T.
+	 *
+	 * Params:
+	 *     count = number of instances to allocate.
+	 * Returns: pointer (of type T*) to memory buffer
+	 */
+	template <typename T>
+	inline T* allocate(size_t count = 1)
+	{
+		T* mem = (T*) ::malloc(sizeof(T)*count);
+		return mem;
+	}
+
+
+	/**
+	 * Pooled storage allocator
+	 *
+	 * The following routines allow for the efficient allocation of storage in
+	 * small chunks from a specified pool.  Rather than allowing each structure
+	 * to be freed individually, an entire pool of storage is freed at once.
+	 * This method has two advantages over just using malloc() and free().  First,
+	 * it is far more efficient for allocating small objects, as there is
+	 * no overhead for remembering all the information needed to free each
+	 * object or consolidating fragmented memory.  Second, the decision about
+	 * how long to keep an object is made at the time of allocation, and there
+	 * is no need to track down all the objects to free them.
+	 *
+	 */
+
+	const size_t     WORDSIZE=16;
+	const size_t     BLOCKSIZE=8192;
+
+	class PooledAllocator
+	{
+		/* We maintain memory alignment to word boundaries by requiring that all
+		    allocations be in multiples of the machine wordsize.  */
+		/* Size of machine word in bytes.  Must be power of 2. */
+		/* Minimum number of bytes requested at a time from	the system.  Must be multiple of WORDSIZE. */
+
+
+		size_t  remaining;  /* Number of bytes left in current block of storage. */
+		void*   base;     /* Pointer to base of current block of storage. */
+		void*   loc;      /* Current location in block to next allocate memory. */
+		size_t  blocksize;
+
+
+	public:
+		size_t  usedMemory;
+		size_t  wastedMemory;
+
+		/**
+		    Default constructor. Initializes a new pool.
+		 */
+		PooledAllocator(const size_t blocksize = BLOCKSIZE)
+		{
+			this->blocksize = blocksize;
+			remaining = 0;
+			base = NULL;
+
+			usedMemory = 0;
+			wastedMemory = 0;
+		}
+
+		/**
+		 * Destructor. Frees all the memory allocated in this pool.
+		 */
+		~PooledAllocator()
+		{
+			while (base != NULL) {
+				void *prev = *((void**) base); /* Get pointer to prev block. */
+				::free(base);
+				base = prev;
+			}
+		}
+
+		/**
+		 * Returns a pointer to a piece of new memory of the given size in bytes
+		 * allocated from the pool.
+		 */
+		void* malloc(const size_t req_size)
+		{
+			/* Round size up to a multiple of wordsize.  The following expression
+			    only works for WORDSIZE that is a power of 2, by masking last bits of
+			    incremented size to zero.
+			 */
+			const size_t size = (req_size + (WORDSIZE - 1)) & ~(WORDSIZE - 1);
+
+			/* Check whether a new block must be allocated.  Note that the first word
+			    of a block is reserved for a pointer to the previous block.
+			 */
+			if (size > remaining) {
+
+				wastedMemory += remaining;
+
+				/* Allocate new storage. */
+				const size_t blocksize = (size + sizeof(void*) + (WORDSIZE-1) > BLOCKSIZE) ?
+							size + sizeof(void*) + (WORDSIZE-1) : BLOCKSIZE;
+
+				// use the standard C malloc to allocate memory
+				void* m = ::malloc(blocksize);
+				if (!m) {
+					fprintf(stderr,"Failed to allocate memory.\n");
+					return NULL;
+				}
+
+				/* Fill first word of new block with pointer to previous block. */
+				((void**) m)[0] = base;
+				base = m;
+
+				size_t shift = 0;
+				//int size_t = (WORDSIZE - ( (((size_t)m) + sizeof(void*)) & (WORDSIZE-1))) & (WORDSIZE-1);
+
+				remaining = blocksize - sizeof(void*) - shift;
+				loc = ((char*)m + sizeof(void*) + shift);
+			}
+			void* rloc = loc;
+			loc = (char*)loc + size;
+			remaining -= size;
+
+			usedMemory += size;
+
+			return rloc;
+		}
+
+		/**
+		 * Allocates (using this pool) a generic type T.
+		 *
+		 * Params:
+		 *     count = number of instances to allocate.
+		 * Returns: pointer (of type T*) to memory buffer
+		 */
+		template <typename T>
+		T* allocate(const size_t count = 1)
+		{
+			T* mem = (T*) this->malloc(sizeof(T)*count);
+			return mem;
+		}
+
+	};
+	/** @} */
+
+
+	/** @addtogroup kdtrees_grp KD-tree classes and adaptors
+	  * @{ */
+
+	/** kd-tree index
+	 *
+	 * Contains the k-d trees and other information for indexing a set of points
+	 * for nearest-neighbor matching.
+	 *
+	 *  The class "DatasetAdaptor" must provide the following interface (can be non-virtual, inlined methods):
+	 *
+	 *  \code
+	 *   // Must return the number of data points
+	 *   inline size_t kdtree_get_point_count() const { ... }
+	 *
+	 *   // Must return the Euclidean (L2) distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
+	 *   inline DistanceType kdtree_distance(const T *p1, const size_t idx_p2,size_t size) const { ... }
+	 *
+	 *   // Must return the dim'th component of the idx'th point in the class:
+	 *   inline T kdtree_get_pt(const size_t idx, int dim) const { ... }
+	 *
+	 *   // Optional bounding-box computation: return false to default to a standard bbox computation loop.
+	 *   //   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
+	 *   //   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
+	 *   template <class BBOX>
+	 *   bool kdtree_get_bbox(BBOX &bb) const
+	 *   {
+	 *      bb[0].low = ...; bb[0].high = ...;  // 0th dimension limits
+	 *      bb[1].low = ...; bb[1].high = ...;  // 1st dimension limits
+	 *      ...
+	 *      return true;
+	 *   }
+	 *
+	 *  \endcode
+	 *
+	 * \tparam IndexType Will be typically size_t or int
+	 */
+	template <typename Distance, class DatasetAdaptor,int DIM = -1, typename IndexType = size_t>
+	class KDTreeSingleIndexAdaptor
+	{
+	public:
+		typedef typename Distance::ElementType  ElementType;
+		typedef typename Distance::DistanceType DistanceType;
+	protected:
+
+		/**
+		 *  Array of indices to vectors in the dataset.
+		 */
+		std::vector<IndexType> vind;
+
+		size_t m_leaf_max_size;
+
+
+		/**
+		 * The dataset used by this index
+		 */
+		const DatasetAdaptor &dataset; //!< The source of our data
+
+		const KDTreeSingleIndexAdaptorParams index_params;
+
+		size_t m_size;
+		int dim;  //!< Dimensionality of each data point
+
+
+		/*--------------------- Internal Data Structures --------------------------*/
+		struct Node
+		{
+			union {
+				struct
+				{
+					/**
+					 * Indices of points in leaf node
+					 */
+					IndexType left, right;
+				} lr;
+				struct
+				{
+					/**
+					 * Dimension used for subdivision.
+					 */
+					int divfeat;
+					/**
+					 * The values used for subdivision.
+					 */
+					DistanceType divlow, divhigh;
+				} sub;
+			};
+			/**
+			 * The child nodes.
+			 */
+			Node* child1, * child2;
+		};
+		typedef Node* NodePtr;
+
+
+		struct Interval
+		{
+			ElementType low, high;
+		};
+
+		typedef std::vector<Interval> BoundingBox;
+
+
+		/** This record represents a branch point when finding neighbors in
+			the tree.  It contains a record of the minimum distance to the query
+			point, as well as the node at which the search resumes.
+		 */
+		template <typename T, typename DistanceType>
+		struct BranchStruct
+		{
+			T node;           /* Tree node at which search resumes */
+			DistanceType mindist;     /* Minimum distance to query for all nodes below. */
+
+			BranchStruct() {}
+			BranchStruct(const T& aNode, DistanceType dist) : node(aNode), mindist(dist) {}
+
+			inline bool operator<(const BranchStruct<T, DistanceType>& rhs) const
+			{
+				return mindist<rhs.mindist;
+			}
+		};
+
+		/**
+		 * Array of k-d trees used to find neighbours.
+		 */
+		NodePtr root_node;
+		typedef BranchStruct<NodePtr, DistanceType> BranchSt;
+		typedef BranchSt* Branch;
+
+		BoundingBox root_bbox;
+
+		/**
+		 * Pooled memory allocator.
+		 *
+		 * Using a pooled memory allocator is more efficient
+		 * than allocating memory directly when there is a large
+		 * number small of memory allocations.
+		 */
+		PooledAllocator pool;
+
+	public:
+
+		Distance distance;
+
+		/**
+		 * KDTree constructor
+		 *
+		 * Params:
+		 *          inputData = dataset with the input features
+		 *          params = parameters passed to the kdtree algorithm (see http://code.google.com/p/nanoflann/ for help choosing the parameters)
+		 */
+		KDTreeSingleIndexAdaptor(const int dimensionality, const DatasetAdaptor& inputData, const KDTreeSingleIndexAdaptorParams& params = KDTreeSingleIndexAdaptorParams() ) :
+			dataset(inputData), index_params(params), distance(inputData)
+		{
+			m_size = dataset.kdtree_get_point_count();
+			dim = dimensionality;
+			if (DIM>0) dim=DIM;
+			else {
+				if (params.dim>0) dim = params.dim;
+			}
+			m_leaf_max_size = params.leaf_max_size;
+
+			// Create a permutable array of indices to the input vectors.
+			init_vind();
+		}
+
+		/**
+		 * Standard destructor
+		 */
+		~KDTreeSingleIndexAdaptor()
+		{
+		}
+
+		/**
+		 * Builds the index
+		 */
+		void buildIndex()
+		{
+			init_vind();
+			computeBoundingBox(root_bbox);
+			root_node = divideTree(0, m_size, root_bbox );   // construct the tree
+		}
+
+		/**
+		 *  Returns size of index.
+		 */
+		size_t size() const
+		{
+			return m_size;
+		}
+
+		/**
+		 * Returns the length of an index feature.
+		 */
+		size_t veclen() const
+		{
+			return static_cast<size_t>(DIM>0 ? DIM : dim);
+		}
+
+		/**
+		 * Computes the inde memory usage
+		 * Returns: memory used by the index
+		 */
+		size_t usedMemory() const
+		{
+			return pool.usedMemory+pool.wastedMemory+dataset.kdtree_get_point_count()*sizeof(IndexType);  // pool memory and vind array memory
+		}
+
+		/** \name Query methods
+		  * @{ */
+
+		/**
+		 * Find set of nearest neighbors to vec[0:dim-1]. Their indices are stored inside
+		 * the result object.
+		 *
+		 * Params:
+		 *     result = the result object in which the indices of the nearest-neighbors are stored
+		 *     vec = the vector for which to search the nearest neighbors
+		 *
+		 * \tparam RESULTSET Should be any ResultSet<DistanceType>
+		 * \sa knnSearch, radiusSearch
+		 */
+		template <typename RESULTSET>
+		void findNeighbors(RESULTSET& result, const ElementType* vec, const SearchParams& searchParams) const
+		{
+			assert(vec);
+			float epsError = 1+searchParams.eps;
+
+			std::vector<DistanceType> dists( (DIM>0 ? DIM : dim) ,0);
+			DistanceType distsq = computeInitialDistances(vec, dists);
+			searchLevel(result, vec, root_node, distsq, dists, epsError);  // "count_leaf" parameter removed since was neither used nor returned to the user.
+		}
+
+		/**
+		 * Find the "num_closest" nearest neighbors to the \a query_point[0:dim-1]. Their indices are stored inside
+		 * the result object.
+		 *  \sa radiusSearch, findNeighbors
+		 * \note nChecks_IGNORED is ignored but kept for compatibility with the original FLANN interface.
+		 */
+		inline void knnSearch(const ElementType *query_point, const size_t num_closest, IndexType *out_indices, DistanceType *out_distances_sq, const int nChecks_IGNORED = 10) const
+		{
+			nanoflann::KNNResultSet<DistanceType,IndexType> resultSet(num_closest);
+			resultSet.init(out_indices, out_distances_sq);
+			this->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
+		}
+
+		/**
+		 * Find all the neighbors to \a query_point[0:dim-1] within a maximum radius.
+		 *  The output is given as a vector of pairs, of which the first element is a point index and the second the corresponding distance.
+		 *  Previous contents of \a IndicesDists are cleared.
+		 *
+		 *  If searchParams.sorted==true, the output list is sorted by ascending distances.
+		 *
+		 *  For a better performance, it is advisable to do a .reserve() on the vector if you have any wild guess about the number of expected matches.
+		 *
+		 *  \sa knnSearch, findNeighbors
+		 * \return The number of points within the given radius (i.e. indices.size() or dists.size() )
+		 */
+		size_t radiusSearch(const ElementType *query_point,const DistanceType radius, std::vector<std::pair<IndexType,DistanceType> >& IndicesDists, const SearchParams& searchParams) const
+		{
+			RadiusResultSet<DistanceType,IndexType> resultSet(radius,IndicesDists);
+			this->findNeighbors(resultSet, query_point, searchParams);
+
+			if (searchParams.sorted)
+				std::sort(IndicesDists.begin(),IndicesDists.end(), IndexDist_Sorter() );
+
+			return resultSet.size();
+		}
+
+		/** @} */
+
+	private:
+		/** Make sure the auxiliary list \a vind has the same size than the current dataset, and re-generate if size has changed. */
+		void init_vind()
+		{
+			// Create a permutable array of indices to the input vectors.
+			m_size = dataset.kdtree_get_point_count();
+			if (vind.size()!=m_size)
+			{
+				vind.resize(m_size);
+				for (size_t i = 0; i < m_size; i++) vind[i] = i;
+			}
+		}
+
+		/// Helper accessor to the dataset points:
+		inline ElementType dataset_get(size_t idx, int component) const {
+			return dataset.kdtree_get_pt(idx,component);
+		}
+
+
+		void save_tree(FILE* stream, NodePtr tree)
+		{
+			save_value(stream, *tree);
+			if (tree->child1!=NULL) {
+				save_tree(stream, tree->child1);
+			}
+			if (tree->child2!=NULL) {
+				save_tree(stream, tree->child2);
+			}
+		}
+
+
+		void load_tree(FILE* stream, NodePtr& tree)
+		{
+			tree = pool.allocate<Node>();
+			load_value(stream, *tree);
+			if (tree->child1!=NULL) {
+				load_tree(stream, tree->child1);
+			}
+			if (tree->child2!=NULL) {
+				load_tree(stream, tree->child2);
+			}
+		}
+
+
+		void computeBoundingBox(BoundingBox& bbox)
+		{
+			bbox.resize((DIM>0 ? DIM : dim));
+			if (dataset.kdtree_get_bbox(bbox))
+			{
+				// Done! It was implemented in derived class
+			}
+			else
+			{
+				for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+					bbox[i].low =
+						bbox[i].high = dataset_get(0,i);
+				}
+				const size_t N = dataset.kdtree_get_point_count();
+				for (size_t k=1; k<N; ++k) {
+					for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+						if (dataset_get(k,i)<bbox[i].low) bbox[i].low = dataset_get(k,i);
+						if (dataset_get(k,i)>bbox[i].high) bbox[i].high = dataset_get(k,i);
+					}
+				}
+			}
+		}
+
+
+		/**
+		 * Create a tree node that subdivides the list of vecs from vind[first]
+		 * to vind[last].  The routine is called recursively on each sublist.
+		 * Place a pointer to this new tree node in the location pTree.
+		 *
+		 * Params: pTree = the new node to create
+		 *                  first = index of the first vector
+		 *                  last = index of the last vector
+		 */
+		NodePtr divideTree(const IndexType left, const IndexType right, BoundingBox& bbox)
+		{
+			NodePtr node = pool.allocate<Node>(); // allocate memory
+
+			/* If too few exemplars remain, then make this a leaf node. */
+			if ( (right-left) <= m_leaf_max_size) {
+				node->child1 = node->child2 = NULL;    /* Mark as leaf node. */
+				node->lr.left = left;
+				node->lr.right = right;
+
+				// compute bounding-box of leaf points
+				for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+					bbox[i].low = dataset_get(vind[left],i);
+					bbox[i].high = dataset_get(vind[left],i);
+				}
+				for (IndexType k=left+1; k<right; ++k) {
+					for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+						if (bbox[i].low>dataset_get(vind[k],i)) bbox[i].low=dataset_get(vind[k],i);
+						if (bbox[i].high<dataset_get(vind[k],i)) bbox[i].high=dataset_get(vind[k],i);
+					}
+				}
+			}
+			else {
+				IndexType idx;
+				int cutfeat;
+				DistanceType cutval;
+				middleSplit_(&vind[0]+left, right-left, idx, cutfeat, cutval, bbox);
+
+				node->sub.divfeat = cutfeat;
+
+				BoundingBox left_bbox(bbox);
+				left_bbox[cutfeat].high = cutval;
+				node->child1 = divideTree(left, left+idx, left_bbox);
+
+				BoundingBox right_bbox(bbox);
+				right_bbox[cutfeat].low = cutval;
+				node->child2 = divideTree(left+idx, right, right_bbox);
+
+				node->sub.divlow = left_bbox[cutfeat].high;
+				node->sub.divhigh = right_bbox[cutfeat].low;
+
+				for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+					bbox[i].low = std::min(left_bbox[i].low, right_bbox[i].low);
+					bbox[i].high = std::max(left_bbox[i].high, right_bbox[i].high);
+				}
+			}
+
+			return node;
+		}
+
+		void computeMinMax(IndexType* ind, IndexType count, int element, ElementType& min_elem, ElementType& max_elem)
+		{
+			min_elem = dataset_get(ind[0],element);
+			max_elem = dataset_get(ind[0],element);
+			for (IndexType i=1; i<count; ++i) {
+				ElementType val = dataset_get(ind[i],element);
+				if (val<min_elem) min_elem = val;
+				if (val>max_elem) max_elem = val;
+			}
+		}
+
+		void middleSplit(IndexType* ind, IndexType count, IndexType& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox)
+		{
+			// find the largest span from the approximate bounding box
+			ElementType max_span = bbox[0].high-bbox[0].low;
+			cutfeat = 0;
+			cutval = (bbox[0].high+bbox[0].low)/2;
+			for (int i=1; i<(DIM>0 ? DIM : dim); ++i) {
+				ElementType span = bbox[i].low-bbox[i].low;
+				if (span>max_span) {
+					max_span = span;
+					cutfeat = i;
+					cutval = (bbox[i].high+bbox[i].low)/2;
+				}
+			}
+
+			// compute exact span on the found dimension
+			ElementType min_elem, max_elem;
+			computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+			cutval = (min_elem+max_elem)/2;
+			max_span = max_elem - min_elem;
+
+			// check if a dimension of a largest span exists
+			size_t k = cutfeat;
+			for (size_t i=0; i<(DIM>0 ? DIM : dim); ++i) {
+				if (i==k) continue;
+				ElementType span = bbox[i].high-bbox[i].low;
+				if (span>max_span) {
+					computeMinMax(ind, count, i, min_elem, max_elem);
+					span = max_elem - min_elem;
+					if (span>max_span) {
+						max_span = span;
+						cutfeat = i;
+						cutval = (min_elem+max_elem)/2;
+					}
+				}
+			}
+			IndexType lim1, lim2;
+			planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
+
+			if (lim1>count/2) index = lim1;
+			else if (lim2<count/2) index = lim2;
+			else index = count/2;
+		}
+
+
+		void middleSplit_(IndexType* ind, IndexType count, IndexType& index, int& cutfeat, DistanceType& cutval, const BoundingBox& bbox)
+		{
+			const DistanceType EPS=static_cast<DistanceType>(0.00001);
+			ElementType max_span = bbox[0].high-bbox[0].low;
+			for (int i=1; i<(DIM>0 ? DIM : dim); ++i) {
+				ElementType span = bbox[i].high-bbox[i].low;
+				if (span>max_span) {
+					max_span = span;
+				}
+			}
+			ElementType max_spread = -1;
+			cutfeat = 0;
+			for (int i=0; i<(DIM>0 ? DIM : dim); ++i) {
+				ElementType span = bbox[i].high-bbox[i].low;
+				if (span>(1-EPS)*max_span) {
+					ElementType min_elem, max_elem;
+					computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+					ElementType spread = max_elem-min_elem;;
+					if (spread>max_spread) {
+						cutfeat = i;
+						max_spread = spread;
+					}
+				}
+			}
+			// split in the middle
+			DistanceType split_val = (bbox[cutfeat].low+bbox[cutfeat].high)/2;
+			ElementType min_elem, max_elem;
+			computeMinMax(ind, count, cutfeat, min_elem, max_elem);
+
+			if (split_val<min_elem) cutval = min_elem;
+			else if (split_val>max_elem) cutval = max_elem;
+			else cutval = split_val;
+
+			IndexType lim1, lim2;
+			planeSplit(ind, count, cutfeat, cutval, lim1, lim2);
+
+			if (lim1>count/2) index = lim1;
+			else if (lim2<count/2) index = lim2;
+			else index = count/2;
+		}
+
+
+		/**
+		 *  Subdivide the list of points by a plane perpendicular on axe corresponding
+		 *  to the 'cutfeat' dimension at 'cutval' position.
+		 *
+		 *  On return:
+		 *  dataset[ind[0..lim1-1]][cutfeat]<cutval
+		 *  dataset[ind[lim1..lim2-1]][cutfeat]==cutval
+		 *  dataset[ind[lim2..count]][cutfeat]>cutval
+		 */
+		void planeSplit(IndexType* ind, const IndexType count, int cutfeat, DistanceType cutval, IndexType& lim1, IndexType& lim2)
+		{
+			/* Move vector indices for left subtree to front of list. */
+			IndexType left = 0;
+			IndexType right = count-1;
+			for (;; ) {
+				while (left<=right && dataset_get(ind[left],cutfeat)<cutval) ++left;
+				while (right && left<=right && dataset_get(ind[right],cutfeat)>=cutval) --right;
+				if (left>right || !right) break;  // "!right" was added to support unsigned Index types
+				std::swap(ind[left], ind[right]);
+				++left;
+				--right;
+			}
+			/* If either list is empty, it means that all remaining features
+			 * are identical. Split in the middle to maintain a balanced tree.
+			 */
+			lim1 = left;
+			right = count-1;
+			for (;; ) {
+				while (left<=right && dataset_get(ind[left],cutfeat)<=cutval) ++left;
+				while (right && left<=right && dataset_get(ind[right],cutfeat)>cutval) --right;
+				if (left>right || !right) break;  // "!right" was added to support unsigned Index types
+				std::swap(ind[left], ind[right]);
+				++left;
+				--right;
+			}
+			lim2 = left;
+		}
+
+		DistanceType computeInitialDistances(const ElementType* vec, std::vector<DistanceType>& dists) const
+		{
+			assert(vec);
+			DistanceType distsq = 0.0;
+
+			for (int i = 0; i < (DIM>0 ? DIM : dim); ++i) {
+				if (vec[i] < root_bbox[i].low) {
+					dists[i] = distance.accum_dist(vec[i], root_bbox[i].low, i);
+					distsq += dists[i];
+				}
+				if (vec[i] > root_bbox[i].high) {
+					dists[i] = distance.accum_dist(vec[i], root_bbox[i].high, i);
+					distsq += dists[i];
+				}
+			}
+
+			return distsq;
+		}
+
+		/**
+		 * Performs an exact search in the tree starting from a node.
+		 * \tparam RESULTSET Should be any ResultSet<DistanceType>
+		 */
+		template <class RESULTSET>
+		void searchLevel(RESULTSET& result_set, const ElementType* vec, const NodePtr node, DistanceType mindistsq,
+						 std::vector<DistanceType>& dists, const float epsError) const
+		{
+			/* If this is a leaf node, then do check and return. */
+			if ((node->child1 == NULL)&&(node->child2 == NULL)) {
+				//count_leaf += (node->lr.right-node->lr.left);  // Removed since was neither used nor returned to the user.
+				DistanceType worst_dist = result_set.worstDist();
+				for (IndexType i=node->lr.left; i<node->lr.right; ++i) {
+					const IndexType index = vind[i];// reorder... : i;
+					DistanceType dist = distance(vec, index, (DIM>0 ? DIM : dim));
+					if (dist<worst_dist) {
+						result_set.addPoint(dist,vind[i]);
+					}
+				}
+				return;
+			}
+
+			/* Which child branch should be taken first? */
+			int idx = node->sub.divfeat;
+			ElementType val = vec[idx];
+			DistanceType diff1 = val - node->sub.divlow;
+			DistanceType diff2 = val - node->sub.divhigh;
+
+			NodePtr bestChild;
+			NodePtr otherChild;
+			DistanceType cut_dist;
+			if ((diff1+diff2)<0) {
+				bestChild = node->child1;
+				otherChild = node->child2;
+				cut_dist = distance.accum_dist(val, node->sub.divhigh, idx);
+			}
+			else {
+				bestChild = node->child2;
+				otherChild = node->child1;
+				cut_dist = distance.accum_dist( val, node->sub.divlow, idx);
+			}
+
+			/* Call recursively to search next level down. */
+			searchLevel(result_set, vec, bestChild, mindistsq, dists, epsError);
+
+			DistanceType dst = dists[idx];
+			mindistsq = mindistsq + cut_dist - dst;
+			dists[idx] = cut_dist;
+			if (mindistsq*epsError<=result_set.worstDist()) {
+				searchLevel(result_set, vec, otherChild, mindistsq, dists, epsError);
+			}
+			dists[idx] = dst;
+		}
+
+
+		void saveIndex(FILE* stream)
+		{
+			save_value(stream, m_size);
+			save_value(stream, dim);
+			save_value(stream, root_bbox);
+			save_value(stream, m_leaf_max_size);
+			save_value(stream, vind);
+			save_tree(stream, root_node);
+		}
+
+		void loadIndex(FILE* stream)
+		{
+			load_value(stream, m_size);
+			load_value(stream, dim);
+			load_value(stream, root_bbox);
+			load_value(stream, m_leaf_max_size);
+			load_value(stream, vind);
+			load_tree(stream, root_node);
+		}
+
+	};   // class KDTree
+
+
+	/** A simple KD-tree adaptor for working with data directly stored in an Eigen Matrix, without duplicating the data storage.
+	  *  Each row in the matrix represents a point in the state space.
+	  *
+	  *  Example of usage:
+	  * \code
+	  * 	Eigen::Matrix<num_t,Dynamic,Dynamic>  mat;
+	  * 	// Fill out "mat"...
+	  *
+	  * 	typedef KDTreeEigenMatrixAdaptor< Eigen::Matrix<num_t,Dynamic,Dynamic> >  my_kd_tree_t;
+	  * 	const int max_leaf = 10;
+	  * 	my_kd_tree_t   mat_index(dimdim, mat, max_leaf );
+	  * 	mat_index.index->buildIndex();
+	  * 	mat_index.index->...
+	  * \endcode
+	  *
+	  *  \tparam DIM If set to >0, it specifies a compile-time fixed dimensionality for the points in the data set, allowing more compiler optimizations.
+	  *  \tparam Distance The distance metric to use: nanoflann::metric_L1, nanoflann::metric_L2, nanoflann::metric_L2_Simple, etc.
+	  *  \tparam IndexType The type for indices in the KD-tree index (typically, size_t of int)
+	  */
+	template <class MatrixType, int DIM = -1, class Distance = nanoflann::metric_L2, typename IndexType = size_t>
+	struct KDTreeEigenMatrixAdaptor
+	{
+		typedef KDTreeEigenMatrixAdaptor<MatrixType,DIM,Distance> self_t;
+		typedef typename MatrixType::Scalar              num_t;
+		typedef typename Distance::template traits<num_t,self_t>::distance_t metric_t;
+		typedef KDTreeSingleIndexAdaptor< metric_t,self_t,DIM,IndexType>  index_t;
+
+		index_t* index; //! The kd-tree index for the user to call its methods as usual with any other FLANN index.
+
+		/// Constructor: takes a const ref to the matrix object with the data points
+		KDTreeEigenMatrixAdaptor(const int dimensionality, const MatrixType &mat, const int leaf_max_size = 10) : m_data_matrix(mat)
+		{
+			const size_t dims = mat.cols();
+			if (DIM>0 && static_cast<int>(dims)!=DIM)
+				throw std::runtime_error("Data set dimensionality does not match the 'DIM' template argument");
+			index = new index_t( dims, *this /* adaptor */, nanoflann::KDTreeSingleIndexAdaptorParams(leaf_max_size, dims ) );
+			index->buildIndex();
+		}
+
+		~KDTreeEigenMatrixAdaptor() {
+			delete index;
+		}
+
+		const MatrixType &m_data_matrix;
+
+		/** Query for the \a num_closest closest points to a given point (entered as query_point[0:dim-1]).
+		  *  Note that this is a short-cut method for index->findNeighbors().
+		  *  The user can also call index->... methods as desired.
+		  * \note nChecks_IGNORED is ignored but kept for compatibility with the original FLANN interface.
+		  */
+		inline void query(const num_t *query_point, const size_t num_closest, IndexType *out_indices, num_t *out_distances_sq, const int nChecks_IGNORED = 10) const
+		{
+			nanoflann::KNNResultSet<typename MatrixType::Scalar,IndexType> resultSet(num_closest);
+			resultSet.init(out_indices, out_distances_sq);
+			index->findNeighbors(resultSet, query_point, nanoflann::SearchParams());
+		}
+
+		/** @name Interface expected by KDTreeSingleIndexAdaptor
+		  * @{ */
+
+		const self_t & derived() const {
+			return *this;
+		}
+		self_t & derived()       {
+			return *this;
+		}
+
+		// Must return the number of data points
+		inline size_t kdtree_get_point_count() const {
+			return m_data_matrix.rows();
+		}
+
+		// Returns the distance between the vector "p1[0:size-1]" and the data point with index "idx_p2" stored in the class:
+		inline num_t kdtree_distance(const num_t *p1, const size_t idx_p2,size_t size) const
+		{
+			num_t s=0;
+			for (size_t i=0; i<size; i++) {
+				const num_t d= p1[i]-m_data_matrix.coeff(idx_p2,i);
+				s+=d*d;
+			}
+			return s;
+		}
+
+		// Returns the dim'th component of the idx'th point in the class:
+		inline num_t kdtree_get_pt(const size_t idx, int dim) const {
+			return m_data_matrix.coeff(idx,dim);
+		}
+
+		// Optional bounding-box computation: return false to default to a standard bbox computation loop.
+		//   Return true if the BBOX was already computed by the class and returned in "bb" so it can be avoided to redo it again.
+		//   Look at bb.size() to find out the expected dimensionality (e.g. 2 or 3 for point clouds)
+		template <class BBOX>
+		bool kdtree_get_bbox(BBOX &bb) const {
+			return false;
+		}
+
+		/** @} */
+
+	}; // end of KDTreeEigenMatrixAdaptor
+	/** @} */
+
+/** @} */ // end of grouping
+} // end of NS
+
+
+#endif /* NANOFLANN_HPP_ */
diff --git a/extensions/nanoflann/version b/extensions/nanoflann/version
new file mode 100644
index 0000000000000000000000000000000000000000..9c1218c201fd26e5fc200c5443872cbf14f1c947
--- /dev/null
+++ b/extensions/nanoflann/version
@@ -0,0 +1 @@
+1.1.3
\ No newline at end of file
diff --git a/extensions/pugixml/contrib/foreach.hpp b/extensions/pugixml/contrib/foreach.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..c413f1de712df9a41fc5350e3963b7443e154fbc
--- /dev/null
+++ b/extensions/pugixml/contrib/foreach.hpp
@@ -0,0 +1,102 @@
+/*
+ * Boost.Foreach support for pugixml classes.
+ * This file is provided to the public domain.
+ * Written by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ */
+
+#ifndef HEADER_PUGIXML_FOREACH_HPP
+#define HEADER_PUGIXML_FOREACH_HPP
+
+#include "pugixml.hpp"
+
+/*
+ * These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child iteration only).
+ * Example usage:
+ * BOOST_FOREACH(xml_node n, doc) {}
+ */
+
+namespace boost
+{
+	template <typename> struct range_mutable_iterator;
+	template <typename> struct range_const_iterator;
+
+	template<> struct range_mutable_iterator<pugi::xml_node>
+	{
+		typedef pugi::xml_node::iterator type;
+	};
+
+	template<> struct range_const_iterator<pugi::xml_node>
+	{
+		typedef pugi::xml_node::iterator type;
+	};
+
+	template<> struct range_mutable_iterator<pugi::xml_document>
+	{
+		typedef pugi::xml_document::iterator type;
+	};
+
+	template<> struct range_const_iterator<pugi::xml_document>
+	{
+		typedef pugi::xml_document::iterator type;
+	};
+}
+
+/*
+ * These types add support for BOOST_FOREACH macro to xml_node and xml_document classes (child/attribute iteration).
+ * Example usage:
+ * BOOST_FOREACH(xml_node n, children(doc)) {}
+ * BOOST_FOREACH(xml_node n, attributes(doc)) {}
+ */
+
+namespace pugi
+{
+	struct xml_node_children_adapter
+	{
+		typedef pugi::xml_node::iterator iterator;
+		typedef pugi::xml_node::iterator const_iterator;
+
+		xml_node node;
+
+		const_iterator begin() const
+		{
+			return node.begin();
+		}
+
+		const_iterator end() const
+		{
+			return node.end();
+		}
+	};
+
+	xml_node_children_adapter children(const pugi::xml_node& node)
+	{
+		xml_node_children_adapter result = {node};
+		return result;
+	}
+
+	struct xml_node_attribute_adapter
+	{
+		typedef pugi::xml_node::attribute_iterator iterator;
+		typedef pugi::xml_node::attribute_iterator const_iterator;
+
+		xml_node node;
+
+		const_iterator begin() const
+		{
+			return node.attributes_begin();
+		}
+
+		const_iterator end() const
+		{
+			return node.attributes_end();
+		}
+	};
+
+	xml_node_attribute_adapter attributes(const pugi::xml_node& node)
+	{
+		xml_node_attribute_adapter result = {node};
+		return result;
+	}
+}
+
+#endif
diff --git a/extensions/pugixml/readme.txt b/extensions/pugixml/readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf8892d0a98cc175affec3c1029619742787aab9
--- /dev/null
+++ b/extensions/pugixml/readme.txt
@@ -0,0 +1,52 @@
+pugixml 1.0 - an XML processing library
+
+Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+Report bugs and download new versions at http://pugixml.org/
+
+This is the distribution of pugixml, which is a C++ XML processing library,
+which consists of a DOM-like interface with rich traversal/modification
+capabilities, an extremely fast XML parser which constructs the DOM tree from
+an XML file/buffer, and an XPath 1.0 implementation for complex data-driven
+tree queries. Full Unicode support is also available, with Unicode interface
+variants and conversions between different Unicode encodings (which happen
+automatically during parsing/saving).
+
+The distribution contains the following folders:
+
+	contrib/ - various contributions to pugixml
+
+	docs/ - documentation
+		docs/samples - pugixml usage examples
+		docs/quickstart.html - quick start guide
+		docs/manual.html - complete manual
+
+	scripts/ - project files for IDE/build systems
+
+	src/ - header and source files
+
+	readme.txt - this file.
+
+This library is distributed under the MIT License:
+
+Copyright (c) 2006-2010 Arseny Kapoulkine
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extensions/pugixml/src/pugiconfig.hpp b/extensions/pugixml/src/pugiconfig.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..90b81e11739e2a2b16efba281a6aafd10b558bdd
--- /dev/null
+++ b/extensions/pugixml/src/pugiconfig.hpp
@@ -0,0 +1,62 @@
+/**
+ * pugixml parser - version 1.0
+ * --------------------------------------------------------
+ * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ * Report bugs and download new versions at http://pugixml.org/
+ *
+ * This library is distributed under the MIT License. See notice at the end
+ * of this file.
+ *
+ * This work is based on the pugxml parser, which is:
+ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
+ */
+
+#ifndef HEADER_PUGICONFIG_HPP
+#define HEADER_PUGICONFIG_HPP
+
+// Uncomment this to enable wchar_t mode
+// #define PUGIXML_WCHAR_MODE
+
+// Uncomment this to disable XPath
+// #define PUGIXML_NO_XPATH
+
+// Uncomment this to disable STL
+// Note: you can't use XPath with PUGIXML_NO_STL
+// #define PUGIXML_NO_STL
+
+// Uncomment this to disable exceptions
+// Note: you can't use XPath with PUGIXML_NO_EXCEPTIONS
+// #define PUGIXML_NO_EXCEPTIONS
+
+// Set this to control attributes for public classes/functions, i.e.:
+// #define PUGIXML_API __declspec(dllexport) // to export all public symbols from DLL
+// #define PUGIXML_CLASS __declspec(dllimport) // to import all classes from DLL
+// #define PUGIXML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall
+// In absence of PUGIXML_CLASS/PUGIXML_FUNCTION definitions PUGIXML_API is used instead
+
+#endif
+
+/**
+ * Copyright (c) 2006-2010 Arseny Kapoulkine
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
diff --git a/extensions/pugixml/src/pugixml.cpp b/extensions/pugixml/src/pugixml.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..901731a9b8ff95295c8e84519797143b91d485aa
--- /dev/null
+++ b/extensions/pugixml/src/pugixml.cpp
@@ -0,0 +1,9576 @@
+/**
+ * pugixml parser - version 1.0
+ * --------------------------------------------------------
+ * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ * Report bugs and download new versions at http://pugixml.org/
+ *
+ * This library is distributed under the MIT License. See notice at the end
+ * of this file.
+ *
+ * This work is based on the pugxml parser, which is:
+ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
+ */
+
+#include "pugixml.hpp"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <setjmp.h>
+#include <wchar.h>
+
+#ifndef PUGIXML_NO_XPATH
+#	include <math.h>
+#	include <float.h>
+#endif
+
+#ifndef PUGIXML_NO_STL
+#	include <istream>
+#	include <ostream>
+#	include <string>
+#endif
+
+// For placement new
+#include <new>
+
+#ifdef _MSC_VER
+#	pragma warning(disable: 4127) // conditional expression is constant
+#	pragma warning(disable: 4324) // structure was padded due to __declspec(align())
+#	pragma warning(disable: 4611) // interaction between '_setjmp' and C++ object destruction is non-portable
+#	pragma warning(disable: 4702) // unreachable code
+#	pragma warning(disable: 4996) // this function or variable may be unsafe
+#endif
+
+#ifdef __INTEL_COMPILER
+#	pragma warning(disable: 177) // function was declared but never referenced 
+#	pragma warning(disable: 1478 1786) // function was declared "deprecated"
+#endif
+
+#ifdef __BORLANDC__
+#	pragma warn -8008 // condition is always false
+#	pragma warn -8066 // unreachable code
+#endif
+
+#ifdef __SNC__
+#	pragma diag_suppress=178 // function was declared but never referenced
+#	pragma diag_suppress=237 // controlling expression is constant
+#endif
+
+// uintptr_t
+#if !defined(_MSC_VER) || _MSC_VER >= 1600
+#	include <stdint.h>
+#else
+#	if _MSC_VER < 1300
+// No native uintptr_t in MSVC6
+typedef size_t uintptr_t;
+#	endif
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef __int32 int32_t;
+#endif
+
+// Inlining controls
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#	define PUGIXML_NO_INLINE __declspec(noinline)
+#elif defined(__GNUC__)
+#	define PUGIXML_NO_INLINE __attribute__((noinline))
+#else
+#	define PUGIXML_NO_INLINE 
+#endif
+
+// Simple static assertion
+#define STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
+
+// Digital Mars C++ bug workaround for passing char loaded from memory via stack
+#ifdef __DMC__
+#	define DMC_VOLATILE volatile
+#else
+#	define DMC_VOLATILE
+#endif
+
+using namespace pugi;
+
+// Memory allocation
+namespace
+{
+	void* default_allocate(size_t size)
+	{
+		return malloc(size);
+	}
+
+	void default_deallocate(void* ptr)
+	{
+		free(ptr);
+	}
+
+	allocation_function global_allocate = default_allocate;
+	deallocation_function global_deallocate = default_deallocate;
+}
+
+// String utilities
+namespace
+{
+	// Get string length
+	size_t strlength(const char_t* s)
+	{
+		assert(s);
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return wcslen(s);
+	#else
+		return strlen(s);
+	#endif
+	}
+
+	// Compare two strings
+	bool strequal(const char_t* src, const char_t* dst)
+	{
+		assert(src && dst);
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return wcscmp(src, dst) == 0;
+	#else
+		return strcmp(src, dst) == 0;
+	#endif
+	}
+
+	// Compare lhs with [rhs_begin, rhs_end)
+	bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count)
+	{
+		for (size_t i = 0; i < count; ++i)
+			if (lhs[i] != rhs[i])
+				return false;
+	
+		return lhs[count] == 0;
+	}
+	
+#ifdef PUGIXML_WCHAR_MODE
+	// Convert string to wide string, assuming all symbols are ASCII
+	void widen_ascii(wchar_t* dest, const char* source)
+	{
+		for (const char* i = source; *i; ++i) *dest++ = *i;
+		*dest = 0;
+	}
+#endif
+}
+
+#if !defined(PUGIXML_NO_STL) || !defined(PUGIXML_NO_XPATH)
+// auto_ptr-like buffer holder for exception recovery
+namespace
+{
+	struct buffer_holder
+	{
+		void* data;
+		void (*deleter)(void*);
+
+		buffer_holder(void* data, void (*deleter)(void*)): data(data), deleter(deleter)
+		{
+		}
+
+		~buffer_holder()
+		{
+			if (data) deleter(data);
+		}
+
+		void* release()
+		{
+			void* result = data;
+			data = 0;
+			return result;
+		}
+	};
+}
+#endif
+
+namespace
+{
+	static const size_t xml_memory_page_size = 32768;
+
+	static const uintptr_t xml_memory_page_alignment = 32;
+	static const uintptr_t xml_memory_page_pointer_mask = ~(xml_memory_page_alignment - 1);
+	static const uintptr_t xml_memory_page_name_allocated_mask = 16;
+	static const uintptr_t xml_memory_page_value_allocated_mask = 8;
+	static const uintptr_t xml_memory_page_type_mask = 7;
+
+	struct xml_allocator;
+
+	struct xml_memory_page
+	{
+		static xml_memory_page* construct(void* memory)
+		{
+			if (!memory) return 0; //$ redundant, left for performance
+
+			xml_memory_page* result = static_cast<xml_memory_page*>(memory);
+
+			result->allocator = 0;
+			result->memory = 0;
+			result->prev = 0;
+			result->next = 0;
+			result->busy_size = 0;
+			result->freed_size = 0;
+
+			return result;
+		}
+
+		xml_allocator* allocator;
+
+		void* memory;
+
+		xml_memory_page* prev;
+		xml_memory_page* next;
+
+		size_t busy_size;
+		size_t freed_size;
+
+		char data[1];
+	};
+
+	struct xml_memory_string_header
+	{
+		uint16_t page_offset; // offset from page->data
+		uint16_t full_size; // 0 if string occupies whole page
+	};
+
+	struct xml_allocator
+	{
+		xml_allocator(xml_memory_page* root): _root(root), _busy_size(root->busy_size)
+		{
+		}
+
+		xml_memory_page* allocate_page(size_t data_size)
+		{
+			size_t size = offsetof(xml_memory_page, data) + data_size;
+
+			// allocate block with some alignment, leaving memory for worst-case padding
+			void* memory = global_allocate(size + xml_memory_page_alignment);
+			if (!memory) return 0;
+
+			// align upwards to page boundary
+			void* page_memory = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1));
+
+			// prepare page structure
+			xml_memory_page* page = xml_memory_page::construct(page_memory);
+
+			page->memory = memory;
+			page->allocator = _root->allocator;
+
+			return page;
+		}
+
+		static void deallocate_page(xml_memory_page* page)
+		{
+			global_deallocate(page->memory);
+		}
+
+		void* allocate_memory_oob(size_t size, xml_memory_page*& out_page);
+
+		void* allocate_memory(size_t size, xml_memory_page*& out_page)
+		{
+			if (_busy_size + size > xml_memory_page_size) return allocate_memory_oob(size, out_page);
+
+			void* buf = _root->data + _busy_size;
+
+			_busy_size += size;
+
+			out_page = _root;
+
+			return buf;
+		}
+
+		void deallocate_memory(void* ptr, size_t size, xml_memory_page* page)
+		{
+			if (page == _root) page->busy_size = _busy_size;
+
+			assert(ptr >= page->data && ptr < page->data + page->busy_size);
+			(void)!ptr;
+
+			page->freed_size += size;
+			assert(page->freed_size <= page->busy_size);
+
+			if (page->freed_size == page->busy_size)
+			{
+				if (page->next == 0)
+				{
+					assert(_root == page);
+
+					// top page freed, just reset sizes
+					page->busy_size = page->freed_size = 0;
+					_busy_size = 0;
+				}
+				else
+				{
+					assert(_root != page);
+					assert(page->prev);
+
+					// remove from the list
+					page->prev->next = page->next;
+					page->next->prev = page->prev;
+
+					// deallocate
+					deallocate_page(page);
+				}
+			}
+		}
+
+		char_t* allocate_string(size_t length)
+		{
+			// allocate memory for string and header block
+			size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t);
+			
+			// round size up to pointer alignment boundary
+			size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1);
+
+			xml_memory_page* page;
+			xml_memory_string_header* header = static_cast<xml_memory_string_header*>(allocate_memory(full_size, page));
+
+			if (!header) return 0;
+
+			// setup header
+			ptrdiff_t page_offset = reinterpret_cast<char*>(header) - page->data;
+
+			assert(page_offset >= 0 && page_offset < (1 << 16));
+			header->page_offset = static_cast<uint16_t>(page_offset);
+
+			// full_size == 0 for large strings that occupy the whole page
+			assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0));
+			header->full_size = static_cast<uint16_t>(full_size < (1 << 16) ? full_size : 0);
+
+			return reinterpret_cast<char_t*>(header + 1);
+		}
+
+		void deallocate_string(char_t* string)
+		{
+			// get header
+			xml_memory_string_header* header = reinterpret_cast<xml_memory_string_header*>(string) - 1;
+
+			// deallocate
+			size_t page_offset = offsetof(xml_memory_page, data) + header->page_offset;
+			xml_memory_page* page = reinterpret_cast<xml_memory_page*>(reinterpret_cast<char*>(header) - page_offset);
+
+			// if full_size == 0 then this string occupies the whole page
+			size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size;
+
+			deallocate_memory(header, full_size, page);
+		}
+
+		xml_memory_page* _root;
+		size_t _busy_size;
+	};
+
+	PUGIXML_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page)
+	{
+		const size_t large_allocation_threshold = xml_memory_page_size / 4;
+
+		xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size);
+		if (!page) return 0;
+
+		if (size <= large_allocation_threshold)
+		{
+			_root->busy_size = _busy_size;
+
+			// insert page at the end of linked list
+			page->prev = _root;
+			_root->next = page;
+			_root = page;
+
+			_busy_size = size;
+		}
+		else
+		{
+			// insert page before the end of linked list, so that it is deleted as soon as possible
+			// the last page is not deleted even if it's empty (see deallocate_memory)
+			assert(_root->prev);
+
+			page->prev = _root->prev;
+			page->next = _root;
+
+			_root->prev->next = page;
+			_root->prev = page;
+		}
+
+		// allocate inside page
+		page->busy_size = size;
+
+		out_page = page;
+		return page->data;
+	}
+}
+
+namespace pugi
+{
+	/// A 'name=value' XML attribute structure.
+	struct xml_attribute_struct
+	{
+		/// Default ctor
+		xml_attribute_struct(xml_memory_page* page): header(reinterpret_cast<uintptr_t>(page)), name(0), value(0), prev_attribute_c(0), next_attribute(0)
+		{
+		}
+
+		uintptr_t header;
+
+		char_t* name;	///< Pointer to attribute name.
+		char_t*	value;	///< Pointer to attribute value.
+
+		xml_attribute_struct* prev_attribute_c;	///< Previous attribute (cyclic list)
+		xml_attribute_struct* next_attribute;	///< Next attribute
+	};
+
+	/// An XML document tree node.
+	struct xml_node_struct
+	{
+		/// Default ctor
+		/// \param type - node type
+		xml_node_struct(xml_memory_page* page, xml_node_type type): header(reinterpret_cast<uintptr_t>(page) | (type - 1)), parent(0), name(0), value(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0)
+		{
+		}
+
+		uintptr_t header;
+
+		xml_node_struct*		parent;					///< Pointer to parent
+
+		char_t*					name;					///< Pointer to element name.
+		char_t*					value;					///< Pointer to any associated string data.
+
+		xml_node_struct*		first_child;			///< First child
+		
+		xml_node_struct*		prev_sibling_c;			///< Left brother (cyclic list)
+		xml_node_struct*		next_sibling;			///< Right brother
+		
+		xml_attribute_struct*	first_attribute;		///< First attribute
+	};
+}
+
+namespace
+{
+	struct xml_document_struct: public xml_node_struct, public xml_allocator
+	{
+		xml_document_struct(xml_memory_page* page): xml_node_struct(page, node_document), xml_allocator(page), buffer(0)
+		{
+		}
+
+		const char_t* buffer;
+	};
+
+	static inline xml_allocator& get_allocator(const xml_node_struct* node)
+	{
+		assert(node);
+
+		return *reinterpret_cast<xml_memory_page*>(node->header & xml_memory_page_pointer_mask)->allocator;
+	}
+}
+
+// Low-level DOM operations
+namespace
+{
+	inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc)
+	{
+		xml_memory_page* page;
+		void* memory = alloc.allocate_memory(sizeof(xml_attribute_struct), page);
+
+		return new (memory) xml_attribute_struct(page);
+	}
+
+	inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type)
+	{
+		xml_memory_page* page;
+		void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page);
+
+		return new (memory) xml_node_struct(page, type);
+	}
+
+	inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc)
+	{
+		uintptr_t header = a->header;
+
+		if (header & xml_memory_page_name_allocated_mask) alloc.deallocate_string(a->name);
+		if (header & xml_memory_page_value_allocated_mask) alloc.deallocate_string(a->value);
+
+		alloc.deallocate_memory(a, sizeof(xml_attribute_struct), reinterpret_cast<xml_memory_page*>(header & xml_memory_page_pointer_mask));
+	}
+
+	inline void destroy_node(xml_node_struct* n, xml_allocator& alloc)
+	{
+		uintptr_t header = n->header;
+
+		if (header & xml_memory_page_name_allocated_mask) alloc.deallocate_string(n->name);
+		if (header & xml_memory_page_value_allocated_mask) alloc.deallocate_string(n->value);
+
+		for (xml_attribute_struct* attr = n->first_attribute; attr; )
+		{
+			xml_attribute_struct* next = attr->next_attribute;
+
+			destroy_attribute(attr, alloc);
+
+			attr = next;
+		}
+
+		for (xml_node_struct* child = n->first_child; child; )
+		{
+			xml_node_struct* next = child->next_sibling;
+
+			destroy_node(child, alloc);
+
+			child = next;
+		}
+
+		alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast<xml_memory_page*>(header & xml_memory_page_pointer_mask));
+	}
+
+	PUGIXML_NO_INLINE xml_node_struct* append_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element)
+	{
+		xml_node_struct* child = allocate_node(alloc, type);
+		if (!child) return 0;
+
+		child->parent = node;
+
+		xml_node_struct* first_child = node->first_child;
+			
+		if (first_child)
+		{
+			xml_node_struct* last_child = first_child->prev_sibling_c;
+
+			last_child->next_sibling = child;
+			child->prev_sibling_c = last_child;
+			first_child->prev_sibling_c = child;
+		}
+		else
+		{
+			node->first_child = child;
+			child->prev_sibling_c = child;
+		}
+			
+		return child;
+	}
+
+	PUGIXML_NO_INLINE xml_attribute_struct* append_attribute_ll(xml_node_struct* node, xml_allocator& alloc)
+	{
+		xml_attribute_struct* a = allocate_attribute(alloc);
+		if (!a) return 0;
+
+		xml_attribute_struct* first_attribute = node->first_attribute;
+
+		if (first_attribute)
+		{
+			xml_attribute_struct* last_attribute = first_attribute->prev_attribute_c;
+
+			last_attribute->next_attribute = a;
+			a->prev_attribute_c = last_attribute;
+			first_attribute->prev_attribute_c = a;
+		}
+		else
+		{
+			node->first_attribute = a;
+			a->prev_attribute_c = a;
+		}
+			
+		return a;
+	}
+}
+
+// Helper classes for code generation
+namespace
+{
+	struct opt_false
+	{
+		enum { value = 0 };
+	};
+
+	struct opt_true
+	{
+		enum { value = 1 };
+	};
+}
+
+// Unicode utilities
+namespace
+{
+	inline uint16_t endian_swap(uint16_t value)
+	{
+		return static_cast<uint16_t>(((value & 0xff) << 8) | (value >> 8));
+	}
+
+	inline uint32_t endian_swap(uint32_t value)
+	{
+		return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24);
+	}
+
+	struct utf8_counter
+	{
+		typedef size_t value_type;
+
+		static value_type low(value_type result, uint32_t ch)
+		{
+			// U+0000..U+007F
+			if (ch < 0x80) return result + 1;
+			// U+0080..U+07FF
+			else if (ch < 0x800) return result + 2;
+			// U+0800..U+FFFF
+			else return result + 3;
+		}
+
+		static value_type high(value_type result, uint32_t)
+		{
+			// U+10000..U+10FFFF
+			return result + 4;
+		}
+	};
+
+	struct utf8_writer
+	{
+		typedef uint8_t* value_type;
+
+		static value_type low(value_type result, uint32_t ch)
+		{
+			// U+0000..U+007F
+			if (ch < 0x80)
+			{
+				*result = static_cast<uint8_t>(ch);
+				return result + 1;
+			}
+			// U+0080..U+07FF
+			else if (ch < 0x800)
+			{
+				result[0] = static_cast<uint8_t>(0xC0 | (ch >> 6));
+				result[1] = static_cast<uint8_t>(0x80 | (ch & 0x3F));
+				return result + 2;
+			}
+			// U+0800..U+FFFF
+			else
+			{
+				result[0] = static_cast<uint8_t>(0xE0 | (ch >> 12));
+				result[1] = static_cast<uint8_t>(0x80 | ((ch >> 6) & 0x3F));
+				result[2] = static_cast<uint8_t>(0x80 | (ch & 0x3F));
+				return result + 3;
+			}
+		}
+
+		static value_type high(value_type result, uint32_t ch)
+		{
+			// U+10000..U+10FFFF
+			result[0] = static_cast<uint8_t>(0xF0 | (ch >> 18));
+			result[1] = static_cast<uint8_t>(0x80 | ((ch >> 12) & 0x3F));
+			result[2] = static_cast<uint8_t>(0x80 | ((ch >> 6) & 0x3F));
+			result[3] = static_cast<uint8_t>(0x80 | (ch & 0x3F));
+			return result + 4;
+		}
+
+		static value_type any(value_type result, uint32_t ch)
+		{
+			return (ch < 0x10000) ? low(result, ch) : high(result, ch);
+		}
+	};
+
+	struct utf16_counter
+	{
+		typedef size_t value_type;
+
+		static value_type low(value_type result, uint32_t)
+		{
+			return result + 1;
+		}
+
+		static value_type high(value_type result, uint32_t)
+		{
+			return result + 2;
+		}
+	};
+
+	struct utf16_writer
+	{
+		typedef uint16_t* value_type;
+
+		static value_type low(value_type result, uint32_t ch)
+		{
+			*result = static_cast<uint16_t>(ch);
+
+			return result + 1;
+		}
+
+		static value_type high(value_type result, uint32_t ch)
+		{
+			uint32_t msh = (uint32_t)(ch - 0x10000) >> 10;
+			uint32_t lsh = (uint32_t)(ch - 0x10000) & 0x3ff;
+
+			result[0] = static_cast<uint16_t>(0xD800 + msh);
+			result[1] = static_cast<uint16_t>(0xDC00 + lsh);
+
+			return result + 2;
+		}
+
+		static value_type any(value_type result, uint32_t ch)
+		{
+			return (ch < 0x10000) ? low(result, ch) : high(result, ch);
+		}
+	};
+
+	struct utf32_counter
+	{
+		typedef size_t value_type;
+
+		static value_type low(value_type result, uint32_t)
+		{
+			return result + 1;
+		}
+
+		static value_type high(value_type result, uint32_t)
+		{
+			return result + 1;
+		}
+	};
+
+	struct utf32_writer
+	{
+		typedef uint32_t* value_type;
+
+		static value_type low(value_type result, uint32_t ch)
+		{
+			*result = ch;
+
+			return result + 1;
+		}
+
+		static value_type high(value_type result, uint32_t ch)
+		{
+			*result = ch;
+
+			return result + 1;
+		}
+
+		static value_type any(value_type result, uint32_t ch)
+		{
+			*result = ch;
+
+			return result + 1;
+		}
+	};
+
+	template <size_t size> struct wchar_selector;
+
+	template <> struct wchar_selector<2>
+	{
+		typedef uint16_t type;
+		typedef utf16_counter counter;
+		typedef utf16_writer writer;
+	};
+
+	template <> struct wchar_selector<4>
+	{
+		typedef uint32_t type;
+		typedef utf32_counter counter;
+		typedef utf32_writer writer;
+	};
+
+	typedef wchar_selector<sizeof(wchar_t)>::counter wchar_counter;
+	typedef wchar_selector<sizeof(wchar_t)>::writer wchar_writer;
+
+	template <typename Traits, typename opt_swap = opt_false> struct utf_decoder
+	{
+		static inline typename Traits::value_type decode_utf8_block(const uint8_t* data, size_t size, typename Traits::value_type result)
+		{
+			const uint8_t utf8_byte_mask = 0x3f;
+
+			while (size)
+			{
+				uint8_t lead = *data;
+
+				// 0xxxxxxx -> U+0000..U+007F
+				if (lead < 0x80)
+				{
+					result = Traits::low(result, lead);
+					data += 1;
+					size -= 1;
+
+					// process aligned single-byte (ascii) blocks
+					if ((reinterpret_cast<uintptr_t>(data) & 3) == 0)
+					{
+						while (size >= 4 && (*reinterpret_cast<const uint32_t*>(data) & 0x80808080) == 0)
+						{
+							result = Traits::low(result, data[0]);
+							result = Traits::low(result, data[1]);
+							result = Traits::low(result, data[2]);
+							result = Traits::low(result, data[3]);
+							data += 4;
+							size -= 4;
+						}
+					}
+				}
+				// 110xxxxx -> U+0080..U+07FF
+				else if ((unsigned)(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
+				{
+					result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
+					data += 2;
+					size -= 2;
+				}
+				// 1110xxxx -> U+0800-U+FFFF
+				else if ((unsigned)(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
+				{
+					result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
+					data += 3;
+					size -= 3;
+				}
+				// 11110xxx -> U+10000..U+10FFFF
+				else if ((unsigned)(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
+				{
+					result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
+					data += 4;
+					size -= 4;
+				}
+				// 10xxxxxx or 11111xxx -> invalid
+				else
+				{
+					data += 1;
+					size -= 1;
+				}
+			}
+
+			return result;
+		}
+
+		static inline typename Traits::value_type decode_utf16_block(const uint16_t* data, size_t size, typename Traits::value_type result)
+		{
+			const uint16_t* end = data + size;
+
+			while (data < end)
+			{
+				uint16_t lead = opt_swap::value ? endian_swap(*data) : *data;
+
+				// U+0000..U+D7FF
+				if (lead < 0xD800)
+				{
+					result = Traits::low(result, lead);
+					data += 1;
+				}
+				// U+E000..U+FFFF
+				else if ((unsigned)(lead - 0xE000) < 0x2000)
+				{
+					result = Traits::low(result, lead);
+					data += 1;
+				}
+				// surrogate pair lead
+				else if ((unsigned)(lead - 0xD800) < 0x400 && data + 1 < end)
+				{
+					uint16_t next = opt_swap::value ? endian_swap(data[1]) : data[1];
+
+					if ((unsigned)(next - 0xDC00) < 0x400)
+					{
+						result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
+						data += 2;
+					}
+					else
+					{
+						data += 1;
+					}
+				}
+				else
+				{
+					data += 1;
+				}
+			}
+
+			return result;
+		}
+
+		static inline typename Traits::value_type decode_utf32_block(const uint32_t* data, size_t size, typename Traits::value_type result)
+		{
+			const uint32_t* end = data + size;
+
+			while (data < end)
+			{
+				uint32_t lead = opt_swap::value ? endian_swap(*data) : *data;
+
+				// U+0000..U+FFFF
+				if (lead < 0x10000)
+				{
+					result = Traits::low(result, lead);
+					data += 1;
+				}
+				// U+10000..U+10FFFF
+				else
+				{
+					result = Traits::high(result, lead);
+					data += 1;
+				}
+			}
+
+			return result;
+		}
+	};
+
+	template <typename T> inline void convert_utf_endian_swap(T* result, const T* data, size_t length)
+	{
+		for (size_t i = 0; i < length; ++i) result[i] = endian_swap(data[i]);
+	}
+
+	inline void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length)
+	{
+		for (size_t i = 0; i < length; ++i) result[i] = static_cast<wchar_t>(endian_swap(static_cast<wchar_selector<sizeof(wchar_t)>::type>(data[i])));
+	}
+}
+
+namespace
+{	
+	enum chartype_t
+	{
+		ct_parse_pcdata = 1,	// \0, &, \r, <
+		ct_parse_attr = 2,		// \0, &, \r, ', "
+		ct_parse_attr_ws = 4,	// \0, &, \r, ', ", \n, tab
+		ct_space = 8,			// \r, \n, space, tab
+		ct_parse_cdata = 16,	// \0, ], >, \r
+		ct_parse_comment = 32,	// \0, -, >, \r
+		ct_symbol = 64,			// Any symbol > 127, a-z, A-Z, 0-9, _, :, -, .
+		ct_start_symbol = 128	// Any symbol > 127, a-z, A-Z, _, :
+	};
+
+	const unsigned char chartype_table[256] =
+	{
+		55,  0,   0,   0,   0,   0,   0,   0,      0,   12,  12,  0,   0,   63,  0,   0,   // 0-15
+		0,   0,   0,   0,   0,   0,   0,   0,      0,   0,   0,   0,   0,   0,   0,   0,   // 16-31
+		8,   0,   6,   0,   0,   0,   7,   6,      0,   0,   0,   0,   0,   96,  64,  0,   // 32-47
+		64,  64,  64,  64,  64,  64,  64,  64,     64,  64,  192, 0,   1,   0,   48,  0,   // 48-63
+		0,   192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192, // 64-79
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 0,   0,   16,  0,   192, // 80-95
+		0,   192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192, // 96-111
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 0, 0, 0, 0, 0,           // 112-127
+
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192, // 128+
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192,
+		192, 192, 192, 192, 192, 192, 192, 192,    192, 192, 192, 192, 192, 192, 192, 192
+	};
+
+	enum chartypex_t
+	{
+		ctx_special_pcdata = 1,   // Any symbol >= 0 and < 32 (except \t, \r, \n), &, <, >
+		ctx_special_attr = 2,     // Any symbol >= 0 and < 32 (except \t), &, <, >, "
+		ctx_start_symbol = 4,	  // Any symbol > 127, a-z, A-Z, _
+		ctx_digit = 8,			  // 0-9
+		ctx_symbol = 16			  // Any symbol > 127, a-z, A-Z, 0-9, _, -, .
+	};
+	
+	const unsigned char chartypex_table[256] =
+	{
+		3,  3,  3,  3,  3,  3,  3,  3,     3,  0,  2,  3,  3,  2,  3,  3,     // 0-15
+		3,  3,  3,  3,  3,  3,  3,  3,     3,  3,  3,  3,  3,  3,  3,  3,     // 16-31
+		0,  0,  2,  0,  0,  0,  3,  0,     0,  0,  0,  0,  0, 16, 16,  0,     // 32-47
+		24, 24, 24, 24, 24, 24, 24, 24,    24, 24, 0,  0,  3,  0,  3,  0,     // 48-63
+
+		0,  20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,    // 64-79
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 0,  0,  0,  0,  20,    // 80-95
+		0,  20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,    // 96-111
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 0,  0,  0,  0,  0,     // 112-127
+
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,    // 128+
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20,
+		20, 20, 20, 20, 20, 20, 20, 20,    20, 20, 20, 20, 20, 20, 20, 20
+	};
+	
+#ifdef PUGIXML_WCHAR_MODE
+	#define IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct))
+#else
+	#define IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct))
+#endif
+
+	#define IS_CHARTYPE(c, ct) IS_CHARTYPE_IMPL(c, ct, chartype_table)
+	#define IS_CHARTYPEX(c, ct) IS_CHARTYPE_IMPL(c, ct, chartypex_table)
+
+	bool is_little_endian()
+	{
+		unsigned int ui = 1;
+
+		return *reinterpret_cast<unsigned char*>(&ui) == 1;
+	}
+
+	xml_encoding get_wchar_encoding()
+	{
+		STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4);
+
+		if (sizeof(wchar_t) == 2)
+			return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+		else 
+			return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+	}
+
+	xml_encoding guess_buffer_encoding(uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
+	{
+		// look for BOM in first few bytes
+		if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff) return encoding_utf32_be;
+		if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0) return encoding_utf32_le;
+		if (d0 == 0xfe && d1 == 0xff) return encoding_utf16_be;
+		if (d0 == 0xff && d1 == 0xfe) return encoding_utf16_le;
+		if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf) return encoding_utf8;
+
+		// look for <, <? or <?xm in various encodings
+		if (d0 == 0 && d1 == 0 && d2 == 0 && d3 == 0x3c) return encoding_utf32_be;
+		if (d0 == 0x3c && d1 == 0 && d2 == 0 && d3 == 0) return encoding_utf32_le;
+		if (d0 == 0 && d1 == 0x3c && d2 == 0 && d3 == 0x3f) return encoding_utf16_be;
+		if (d0 == 0x3c && d1 == 0 && d2 == 0x3f && d3 == 0) return encoding_utf16_le;
+		if (d0 == 0x3c && d1 == 0x3f && d2 == 0x78 && d3 == 0x6d) return encoding_utf8;
+
+		// look for utf16 < followed by node name (this may fail, but is better than utf8 since it's zero terminated so early)
+		if (d0 == 0 && d1 == 0x3c) return encoding_utf16_be;
+		if (d0 == 0x3c && d1 == 0) return encoding_utf16_le;
+
+		// no known BOM detected, assume utf8
+		return encoding_utf8;
+	}
+
+	xml_encoding get_buffer_encoding(xml_encoding encoding, const void* contents, size_t size)
+	{
+		// replace wchar encoding with utf implementation
+		if (encoding == encoding_wchar) return get_wchar_encoding();
+
+		// replace utf16 encoding with utf16 with specific endianness
+		if (encoding == encoding_utf16) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+		// replace utf32 encoding with utf32 with specific endianness
+		if (encoding == encoding_utf32) return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+		// only do autodetection if no explicit encoding is requested
+		if (encoding != encoding_auto) return encoding;
+
+		// skip encoding autodetection if input buffer is too small
+		if (size < 4) return encoding_utf8;
+
+		// try to guess encoding (based on XML specification, Appendix F.1)
+		const uint8_t* data = static_cast<const uint8_t*>(contents);
+
+		DMC_VOLATILE uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3];
+
+		return guess_buffer_encoding(d0, d1, d2, d3);
+	}
+
+	bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable)
+	{
+		if (is_mutable)
+		{
+			out_buffer = static_cast<char_t*>(const_cast<void*>(contents));
+		}
+		else
+		{
+			void* buffer = global_allocate(size > 0 ? size : 1);
+			if (!buffer) return false;
+
+			memcpy(buffer, contents, size);
+
+			out_buffer = static_cast<char_t*>(buffer);
+		}
+
+		out_length = size / sizeof(char_t);
+
+		return true;
+	}
+
+#ifdef PUGIXML_WCHAR_MODE
+	inline bool need_endian_swap_utf(xml_encoding le, xml_encoding re)
+	{
+		return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) ||
+		       (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be);
+	}
+
+	bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable)
+	{
+		const char_t* data = static_cast<const char_t*>(contents);
+	
+		if (is_mutable)
+		{
+			out_buffer = const_cast<char_t*>(data);
+		}
+		else
+		{
+			out_buffer = static_cast<char_t*>(global_allocate(size > 0 ? size : 1));
+			if (!out_buffer) return false;
+		}
+
+		out_length = size / sizeof(char_t);
+
+		convert_wchar_endian_swap(out_buffer, data, out_length);
+
+		return true;
+	}
+
+	bool convert_buffer_utf8(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size)
+	{
+		const uint8_t* data = static_cast<const uint8_t*>(contents);
+
+		// first pass: get length in wchar_t units
+		out_length = utf_decoder<wchar_counter>::decode_utf8_block(data, size, 0);
+
+		// allocate buffer of suitable length
+		out_buffer = static_cast<char_t*>(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t)));
+		if (!out_buffer) return false;
+
+		// second pass: convert utf8 input to wchar_t
+		wchar_writer::value_type out_begin = reinterpret_cast<wchar_writer::value_type>(out_buffer);
+		wchar_writer::value_type out_end = utf_decoder<wchar_writer>::decode_utf8_block(data, size, out_begin);
+
+		assert(out_end == out_begin + out_length);
+		(void)!out_end;
+
+		return true;
+	}
+
+	template <typename opt_swap> bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap)
+	{
+		const uint16_t* data = static_cast<const uint16_t*>(contents);
+		size_t length = size / sizeof(uint16_t);
+
+		// first pass: get length in wchar_t units
+		out_length = utf_decoder<wchar_counter, opt_swap>::decode_utf16_block(data, length, 0);
+
+		// allocate buffer of suitable length
+		out_buffer = static_cast<char_t*>(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t)));
+		if (!out_buffer) return false;
+
+		// second pass: convert utf16 input to wchar_t
+		wchar_writer::value_type out_begin = reinterpret_cast<wchar_writer::value_type>(out_buffer);
+		wchar_writer::value_type out_end = utf_decoder<wchar_writer, opt_swap>::decode_utf16_block(data, length, out_begin);
+
+		assert(out_end == out_begin + out_length);
+		(void)!out_end;
+
+		return true;
+	}
+
+	template <typename opt_swap> bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap)
+	{
+		const uint32_t* data = static_cast<const uint32_t*>(contents);
+		size_t length = size / sizeof(uint32_t);
+
+		// first pass: get length in wchar_t units
+		out_length = utf_decoder<wchar_counter, opt_swap>::decode_utf32_block(data, length, 0);
+
+		// allocate buffer of suitable length
+		out_buffer = static_cast<char_t*>(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t)));
+		if (!out_buffer) return false;
+
+		// second pass: convert utf32 input to wchar_t
+		wchar_writer::value_type out_begin = reinterpret_cast<wchar_writer::value_type>(out_buffer);
+		wchar_writer::value_type out_end = utf_decoder<wchar_writer, opt_swap>::decode_utf32_block(data, length, out_begin);
+
+		assert(out_end == out_begin + out_length);
+		(void)!out_end;
+
+		return true;
+	}
+
+	bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable)
+	{
+		// get native encoding
+		xml_encoding wchar_encoding = get_wchar_encoding();
+
+		// fast path: no conversion required
+		if (encoding == wchar_encoding) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
+
+		// only endian-swapping is required
+		if (need_endian_swap_utf(encoding, wchar_encoding)) return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable);
+
+		// source encoding is utf8
+		if (encoding == encoding_utf8) return convert_buffer_utf8(out_buffer, out_length, contents, size);
+
+		// source encoding is utf16
+		if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
+		{
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+			return (native_encoding == encoding) ?
+				convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) :
+				convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true());
+		}
+
+		// source encoding is utf32
+		if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
+		{
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+			return (native_encoding == encoding) ?
+				convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) :
+				convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true());
+		}
+
+		assert(!"Invalid encoding");
+		return false;
+	}
+#else
+	template <typename opt_swap> bool convert_buffer_utf16(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap)
+	{
+		const uint16_t* data = static_cast<const uint16_t*>(contents);
+		size_t length = size / sizeof(uint16_t);
+
+		// first pass: get length in utf8 units
+		out_length = utf_decoder<utf8_counter, opt_swap>::decode_utf16_block(data, length, 0);
+
+		// allocate buffer of suitable length
+		out_buffer = static_cast<char_t*>(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t)));
+		if (!out_buffer) return false;
+
+		// second pass: convert utf16 input to utf8
+		uint8_t* out_begin = reinterpret_cast<uint8_t*>(out_buffer);
+		uint8_t* out_end = utf_decoder<utf8_writer, opt_swap>::decode_utf16_block(data, length, out_begin);
+
+		assert(out_end == out_begin + out_length);
+		(void)!out_end;
+
+		return true;
+	}
+
+	template <typename opt_swap> bool convert_buffer_utf32(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, opt_swap)
+	{
+		const uint32_t* data = static_cast<const uint32_t*>(contents);
+		size_t length = size / sizeof(uint32_t);
+
+		// first pass: get length in utf8 units
+		out_length = utf_decoder<utf8_counter, opt_swap>::decode_utf32_block(data, length, 0);
+
+		// allocate buffer of suitable length
+		out_buffer = static_cast<char_t*>(global_allocate((out_length > 0 ? out_length : 1) * sizeof(char_t)));
+		if (!out_buffer) return false;
+
+		// second pass: convert utf32 input to utf8
+		uint8_t* out_begin = reinterpret_cast<uint8_t*>(out_buffer);
+		uint8_t* out_end = utf_decoder<utf8_writer, opt_swap>::decode_utf32_block(data, length, out_begin);
+
+		assert(out_end == out_begin + out_length);
+		(void)!out_end;
+
+		return true;
+	}
+
+	bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable)
+	{
+		// fast path: no conversion required
+		if (encoding == encoding_utf8) return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
+
+		// source encoding is utf16
+		if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
+		{
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+			return (native_encoding == encoding) ?
+				convert_buffer_utf16(out_buffer, out_length, contents, size, opt_false()) :
+				convert_buffer_utf16(out_buffer, out_length, contents, size, opt_true());
+		}
+
+		// source encoding is utf32
+		if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
+		{
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+			return (native_encoding == encoding) ?
+				convert_buffer_utf32(out_buffer, out_length, contents, size, opt_false()) :
+				convert_buffer_utf32(out_buffer, out_length, contents, size, opt_true());
+		}
+
+		assert(!"Invalid encoding");
+		return false;
+	}
+#endif
+
+	size_t as_utf8_begin(const wchar_t* str, size_t length)
+	{
+		STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4);
+
+		// get length in utf8 characters
+		return sizeof(wchar_t) == 2 ?
+			utf_decoder<utf8_counter>::decode_utf16_block(reinterpret_cast<const uint16_t*>(str), length, 0) :
+			utf_decoder<utf8_counter>::decode_utf32_block(reinterpret_cast<const uint32_t*>(str), length, 0);
+    }
+
+    void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length)
+    {
+		STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4);
+
+        // convert to utf8
+        uint8_t* begin = reinterpret_cast<uint8_t*>(buffer);
+        uint8_t* end = sizeof(wchar_t) == 2 ?
+            utf_decoder<utf8_writer>::decode_utf16_block(reinterpret_cast<const uint16_t*>(str), length, begin) :
+            utf_decoder<utf8_writer>::decode_utf32_block(reinterpret_cast<const uint32_t*>(str), length, begin);
+    
+        assert(begin + size == end);
+        (void)!end;
+
+		// zero-terminate
+		buffer[size] = 0;
+	}
+    
+#ifndef PUGIXML_NO_STL
+    std::string as_utf8_impl(const wchar_t* str, size_t length)
+    {
+		// first pass: get length in utf8 characters
+        size_t size = as_utf8_begin(str, length);
+
+		// allocate resulting string
+		std::string result;
+		result.resize(size);
+
+		// second pass: convert to utf8
+		if (size > 0) as_utf8_end(&result[0], size, str, length);
+
+	  	return result;
+    }
+
+	std::wstring as_wide_impl(const char* str, size_t size)
+	{
+		const uint8_t* data = reinterpret_cast<const uint8_t*>(str);
+
+		// first pass: get length in wchar_t units
+		size_t length = utf_decoder<wchar_counter>::decode_utf8_block(data, size, 0);
+
+		// allocate resulting string
+		std::wstring result;
+		result.resize(length);
+
+		// second pass: convert to wchar_t
+		if (length > 0)
+		{
+			wchar_writer::value_type begin = reinterpret_cast<wchar_writer::value_type>(&result[0]);
+			wchar_writer::value_type end = utf_decoder<wchar_writer>::decode_utf8_block(data, size, begin);
+
+			assert(begin + length == end);
+			(void)!end;
+		}
+
+		return result;
+	}
+#endif
+
+	inline bool strcpy_insitu_allow(size_t length, uintptr_t allocated, char_t* target)
+	{
+		assert(target);
+		size_t target_length = strlength(target);
+
+		// always reuse document buffer memory if possible
+		if (!allocated) return target_length >= length;
+
+		// reuse heap memory if waste is not too great
+		const size_t reuse_threshold = 32;
+
+		return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2);
+	}
+
+	bool strcpy_insitu(char_t*& dest, uintptr_t& header, uintptr_t header_mask, const char_t* source)
+	{
+		size_t source_length = strlength(source);
+
+		if (source_length == 0)
+		{
+			// empty string and null pointer are equivalent, so just deallocate old memory
+			xml_allocator* alloc = reinterpret_cast<xml_memory_page*>(header & xml_memory_page_pointer_mask)->allocator;
+
+			if (header & header_mask) alloc->deallocate_string(dest);
+			
+			// mark the string as not allocated
+			dest = 0;
+			header &= ~header_mask;
+
+			return true;
+		}
+		else if (dest && strcpy_insitu_allow(source_length, header & header_mask, dest))
+		{
+			// we can reuse old buffer, so just copy the new data (including zero terminator)
+			memcpy(dest, source, (source_length + 1) * sizeof(char_t));
+			
+			return true;
+		}
+		else
+		{
+			xml_allocator* alloc = reinterpret_cast<xml_memory_page*>(header & xml_memory_page_pointer_mask)->allocator;
+
+			// allocate new buffer
+			char_t* buf = alloc->allocate_string(source_length + 1);
+			if (!buf) return false;
+
+			// copy the string (including zero terminator)
+			memcpy(buf, source, (source_length + 1) * sizeof(char_t));
+
+			// deallocate old buffer (*after* the above to protect against overlapping memory and/or allocation failures)
+			if (header & header_mask) alloc->deallocate_string(dest);
+			
+			// the string is now allocated, so set the flag
+			dest = buf;
+			header |= header_mask;
+
+			return true;
+		}
+	}
+
+	struct gap
+	{
+		char_t* end;
+		size_t size;
+			
+		gap(): end(0), size(0)
+		{
+		}
+			
+		// Push new gap, move s count bytes further (skipping the gap).
+		// Collapse previous gap.
+		void push(char_t*& s, size_t count)
+		{
+			if (end) // there was a gap already; collapse it
+			{
+				// Move [old_gap_end, new_gap_start) to [old_gap_start, ...)
+				assert(s >= end);
+				memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
+			}
+				
+			s += count; // end of current gap
+				
+			// "merge" two gaps
+			end = s;
+			size += count;
+		}
+			
+		// Collapse all gaps, return past-the-end pointer
+		char_t* flush(char_t* s)
+		{
+			if (end)
+			{
+				// Move [old_gap_end, current_pos) to [old_gap_start, ...)
+				assert(s >= end);
+				memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
+
+				return s - size;
+			}
+			else return s;
+		}
+	};
+	
+	char_t* strconv_escape(char_t* s, gap& g)
+	{
+		char_t* stre = s + 1;
+
+		switch (*stre)
+		{
+			case '#':	// &#...
+			{
+				unsigned int ucsc = 0;
+
+				if (stre[1] == 'x') // &#x... (hex code)
+				{
+					stre += 2;
+
+					char_t ch = *stre;
+
+					if (ch == ';') return stre;
+
+					for (;;)
+					{
+						if (static_cast<unsigned int>(ch - '0') <= 9)
+							ucsc = 16 * ucsc + (ch - '0');
+						else if (static_cast<unsigned int>((ch | ' ') - 'a') <= 5)
+							ucsc = 16 * ucsc + ((ch | ' ') - 'a' + 10);
+						else if (ch == ';')
+							break;
+						else // cancel
+							return stre;
+
+						ch = *++stre;
+					}
+					
+					++stre;
+				}
+				else	// &#... (dec code)
+				{
+					char_t ch = *++stre;
+
+					if (ch == ';') return stre;
+
+					for (;;)
+					{
+						if (static_cast<unsigned int>(ch - '0') <= 9)
+							ucsc = 10 * ucsc + (ch - '0');
+						else if (ch == ';')
+							break;
+						else // cancel
+							return stre;
+
+						ch = *++stre;
+					}
+					
+					++stre;
+				}
+
+			#ifdef PUGIXML_WCHAR_MODE
+				s = reinterpret_cast<char_t*>(wchar_writer::any(reinterpret_cast<wchar_writer::value_type>(s), ucsc));
+			#else
+				s = reinterpret_cast<char_t*>(utf8_writer::any(reinterpret_cast<uint8_t*>(s), ucsc));
+			#endif
+					
+				g.push(s, stre - s);
+				return stre;
+			}
+			case 'a':	// &a
+			{
+				++stre;
+
+				if (*stre == 'm') // &am
+				{
+					if (*++stre == 'p' && *++stre == ';') // &amp;
+					{
+						*s++ = '&';
+						++stre;
+							
+						g.push(s, stre - s);
+						return stre;
+					}
+				}
+				else if (*stre == 'p') // &ap
+				{
+					if (*++stre == 'o' && *++stre == 's' && *++stre == ';') // &apos;
+					{
+						*s++ = '\'';
+						++stre;
+
+						g.push(s, stre - s);
+						return stre;
+					}
+				}
+				break;
+			}
+			case 'g': // &g
+			{
+				if (*++stre == 't' && *++stre == ';') // &gt;
+				{
+					*s++ = '>';
+					++stre;
+					
+					g.push(s, stre - s);
+					return stre;
+				}
+				break;
+			}
+			case 'l': // &l
+			{
+				if (*++stre == 't' && *++stre == ';') // &lt;
+				{
+					*s++ = '<';
+					++stre;
+						
+					g.push(s, stre - s);
+					return stre;
+				}
+				break;
+			}
+			case 'q': // &q
+			{
+				if (*++stre == 'u' && *++stre == 'o' && *++stre == 't' && *++stre == ';') // &quot;
+				{
+					*s++ = '"';
+					++stre;
+					
+					g.push(s, stre - s);
+					return stre;
+				}
+				break;
+			}
+		}
+		
+		return stre;
+	}
+
+	// Utility macro for last character handling
+	#define ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e)))
+
+	char_t* strconv_comment(char_t* s, char_t endch)
+	{
+		gap g;
+		
+		while (true)
+		{
+			while (!IS_CHARTYPE(*s, ct_parse_comment)) ++s;
+		
+			if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+			{
+				*s++ = '\n'; // replace first one with 0x0a
+				
+				if (*s == '\n') g.push(s, 1);
+			}
+			else if (s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>')) // comment ends here
+			{
+				*g.flush(s) = 0;
+				
+				return s + (s[2] == '>' ? 3 : 2);
+			}
+			else if (*s == 0)
+			{
+				return 0;
+			}
+			else ++s;
+		}
+	}
+
+	char_t* strconv_cdata(char_t* s, char_t endch)
+	{
+		gap g;
+			
+		while (true)
+		{
+			while (!IS_CHARTYPE(*s, ct_parse_cdata)) ++s;
+			
+			if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+			{
+				*s++ = '\n'; // replace first one with 0x0a
+				
+				if (*s == '\n') g.push(s, 1);
+			}
+			else if (s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>')) // CDATA ends here
+			{
+				*g.flush(s) = 0;
+				
+				return s + 1;
+			}
+			else if (*s == 0)
+			{
+				return 0;
+			}
+			else ++s;
+		}
+	}
+	
+	typedef char_t* (*strconv_pcdata_t)(char_t*);
+		
+	template <typename opt_eol, typename opt_escape> struct strconv_pcdata_impl
+	{
+		static char_t* parse(char_t* s)
+		{
+			gap g;
+			
+			while (true)
+			{
+				while (!IS_CHARTYPE(*s, ct_parse_pcdata)) ++s;
+					
+				if (*s == '<') // PCDATA ends here
+				{
+					*g.flush(s) = 0;
+					
+					return s + 1;
+				}
+				else if (opt_eol::value && *s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
+				{
+					*s++ = '\n'; // replace first one with 0x0a
+					
+					if (*s == '\n') g.push(s, 1);
+				}
+				else if (opt_escape::value && *s == '&')
+				{
+					s = strconv_escape(s, g);
+				}
+				else if (*s == 0)
+				{
+					return s;
+				}
+				else ++s;
+			}
+		}
+	};
+	
+	strconv_pcdata_t get_strconv_pcdata(unsigned int optmask)
+	{
+		STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20);
+
+		switch ((optmask >> 4) & 3) // get bitmask for flags (eol escapes)
+		{
+		case 0: return strconv_pcdata_impl<opt_false, opt_false>::parse;
+		case 1: return strconv_pcdata_impl<opt_false, opt_true>::parse;
+		case 2: return strconv_pcdata_impl<opt_true, opt_false>::parse;
+		case 3: return strconv_pcdata_impl<opt_true, opt_true>::parse;
+		default: return 0; // should not get here
+		}
+	}
+
+	typedef char_t* (*strconv_attribute_t)(char_t*, char_t);
+	
+	template <typename opt_escape> struct strconv_attribute_impl
+	{
+		static char_t* parse_wnorm(char_t* s, char_t end_quote)
+		{
+			gap g;
+
+			// trim leading whitespaces
+			if (IS_CHARTYPE(*s, ct_space))
+			{
+				char_t* str = s;
+				
+				do ++str;
+				while (IS_CHARTYPE(*str, ct_space));
+				
+				g.push(s, str - s);
+			}
+
+			while (true)
+			{
+				while (!IS_CHARTYPE(*s, ct_parse_attr_ws | ct_space)) ++s;
+				
+				if (*s == end_quote)
+				{
+					char_t* str = g.flush(s);
+					
+					do *str-- = 0;
+					while (IS_CHARTYPE(*str, ct_space));
+				
+					return s + 1;
+				}
+				else if (IS_CHARTYPE(*s, ct_space))
+				{
+					*s++ = ' ';
+		
+					if (IS_CHARTYPE(*s, ct_space))
+					{
+						char_t* str = s + 1;
+						while (IS_CHARTYPE(*str, ct_space)) ++str;
+						
+						g.push(s, str - s);
+					}
+				}
+				else if (opt_escape::value && *s == '&')
+				{
+					s = strconv_escape(s, g);
+				}
+				else if (!*s)
+				{
+					return 0;
+				}
+				else ++s;
+			}
+		}
+
+		static char_t* parse_wconv(char_t* s, char_t end_quote)
+		{
+			gap g;
+
+			while (true)
+			{
+				while (!IS_CHARTYPE(*s, ct_parse_attr_ws)) ++s;
+				
+				if (*s == end_quote)
+				{
+					*g.flush(s) = 0;
+				
+					return s + 1;
+				}
+				else if (IS_CHARTYPE(*s, ct_space))
+				{
+					if (*s == '\r')
+					{
+						*s++ = ' ';
+				
+						if (*s == '\n') g.push(s, 1);
+					}
+					else *s++ = ' ';
+				}
+				else if (opt_escape::value && *s == '&')
+				{
+					s = strconv_escape(s, g);
+				}
+				else if (!*s)
+				{
+					return 0;
+				}
+				else ++s;
+			}
+		}
+
+		static char_t* parse_eol(char_t* s, char_t end_quote)
+		{
+			gap g;
+
+			while (true)
+			{
+				while (!IS_CHARTYPE(*s, ct_parse_attr)) ++s;
+				
+				if (*s == end_quote)
+				{
+					*g.flush(s) = 0;
+				
+					return s + 1;
+				}
+				else if (*s == '\r')
+				{
+					*s++ = '\n';
+					
+					if (*s == '\n') g.push(s, 1);
+				}
+				else if (opt_escape::value && *s == '&')
+				{
+					s = strconv_escape(s, g);
+				}
+				else if (!*s)
+				{
+					return 0;
+				}
+				else ++s;
+			}
+		}
+
+		static char_t* parse_simple(char_t* s, char_t end_quote)
+		{
+			gap g;
+
+			while (true)
+			{
+				while (!IS_CHARTYPE(*s, ct_parse_attr)) ++s;
+				
+				if (*s == end_quote)
+				{
+					*g.flush(s) = 0;
+				
+					return s + 1;
+				}
+				else if (opt_escape::value && *s == '&')
+				{
+					s = strconv_escape(s, g);
+				}
+				else if (!*s)
+				{
+					return 0;
+				}
+				else ++s;
+			}
+		}
+	};
+
+	strconv_attribute_t get_strconv_attribute(unsigned int optmask)
+	{
+		STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80);
+		
+		switch ((optmask >> 4) & 15) // get bitmask for flags (wconv wnorm eol escapes)
+		{
+		case 0:  return strconv_attribute_impl<opt_false>::parse_simple;
+		case 1:  return strconv_attribute_impl<opt_true>::parse_simple;
+		case 2:  return strconv_attribute_impl<opt_false>::parse_eol;
+		case 3:  return strconv_attribute_impl<opt_true>::parse_eol;
+		case 4:  return strconv_attribute_impl<opt_false>::parse_wconv;
+		case 5:  return strconv_attribute_impl<opt_true>::parse_wconv;
+		case 6:  return strconv_attribute_impl<opt_false>::parse_wconv;
+		case 7:  return strconv_attribute_impl<opt_true>::parse_wconv;
+		case 8:  return strconv_attribute_impl<opt_false>::parse_wnorm;
+		case 9:  return strconv_attribute_impl<opt_true>::parse_wnorm;
+		case 10: return strconv_attribute_impl<opt_false>::parse_wnorm;
+		case 11: return strconv_attribute_impl<opt_true>::parse_wnorm;
+		case 12: return strconv_attribute_impl<opt_false>::parse_wnorm;
+		case 13: return strconv_attribute_impl<opt_true>::parse_wnorm;
+		case 14: return strconv_attribute_impl<opt_false>::parse_wnorm;
+		case 15: return strconv_attribute_impl<opt_true>::parse_wnorm;
+		default: return 0; // should not get here
+		}
+	}
+
+	inline xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset = 0)
+	{
+		xml_parse_result result;
+		result.status = status;
+		result.offset = offset;
+
+		return result;
+	}
+
+	struct xml_parser
+	{
+		xml_allocator alloc;
+		char_t* error_offset;
+		jmp_buf error_handler;
+		
+		// Parser utilities.
+		#define SKIPWS()			{ while (IS_CHARTYPE(*s, ct_space)) ++s; }
+		#define OPTSET(OPT)			( optmsk & OPT )
+		#define PUSHNODE(TYPE)		{ cursor = append_node(cursor, alloc, TYPE); if (!cursor) THROW_ERROR(status_out_of_memory, s); }
+		#define POPNODE()			{ cursor = cursor->parent; }
+		#define SCANFOR(X)			{ while (*s != 0 && !(X)) ++s; }
+		#define SCANWHILE(X)		{ while ((X)) ++s; }
+		#define ENDSEG()			{ ch = *s; *s = 0; ++s; }
+		#define THROW_ERROR(err, m)	error_offset = m, longjmp(error_handler, err)
+		#define CHECK_ERROR(err, m)	{ if (*s == 0) THROW_ERROR(err, m); }
+		
+		xml_parser(const xml_allocator& alloc): alloc(alloc), error_offset(0)
+		{
+		}
+
+		// DOCTYPE consists of nested sections of the following possible types:
+		// <!-- ... -->, <? ... ?>, "...", '...'
+		// <![...]]>
+		// <!...>
+		// First group can not contain nested groups
+		// Second group can contain nested groups of the same type
+		// Third group can contain all other groups
+		char_t* parse_doctype_primitive(char_t* s)
+		{
+			if (*s == '"' || *s == '\'')
+			{
+				// quoted string
+				char_t ch = *s++;
+				SCANFOR(*s == ch);
+				if (!*s) THROW_ERROR(status_bad_doctype, s);
+
+				s++;
+			}
+			else if (s[0] == '<' && s[1] == '?')
+			{
+				// <? ... ?>
+				s += 2;
+				SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype
+				if (!*s) THROW_ERROR(status_bad_doctype, s);
+
+				s += 2;
+			}
+			else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-')
+			{
+				s += 4;
+				SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype
+				if (!*s) THROW_ERROR(status_bad_doctype, s);
+
+				s += 4;
+			}
+			else THROW_ERROR(status_bad_doctype, s);
+
+			return s;
+		}
+
+		char_t* parse_doctype_ignore(char_t* s)
+		{
+			assert(s[0] == '<' && s[1] == '!' && s[2] == '[');
+			s++;
+
+			while (*s)
+			{
+				if (s[0] == '<' && s[1] == '!' && s[2] == '[')
+				{
+					// nested ignore section
+					s = parse_doctype_ignore(s);
+				}
+				else if (s[0] == ']' && s[1] == ']' && s[2] == '>')
+				{
+					// ignore section end
+					s += 3;
+
+					return s;
+				}
+				else s++;
+			}
+
+			THROW_ERROR(status_bad_doctype, s);
+
+			return s;
+		}
+
+		char_t* parse_doctype_group(char_t* s, char_t endch, bool toplevel)
+		{
+			assert(s[0] == '<' && s[1] == '!');
+			s++;
+
+			while (*s)
+			{
+				if (s[0] == '<' && s[1] == '!' && s[2] != '-')
+				{
+					if (s[2] == '[')
+					{
+						// ignore
+						s = parse_doctype_ignore(s);
+					}
+					else
+					{
+						// some control group
+						s = parse_doctype_group(s, endch, false);
+					}
+				}
+				else if (s[0] == '<' || s[0] == '"' || s[0] == '\'')
+				{
+					// unknown tag (forbidden), or some primitive group
+					s = parse_doctype_primitive(s);
+				}
+				else if (*s == '>')
+				{
+					s++;
+
+					return s;
+				}
+				else s++;
+			}
+
+			if (!toplevel || endch != '>') THROW_ERROR(status_bad_doctype, s);
+
+			return s;
+		}
+
+		char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch)
+		{
+			// parse node contents, starting with exclamation mark
+			++s;
+
+			if (*s == '-') // '<!-...'
+			{
+				++s;
+
+				if (*s == '-') // '<!--...'
+				{
+					++s;
+
+					if (OPTSET(parse_comments))
+					{
+						PUSHNODE(node_comment); // Append a new node on the tree.
+						cursor->value = s; // Save the offset.
+					}
+
+					if (OPTSET(parse_eol) && OPTSET(parse_comments))
+					{
+						s = strconv_comment(s, endch);
+
+						if (!s) THROW_ERROR(status_bad_comment, cursor->value);
+					}
+					else
+					{
+						// Scan for terminating '-->'.
+						SCANFOR(s[0] == '-' && s[1] == '-' && ENDSWITH(s[2], '>'));
+						CHECK_ERROR(status_bad_comment, s);
+
+						if (OPTSET(parse_comments))
+							*s = 0; // Zero-terminate this segment at the first terminating '-'.
+
+						s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'.
+					}
+				}
+				else THROW_ERROR(status_bad_comment, s);
+			}
+			else if (*s == '[')
+			{
+				// '<![CDATA[...'
+				if (*++s=='C' && *++s=='D' && *++s=='A' && *++s=='T' && *++s=='A' && *++s == '[')
+				{
+					++s;
+
+					if (OPTSET(parse_cdata))
+					{
+						PUSHNODE(node_cdata); // Append a new node on the tree.
+						cursor->value = s; // Save the offset.
+
+						if (OPTSET(parse_eol))
+						{
+							s = strconv_cdata(s, endch);
+
+							if (!s) THROW_ERROR(status_bad_cdata, cursor->value);
+						}
+						else
+						{
+							// Scan for terminating ']]>'.
+							SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>'));
+							CHECK_ERROR(status_bad_cdata, s);
+
+							*s++ = 0; // Zero-terminate this segment.
+						}
+					}
+					else // Flagged for discard, but we still have to scan for the terminator.
+					{
+						// Scan for terminating ']]>'.
+						SCANFOR(s[0] == ']' && s[1] == ']' && ENDSWITH(s[2], '>'));
+						CHECK_ERROR(status_bad_cdata, s);
+
+						++s;
+					}
+
+					s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'.
+				}
+				else THROW_ERROR(status_bad_cdata, s);
+			}
+			else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && ENDSWITH(s[6], 'E'))
+			{
+				s -= 2;
+
+                if (cursor->parent) THROW_ERROR(status_bad_doctype, s);
+
+                char_t* mark = s + 9;
+
+				s = parse_doctype_group(s, endch, true);
+
+                if (OPTSET(parse_doctype))
+                {
+                    while (IS_CHARTYPE(*mark, ct_space)) ++mark;
+
+                    PUSHNODE(node_doctype);
+
+                    cursor->value = mark;
+
+                    assert((s[0] == 0 && endch == '>') || s[-1] == '>');
+                    s[*s == 0 ? 0 : -1] = 0;
+
+                    POPNODE();
+                }
+			}
+			else if (*s == 0 && endch == '-') THROW_ERROR(status_bad_comment, s);
+			else if (*s == 0 && endch == '[') THROW_ERROR(status_bad_cdata, s);
+			else THROW_ERROR(status_unrecognized_tag, s);
+
+			return s;
+		}
+
+		char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch)
+		{
+			// load into registers
+			xml_node_struct* cursor = ref_cursor;
+			char_t ch = 0;
+
+			// parse node contents, starting with question mark
+			++s;
+
+			// read PI target
+			char_t* target = s;
+
+			if (!IS_CHARTYPE(*s, ct_start_symbol)) THROW_ERROR(status_bad_pi, s);
+
+			SCANWHILE(IS_CHARTYPE(*s, ct_symbol));
+			CHECK_ERROR(status_bad_pi, s);
+
+			// determine node type; stricmp / strcasecmp is not portable
+			bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s;
+
+			if (declaration ? OPTSET(parse_declaration) : OPTSET(parse_pi))
+			{
+				if (declaration)
+				{
+					// disallow non top-level declarations
+					if (cursor->parent) THROW_ERROR(status_bad_pi, s);
+
+					PUSHNODE(node_declaration);
+				}
+				else
+				{
+					PUSHNODE(node_pi);
+				}
+
+				cursor->name = target;
+
+				ENDSEG();
+
+				// parse value/attributes
+				if (ch == '?')
+				{
+					// empty node
+					if (!ENDSWITH(*s, '>')) THROW_ERROR(status_bad_pi, s);
+					s += (*s == '>');
+
+					POPNODE();
+				}
+				else if (IS_CHARTYPE(ch, ct_space))
+				{
+					SKIPWS();
+
+					// scan for tag end
+					char_t* value = s;
+
+					SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>'));
+					CHECK_ERROR(status_bad_pi, s);
+
+					if (declaration)
+					{
+						// replace ending ? with / so that 'element' terminates properly
+						*s = '/';
+
+						// we exit from this function with cursor at node_declaration, which is a signal to parse() to go to LOC_ATTRIBUTES
+						s = value;
+					}
+					else
+					{
+						// store value and step over >
+						cursor->value = value;
+						POPNODE();
+
+						ENDSEG();
+
+						s += (*s == '>');
+					}
+				}
+				else THROW_ERROR(status_bad_pi, s);
+			}
+			else
+			{
+				// scan for tag end
+				SCANFOR(s[0] == '?' && ENDSWITH(s[1], '>'));
+				CHECK_ERROR(status_bad_pi, s);
+
+				s += (s[1] == '>' ? 2 : 1);
+			}
+
+			// store from registers
+			ref_cursor = cursor;
+
+			return s;
+		}
+
+		void parse(char_t* s, xml_node_struct* xmldoc, unsigned int optmsk, char_t endch)
+		{
+			strconv_attribute_t strconv_attribute = get_strconv_attribute(optmsk);
+			strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk);
+			
+			char_t ch = 0;
+			xml_node_struct* cursor = xmldoc;
+			char_t* mark = s;
+
+			while (*s != 0)
+			{
+				if (*s == '<')
+				{
+					++s;
+
+				LOC_TAG:
+					if (IS_CHARTYPE(*s, ct_start_symbol)) // '<#...'
+					{
+						PUSHNODE(node_element); // Append a new node to the tree.
+
+						cursor->name = s;
+
+						SCANWHILE(IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator.
+						ENDSEG(); // Save char in 'ch', terminate & step over.
+
+						if (ch == '>')
+						{
+							// end of tag
+						}
+						else if (IS_CHARTYPE(ch, ct_space))
+						{
+						LOC_ATTRIBUTES:
+						    while (true)
+						    {
+								SKIPWS(); // Eat any whitespace.
+						
+								if (IS_CHARTYPE(*s, ct_start_symbol)) // <... #...
+								{
+									xml_attribute_struct* a = append_attribute_ll(cursor, alloc); // Make space for this attribute.
+									if (!a) THROW_ERROR(status_out_of_memory, s);
+
+									a->name = s; // Save the offset.
+
+									SCANWHILE(IS_CHARTYPE(*s, ct_symbol)); // Scan for a terminator.
+									CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance
+
+									ENDSEG(); // Save char in 'ch', terminate & step over.
+									CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance
+
+									if (IS_CHARTYPE(ch, ct_space))
+									{
+										SKIPWS(); // Eat any whitespace.
+										CHECK_ERROR(status_bad_attribute, s); //$ redundant, left for performance
+
+										ch = *s;
+										++s;
+									}
+									
+									if (ch == '=') // '<... #=...'
+									{
+										SKIPWS(); // Eat any whitespace.
+
+										if (*s == '"' || *s == '\'') // '<... #="...'
+										{
+											ch = *s; // Save quote char to avoid breaking on "''" -or- '""'.
+											++s; // Step over the quote.
+											a->value = s; // Save the offset.
+
+											s = strconv_attribute(s, ch);
+										
+											if (!s) THROW_ERROR(status_bad_attribute, a->value);
+
+											// After this line the loop continues from the start;
+											// Whitespaces, / and > are ok, symbols and EOF are wrong,
+											// everything else will be detected
+											if (IS_CHARTYPE(*s, ct_start_symbol)) THROW_ERROR(status_bad_attribute, s);
+										}
+										else THROW_ERROR(status_bad_attribute, s);
+									}
+									else THROW_ERROR(status_bad_attribute, s);
+								}
+								else if (*s == '/')
+								{
+									++s;
+									
+									if (*s == '>')
+									{
+										POPNODE();
+										s++;
+										break;
+									}
+									else if (*s == 0 && endch == '>')
+									{
+										POPNODE();
+										break;
+									}
+									else THROW_ERROR(status_bad_start_element, s);
+								}
+								else if (*s == '>')
+								{
+									++s;
+
+									break;
+								}
+								else if (*s == 0 && endch == '>')
+								{
+									break;
+								}
+								else THROW_ERROR(status_bad_start_element, s);
+							}
+
+							// !!!
+						}
+						else if (ch == '/') // '<#.../'
+						{
+							if (!ENDSWITH(*s, '>')) THROW_ERROR(status_bad_start_element, s);
+
+							POPNODE(); // Pop.
+
+							s += (*s == '>');
+						}
+						else if (ch == 0)
+						{
+							// we stepped over null terminator, backtrack & handle closing tag
+							--s;
+							
+							if (endch != '>') THROW_ERROR(status_bad_start_element, s);
+						}
+						else THROW_ERROR(status_bad_start_element, s);
+					}
+					else if (*s == '/')
+					{
+						++s;
+
+						char_t* name = cursor->name;
+						if (!name) THROW_ERROR(status_end_element_mismatch, s);
+						
+						while (IS_CHARTYPE(*s, ct_symbol))
+						{
+							if (*s++ != *name++) THROW_ERROR(status_end_element_mismatch, s);
+						}
+
+						if (*name)
+						{
+							if (*s == 0 && name[0] == endch && name[1] == 0) THROW_ERROR(status_bad_end_element, s);
+							else THROW_ERROR(status_end_element_mismatch, s);
+						}
+							
+						POPNODE(); // Pop.
+
+						SKIPWS();
+
+						if (*s == 0)
+						{
+							if (endch != '>') THROW_ERROR(status_bad_end_element, s);
+						}
+						else
+						{
+							if (*s != '>') THROW_ERROR(status_bad_end_element, s);
+							++s;
+						}
+					}
+					else if (*s == '?') // '<?...'
+					{
+						s = parse_question(s, cursor, optmsk, endch);
+
+						assert(cursor);
+						if ((cursor->header & xml_memory_page_type_mask) + 1 == node_declaration) goto LOC_ATTRIBUTES;
+					}
+					else if (*s == '!') // '<!...'
+					{
+						s = parse_exclamation(s, cursor, optmsk, endch);
+					}
+					else if (*s == 0 && endch == '?') THROW_ERROR(status_bad_pi, s);
+					else THROW_ERROR(status_unrecognized_tag, s);
+				}
+				else
+				{
+					mark = s; // Save this offset while searching for a terminator.
+
+					SKIPWS(); // Eat whitespace if no genuine PCDATA here.
+
+					if ((!OPTSET(parse_ws_pcdata) || mark == s) && (*s == '<' || !*s))
+					{
+						continue;
+					}
+
+					s = mark;
+							
+					if (cursor->parent)
+					{
+						PUSHNODE(node_pcdata); // Append a new node on the tree.
+						cursor->value = s; // Save the offset.
+
+						s = strconv_pcdata(s);
+								
+						POPNODE(); // Pop since this is a standalone.
+						
+						if (!*s) break;
+					}
+					else
+					{
+						SCANFOR(*s == '<'); // '...<'
+						if (!*s) break;
+						
+						++s;
+					}
+
+					// We're after '<'
+					goto LOC_TAG;
+				}
+			}
+
+			// check that last tag is closed
+			if (cursor != xmldoc) THROW_ERROR(status_end_element_mismatch, s);
+		}
+
+		static xml_parse_result parse(char_t* buffer, size_t length, xml_node_struct* root, unsigned int optmsk)
+		{
+			xml_document_struct* xmldoc = static_cast<xml_document_struct*>(root);
+
+			// store buffer for offset_debug
+			xmldoc->buffer = buffer;
+
+			// early-out for empty documents
+			if (length == 0) return make_parse_result(status_ok);
+
+			// create parser on stack
+			xml_parser parser(*xmldoc);
+
+			// save last character and make buffer zero-terminated (speeds up parsing)
+			char_t endch = buffer[length - 1];
+			buffer[length - 1] = 0;
+			
+			// perform actual parsing
+			int error = setjmp(parser.error_handler);
+
+			if (error == 0)
+			{
+				parser.parse(buffer, xmldoc, optmsk, endch);
+			}
+
+			xml_parse_result result = make_parse_result(static_cast<xml_parse_status>(error), parser.error_offset ? parser.error_offset - buffer : 0);
+			assert(result.offset >= 0 && static_cast<size_t>(result.offset) <= length);
+
+			// update allocator state
+			*static_cast<xml_allocator*>(xmldoc) = parser.alloc;
+
+			// since we removed last character, we have to handle the only possible false positive
+			if (result && endch == '<')
+			{
+				// there's no possible well-formed document with < at the end
+				return make_parse_result(status_unrecognized_tag, length);
+			}
+
+			return result;
+		}
+	};
+
+	// Output facilities
+	xml_encoding get_write_native_encoding()
+	{
+	#ifdef PUGIXML_WCHAR_MODE
+		return get_wchar_encoding();
+	#else
+		return encoding_utf8;
+	#endif
+	}
+
+	xml_encoding get_write_encoding(xml_encoding encoding)
+	{
+		// replace wchar encoding with utf implementation
+		if (encoding == encoding_wchar) return get_wchar_encoding();
+
+		// replace utf16 encoding with utf16 with specific endianness
+		if (encoding == encoding_utf16) return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+		// replace utf32 encoding with utf32 with specific endianness
+		if (encoding == encoding_utf32) return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+		// only do autodetection if no explicit encoding is requested
+		if (encoding != encoding_auto) return encoding;
+
+		// assume utf8 encoding
+		return encoding_utf8;
+	}
+
+#ifdef PUGIXML_WCHAR_MODE
+	size_t get_valid_length(const char_t* data, size_t length)
+	{
+		assert(length > 0);
+
+		// discard last character if it's the lead of a surrogate pair 
+		return (sizeof(wchar_t) == 2 && (unsigned)(static_cast<uint16_t>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length;
+	}
+
+	size_t convert_buffer(char* result, const char_t* data, size_t length, xml_encoding encoding)
+	{
+		// only endian-swapping is required
+		if (need_endian_swap_utf(encoding, get_wchar_encoding()))
+		{
+			convert_wchar_endian_swap(reinterpret_cast<char_t*>(result), data, length);
+
+			return length * sizeof(char_t);
+		}
+	
+		// convert to utf8
+		if (encoding == encoding_utf8)
+		{
+			uint8_t* dest = reinterpret_cast<uint8_t*>(result);
+
+			uint8_t* end = sizeof(wchar_t) == 2 ?
+				utf_decoder<utf8_writer>::decode_utf16_block(reinterpret_cast<const uint16_t*>(data), length, dest) :
+				utf_decoder<utf8_writer>::decode_utf32_block(reinterpret_cast<const uint32_t*>(data), length, dest);
+
+			return static_cast<size_t>(end - dest);
+		}
+
+		// convert to utf16
+		if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
+		{
+			uint16_t* dest = reinterpret_cast<uint16_t*>(result);
+
+			// convert to native utf16
+			uint16_t* end = utf_decoder<utf16_writer>::decode_utf32_block(reinterpret_cast<const uint32_t*>(data), length, dest);
+
+			// swap if necessary
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+			if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast<size_t>(end - dest));
+
+			return static_cast<size_t>(end - dest) * sizeof(uint16_t);
+		}
+
+		// convert to utf32
+		if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
+		{
+			uint32_t* dest = reinterpret_cast<uint32_t*>(result);
+
+			// convert to native utf32
+			uint32_t* end = utf_decoder<utf32_writer>::decode_utf16_block(reinterpret_cast<const uint16_t*>(data), length, dest);
+
+			// swap if necessary
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+			if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast<size_t>(end - dest));
+
+			return static_cast<size_t>(end - dest) * sizeof(uint32_t);
+		}
+
+		assert(!"Invalid encoding");
+		return 0;
+	}
+#else
+	size_t get_valid_length(const char_t* data, size_t length)
+	{
+		assert(length > 4);
+
+		for (size_t i = 1; i <= 4; ++i)
+		{
+			uint8_t ch = static_cast<uint8_t>(data[length - i]);
+
+			// either a standalone character or a leading one
+			if ((ch & 0xc0) != 0x80) return length - i;
+		}
+
+		// there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk
+		return length;
+	}
+
+	size_t convert_buffer(char* result, const char_t* data, size_t length, xml_encoding encoding)
+	{
+		if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
+		{
+			uint16_t* dest = reinterpret_cast<uint16_t*>(result);
+
+			// convert to native utf16
+			uint16_t* end = utf_decoder<utf16_writer>::decode_utf8_block(reinterpret_cast<const uint8_t*>(data), length, dest);
+
+			// swap if necessary
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
+
+			if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast<size_t>(end - dest));
+
+			return static_cast<size_t>(end - dest) * sizeof(uint16_t);
+		}
+
+		if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
+		{
+			uint32_t* dest = reinterpret_cast<uint32_t*>(result);
+
+			// convert to native utf32
+			uint32_t* end = utf_decoder<utf32_writer>::decode_utf8_block(reinterpret_cast<const uint8_t*>(data), length, dest);
+
+			// swap if necessary
+			xml_encoding native_encoding = is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
+
+			if (native_encoding != encoding) convert_utf_endian_swap(dest, dest, static_cast<size_t>(end - dest));
+
+			return static_cast<size_t>(end - dest) * sizeof(uint32_t);
+		}
+
+		assert(!"Invalid encoding");
+		return 0;
+	}
+#endif
+
+	class xml_buffered_writer
+	{
+		xml_buffered_writer(const xml_buffered_writer&);
+		xml_buffered_writer& operator=(const xml_buffered_writer&);
+
+	public:
+		xml_buffered_writer(xml_writer& writer, xml_encoding user_encoding): writer(writer), bufsize(0), encoding(get_write_encoding(user_encoding))
+		{
+		}
+
+		~xml_buffered_writer()
+		{
+			flush();
+		}
+
+		void flush()
+		{
+			flush(buffer, bufsize);
+			bufsize = 0;
+		}
+
+		void flush(const char_t* data, size_t size)
+		{
+			if (size == 0) return;
+
+			// fast path, just write data
+			if (encoding == get_write_native_encoding())
+				writer.write(data, size * sizeof(char_t));
+			else
+			{
+				// convert chunk
+				size_t result = convert_buffer(scratch, data, size, encoding);
+				assert(result <= sizeof(scratch));
+
+				// write data
+				writer.write(scratch, result);
+			}
+		}
+
+		void write(const char_t* data, size_t length)
+		{
+			if (bufsize + length > bufcapacity)
+			{
+				// flush the remaining buffer contents
+				flush();
+
+				// handle large chunks
+				if (length > bufcapacity)
+				{
+					if (encoding == get_write_native_encoding())
+					{
+						// fast path, can just write data chunk
+						writer.write(data, length * sizeof(char_t));
+						return;
+					}
+
+					// need to convert in suitable chunks
+					while (length > bufcapacity)
+					{
+						// get chunk size by selecting such number of characters that are guaranteed to fit into scratch buffer
+						// and form a complete codepoint sequence (i.e. discard start of last codepoint if necessary)
+						size_t chunk_size = get_valid_length(data, bufcapacity);
+
+						// convert chunk and write
+						flush(data, chunk_size);
+
+						// iterate
+						data += chunk_size;
+						length -= chunk_size;
+					}
+
+					// small tail is copied below
+					bufsize = 0;
+				}
+			}
+
+			memcpy(buffer + bufsize, data, length * sizeof(char_t));
+			bufsize += length;
+		}
+
+		void write(const char_t* data)
+		{
+			write(data, strlength(data));
+		}
+
+		void write(char_t d0)
+		{
+			if (bufsize + 1 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			bufsize += 1;
+		}
+
+		void write(char_t d0, char_t d1)
+		{
+			if (bufsize + 2 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			buffer[bufsize + 1] = d1;
+			bufsize += 2;
+		}
+
+		void write(char_t d0, char_t d1, char_t d2)
+		{
+			if (bufsize + 3 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			buffer[bufsize + 1] = d1;
+			buffer[bufsize + 2] = d2;
+			bufsize += 3;
+		}
+
+		void write(char_t d0, char_t d1, char_t d2, char_t d3)
+		{
+			if (bufsize + 4 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			buffer[bufsize + 1] = d1;
+			buffer[bufsize + 2] = d2;
+			buffer[bufsize + 3] = d3;
+			bufsize += 4;
+		}
+
+		void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
+		{
+			if (bufsize + 5 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			buffer[bufsize + 1] = d1;
+			buffer[bufsize + 2] = d2;
+			buffer[bufsize + 3] = d3;
+			buffer[bufsize + 4] = d4;
+			bufsize += 5;
+		}
+
+		void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
+		{
+			if (bufsize + 6 > bufcapacity) flush();
+
+			buffer[bufsize + 0] = d0;
+			buffer[bufsize + 1] = d1;
+			buffer[bufsize + 2] = d2;
+			buffer[bufsize + 3] = d3;
+			buffer[bufsize + 4] = d4;
+			buffer[bufsize + 5] = d5;
+			bufsize += 6;
+		}
+
+		// utf8 maximum expansion: x4 (-> utf32)
+		// utf16 maximum expansion: x2 (-> utf32)
+		// utf32 maximum expansion: x1
+		enum { bufcapacity = 2048 };
+
+		char_t buffer[bufcapacity];
+		char scratch[4 * bufcapacity];
+
+		xml_writer& writer;
+		size_t bufsize;
+		xml_encoding encoding;
+	};
+
+	void write_bom(xml_writer& writer, xml_encoding encoding)
+	{
+		switch (encoding)
+		{
+		case encoding_utf8:
+			writer.write("\xef\xbb\xbf", 3);
+			break;
+
+		case encoding_utf16_be:
+			writer.write("\xfe\xff", 2);
+			break;
+
+		case encoding_utf16_le:
+			writer.write("\xff\xfe", 2);
+			break;
+
+		case encoding_utf32_be:
+			writer.write("\x00\x00\xfe\xff", 4);
+			break;
+
+		case encoding_utf32_le:
+			writer.write("\xff\xfe\x00\x00", 4);
+			break;
+
+		default:
+			assert(!"Invalid encoding");
+		}
+	}
+
+	void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type)
+	{
+		while (*s)
+		{
+			const char_t* prev = s;
+			
+			// While *s is a usual symbol
+			while (!IS_CHARTYPEX(*s, type)) ++s;
+		
+			writer.write(prev, static_cast<size_t>(s - prev));
+
+			switch (*s)
+			{
+				case 0: break;
+				case '&':
+					writer.write('&', 'a', 'm', 'p', ';');
+					++s;
+					break;
+				case '<':
+					writer.write('&', 'l', 't', ';');
+					++s;
+					break;
+				case '>':
+					writer.write('&', 'g', 't', ';');
+					++s;
+					break;
+				case '"':
+					writer.write('&', 'q', 'u', 'o', 't', ';');
+					++s;
+					break;
+				default: // s is not a usual symbol
+				{
+					unsigned int ch = static_cast<unsigned int>(*s++);
+					assert(ch < 32);
+
+					writer.write('&', '#', static_cast<char_t>((ch / 10) + '0'), static_cast<char_t>((ch % 10) + '0'), ';');
+				}
+			}
+		}
+	}
+
+	void text_output_cdata(xml_buffered_writer& writer, const char_t* s)
+	{
+		do
+		{
+			writer.write('<', '!', '[', 'C', 'D');
+			writer.write('A', 'T', 'A', '[');
+
+			const char_t* prev = s;
+
+			// look for ]]> sequence - we can't output it as is since it terminates CDATA
+			while (*s && !(s[0] == ']' && s[1] == ']' && s[2] == '>')) ++s;
+
+			// skip ]] if we stopped at ]]>, > will go to the next CDATA section
+			if (*s) s += 2;
+
+			writer.write(prev, static_cast<size_t>(s - prev));
+
+			writer.write(']', ']', '>');
+		}
+		while (*s);
+	}
+
+	void node_output_attributes(xml_buffered_writer& writer, const xml_node& node)
+	{
+		const char_t* default_name = PUGIXML_TEXT(":anonymous");
+
+		for (xml_attribute a = node.first_attribute(); a; a = a.next_attribute())
+		{
+			writer.write(' ');
+			writer.write(a.name()[0] ? a.name() : default_name);
+			writer.write('=', '"');
+
+			text_output_escaped(writer, a.value(), ctx_special_attr);
+
+			writer.write('"');
+		}
+	}
+
+	void node_output(xml_buffered_writer& writer, const xml_node& node, const char_t* indent, unsigned int flags, unsigned int depth)
+	{
+		const char_t* default_name = PUGIXML_TEXT(":anonymous");
+
+		if ((flags & format_indent) != 0 && (flags & format_raw) == 0)
+			for (unsigned int i = 0; i < depth; ++i) writer.write(indent);
+
+		switch (node.type())
+		{
+		case node_document:
+		{
+			for (xml_node n = node.first_child(); n; n = n.next_sibling())
+				node_output(writer, n, indent, flags, depth);
+			break;
+		}
+			
+		case node_element:
+		{
+			const char_t* name = node.name()[0] ? node.name() : default_name;
+
+			writer.write('<');
+			writer.write(name);
+
+			node_output_attributes(writer, node);
+
+			if (flags & format_raw)
+			{
+				if (!node.first_child())
+					writer.write(' ', '/', '>');
+				else
+				{
+					writer.write('>');
+
+					for (xml_node n = node.first_child(); n; n = n.next_sibling())
+						node_output(writer, n, indent, flags, depth + 1);
+
+					writer.write('<', '/');
+					writer.write(name);
+					writer.write('>');
+				}
+			}
+			else if (!node.first_child())
+				writer.write(' ', '/', '>', '\n');
+			else if (node.first_child() == node.last_child() && (node.first_child().type() == node_pcdata || node.first_child().type() == node_cdata))
+			{
+				writer.write('>');
+
+                if (node.first_child().type() == node_pcdata)
+                    text_output_escaped(writer, node.first_child().value(), ctx_special_pcdata);
+                else
+                    text_output_cdata(writer, node.first_child().value());
+
+				writer.write('<', '/');
+				writer.write(name);
+				writer.write('>', '\n');
+			}
+			else
+			{
+				writer.write('>', '\n');
+				
+				for (xml_node n = node.first_child(); n; n = n.next_sibling())
+					node_output(writer, n, indent, flags, depth + 1);
+
+				if ((flags & format_indent) != 0 && (flags & format_raw) == 0)
+					for (unsigned int i = 0; i < depth; ++i) writer.write(indent);
+				
+				writer.write('<', '/');
+				writer.write(name);
+				writer.write('>', '\n');
+			}
+
+			break;
+		}
+		
+		case node_pcdata:
+			text_output_escaped(writer, node.value(), ctx_special_pcdata);
+			if ((flags & format_raw) == 0) writer.write('\n');
+			break;
+
+		case node_cdata:
+			text_output_cdata(writer, node.value());
+			if ((flags & format_raw) == 0) writer.write('\n');
+			break;
+
+		case node_comment:
+			writer.write('<', '!', '-', '-');
+			writer.write(node.value());
+			writer.write('-', '-', '>');
+			if ((flags & format_raw) == 0) writer.write('\n');
+			break;
+
+		case node_pi:
+		case node_declaration:
+			writer.write('<', '?');
+			writer.write(node.name()[0] ? node.name() : default_name);
+
+			if (node.type() == node_declaration)
+			{
+				node_output_attributes(writer, node);
+			}
+			else if (node.value()[0])
+			{
+				writer.write(' ');
+				writer.write(node.value());
+			}
+
+			writer.write('?', '>');
+			if ((flags & format_raw) == 0) writer.write('\n');
+			break;
+
+		case node_doctype:
+			writer.write('<', '!', 'D', 'O', 'C');
+			writer.write('T', 'Y', 'P', 'E');
+
+            if (node.value()[0])
+            {
+                writer.write(' ');
+                writer.write(node.value());
+            }
+
+            writer.write('>');
+			if ((flags & format_raw) == 0) writer.write('\n');
+			break;
+
+		default:
+			assert(!"Invalid node type");
+		}
+	}
+
+	inline bool has_declaration(const xml_node& node)
+	{
+		for (xml_node child = node.first_child(); child; child = child.next_sibling())
+		{
+			xml_node_type type = child.type();
+
+			if (type == node_declaration) return true;
+			if (type == node_element) return false;
+		}
+
+		return false;
+	}
+
+	inline bool allow_insert_child(xml_node_type parent, xml_node_type child)
+	{
+		if (parent != node_document && parent != node_element) return false;
+		if (child == node_document || child == node_null) return false;
+		if (parent != node_document && (child == node_declaration || child == node_doctype)) return false;
+
+		return true;
+	}
+
+	void recursive_copy_skip(xml_node& dest, const xml_node& source, const xml_node& skip)
+	{
+		assert(dest.type() == source.type());
+
+		switch (source.type())
+		{
+		case node_element:
+		{
+			dest.set_name(source.name());
+
+			for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute())
+				dest.append_attribute(a.name()).set_value(a.value());
+
+			for (xml_node c = source.first_child(); c; c = c.next_sibling())
+			{
+				if (c == skip) continue;
+
+				xml_node cc = dest.append_child(c.type());
+				assert(cc);
+
+				recursive_copy_skip(cc, c, skip);
+			}
+
+			break;
+		}
+
+		case node_pcdata:
+		case node_cdata:
+		case node_comment:
+        case node_doctype:
+			dest.set_value(source.value());
+			break;
+
+		case node_pi:
+			dest.set_name(source.name());
+			dest.set_value(source.value());
+			break;
+
+		case node_declaration:
+		{
+			dest.set_name(source.name());
+
+			for (xml_attribute a = source.first_attribute(); a; a = a.next_attribute())
+				dest.append_attribute(a.name()).set_value(a.value());
+
+			break;
+		}
+
+		default:
+			assert(!"Invalid node type");
+		}
+	}
+
+	// we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick
+	xml_parse_status get_file_size(FILE* file, size_t& out_result)
+	{
+	#if defined(_MSC_VER) && _MSC_VER >= 1400
+		// there are 64-bit versions of fseek/ftell, let's use them
+		typedef __int64 length_type;
+
+		_fseeki64(file, 0, SEEK_END);
+		length_type length = _ftelli64(file);
+		_fseeki64(file, 0, SEEK_SET);
+	#elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && !defined(__STRICT_ANSI__)
+		// there are 64-bit versions of fseek/ftell, let's use them
+		typedef off64_t length_type;
+
+		fseeko64(file, 0, SEEK_END);
+		length_type length = ftello64(file);
+		fseeko64(file, 0, SEEK_SET);
+	#else
+		// if this is a 32-bit OS, long is enough; if this is a unix system, long is 64-bit, which is enough; otherwise we can't do anything anyway.
+		typedef long length_type;
+
+		fseek(file, 0, SEEK_END);
+		length_type length = ftell(file);
+		fseek(file, 0, SEEK_SET);
+	#endif
+
+		// check for I/O errors
+		if (length < 0) return status_io_error;
+		
+		// check for overflow
+		size_t result = static_cast<size_t>(length);
+
+		if (static_cast<length_type>(result) != length) return status_out_of_memory;
+
+		// finalize
+		out_result = result;
+
+		return status_ok;
+	}
+
+	xml_parse_result load_file_impl(xml_document& doc, FILE* file, unsigned int options, xml_encoding encoding)
+	{
+		if (!file) return make_parse_result(status_file_not_found);
+
+		// get file size (can result in I/O errors)
+		size_t size = 0;
+		xml_parse_status size_status = get_file_size(file, size);
+
+		if (size_status != status_ok)
+		{
+			fclose(file);
+			return make_parse_result(size_status);
+		}
+		
+		// allocate buffer for the whole file
+		char* contents = static_cast<char*>(global_allocate(size > 0 ? size : 1));
+
+		if (!contents)
+		{
+			fclose(file);
+			return make_parse_result(status_out_of_memory);
+		}
+
+		// read file in memory
+		size_t read_size = fread(contents, 1, size, file);
+		fclose(file);
+
+		if (read_size != size)
+		{
+			global_deallocate(contents);
+			return make_parse_result(status_io_error);
+		}
+		
+		return doc.load_buffer_inplace_own(contents, size, options, encoding);
+	}
+
+#ifndef PUGIXML_NO_STL
+	template <typename T> xml_parse_result load_stream_impl(xml_document& doc, std::basic_istream<T>& stream, unsigned int options, xml_encoding encoding)
+	{
+		// get length of remaining data in stream
+		typename std::basic_istream<T>::pos_type pos = stream.tellg();
+		stream.seekg(0, std::ios::end);
+		std::streamoff length = stream.tellg() - pos;
+		stream.seekg(pos);
+
+		if (stream.fail() || pos < 0) return make_parse_result(status_io_error);
+
+		// guard against huge files
+		size_t read_length = static_cast<size_t>(length);
+
+		if (static_cast<std::streamsize>(read_length) != length || length < 0) return make_parse_result(status_out_of_memory);
+
+		// read stream data into memory (guard against stream exceptions with buffer holder)
+		buffer_holder buffer(global_allocate((read_length > 0 ? read_length : 1) * sizeof(T)), global_deallocate);
+		if (!buffer.data) return make_parse_result(status_out_of_memory);
+
+		stream.read(static_cast<T*>(buffer.data), static_cast<std::streamsize>(read_length));
+
+		// read may set failbit | eofbit in case gcount() is less than read_length (i.e. line ending conversion), so check for other I/O errors
+		if (stream.bad()) return make_parse_result(status_io_error);
+
+		// load data from buffer
+		size_t actual_length = static_cast<size_t>(stream.gcount());
+		assert(actual_length <= read_length);
+
+		return doc.load_buffer_inplace_own(buffer.release(), actual_length * sizeof(T), options, encoding);
+	}
+#endif
+
+#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__)
+	FILE* open_file_wide(const wchar_t* path, const wchar_t* mode)
+	{
+		return _wfopen(path, mode);
+	}
+#else
+	char* convert_path_heap(const wchar_t* str)
+	{
+		assert(str);
+
+		// first pass: get length in utf8 characters
+		size_t length = wcslen(str);
+        size_t size = as_utf8_begin(str, length);
+
+		// allocate resulting string
+		char* result = static_cast<char*>(global_allocate(size + 1));
+		if (!result) return 0;
+
+		// second pass: convert to utf8
+        as_utf8_end(result, size, str, length);
+
+	  	return result;
+	}
+
+	FILE* open_file_wide(const wchar_t* path, const wchar_t* mode)
+	{
+		// there is no standard function to open wide paths, so our best bet is to try utf8 path
+		char* path_utf8 = convert_path_heap(path);
+		if (!path_utf8) return 0;
+
+		// convert mode to ASCII (we mirror _wfopen interface)
+		char mode_ascii[4] = {0};
+		for (size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast<char>(mode[i]);
+
+		// try to open the utf8 path
+		FILE* result = fopen(path_utf8, mode_ascii);
+
+		// free dummy buffer
+		global_deallocate(path_utf8);
+
+		return result;
+	}
+#endif
+}
+
+namespace pugi
+{
+	xml_writer_file::xml_writer_file(void* file): file(file)
+	{
+	}
+
+	void xml_writer_file::write(const void* data, size_t size)
+	{
+		fwrite(data, size, 1, static_cast<FILE*>(file));
+	}
+
+#ifndef PUGIXML_NO_STL
+	xml_writer_stream::xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream): narrow_stream(&stream), wide_stream(0)
+	{
+	}
+
+	xml_writer_stream::xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream): narrow_stream(0), wide_stream(&stream)
+	{
+	}
+
+	void xml_writer_stream::write(const void* data, size_t size)
+	{
+		if (narrow_stream)
+		{
+			assert(!wide_stream);
+			narrow_stream->write(reinterpret_cast<const char*>(data), static_cast<std::streamsize>(size));
+		}
+		else
+		{
+			assert(wide_stream);
+			assert(size % sizeof(wchar_t) == 0);
+
+			wide_stream->write(reinterpret_cast<const wchar_t*>(data), static_cast<std::streamsize>(size / sizeof(wchar_t)));
+		}
+	}
+#endif
+
+	xml_tree_walker::xml_tree_walker(): _depth(0)
+	{
+	}
+	
+	xml_tree_walker::~xml_tree_walker()
+	{
+	}
+
+	int xml_tree_walker::depth() const
+	{
+		return _depth;
+	}
+
+	bool xml_tree_walker::begin(xml_node&)
+	{
+		return true;
+	}
+
+	bool xml_tree_walker::end(xml_node&)
+	{
+		return true;
+	}
+
+	xml_attribute::xml_attribute(): _attr(0)
+	{
+	}
+
+	xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr)
+	{
+	}
+
+	xml_attribute::operator xml_attribute::unspecified_bool_type() const
+	{
+      	return _attr ? &xml_attribute::_attr : 0;
+   	}
+
+   	bool xml_attribute::operator!() const
+   	{
+   		return !_attr;
+   	}
+
+	bool xml_attribute::operator==(const xml_attribute& r) const
+	{
+		return (_attr == r._attr);
+	}
+	
+	bool xml_attribute::operator!=(const xml_attribute& r) const
+	{
+		return (_attr != r._attr);
+	}
+
+	bool xml_attribute::operator<(const xml_attribute& r) const
+	{
+		return (_attr < r._attr);
+	}
+	
+	bool xml_attribute::operator>(const xml_attribute& r) const
+	{
+		return (_attr > r._attr);
+	}
+	
+	bool xml_attribute::operator<=(const xml_attribute& r) const
+	{
+		return (_attr <= r._attr);
+	}
+	
+	bool xml_attribute::operator>=(const xml_attribute& r) const
+	{
+		return (_attr >= r._attr);
+	}
+
+   	xml_attribute xml_attribute::next_attribute() const
+   	{
+    	return _attr ? xml_attribute(_attr->next_attribute) : xml_attribute();
+   	}
+
+    xml_attribute xml_attribute::previous_attribute() const
+    {
+    	return _attr && _attr->prev_attribute_c->next_attribute ? xml_attribute(_attr->prev_attribute_c) : xml_attribute();
+    }
+
+	int xml_attribute::as_int() const
+	{
+		if (!_attr || !_attr->value) return 0;
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return (int)wcstol(_attr->value, 0, 10);
+	#else
+		return (int)strtol(_attr->value, 0, 10);
+	#endif
+	}
+
+	unsigned int xml_attribute::as_uint() const
+	{
+		if (!_attr || !_attr->value) return 0;
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return (unsigned int)wcstoul(_attr->value, 0, 10);
+	#else
+		return (unsigned int)strtoul(_attr->value, 0, 10);
+	#endif
+	}
+
+	double xml_attribute::as_double() const
+	{
+		if (!_attr || !_attr->value) return 0;
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return wcstod(_attr->value, 0);
+	#else
+		return strtod(_attr->value, 0);
+	#endif
+	}
+
+	float xml_attribute::as_float() const
+	{
+		if (!_attr || !_attr->value) return 0;
+
+	#ifdef PUGIXML_WCHAR_MODE
+		return (float)wcstod(_attr->value, 0);
+	#else
+		return (float)strtod(_attr->value, 0);
+	#endif
+	}
+
+	bool xml_attribute::as_bool() const
+	{
+		if (!_attr || !_attr->value) return false;
+
+		// only look at first char
+		char_t first = *_attr->value;
+
+		// 1*, t* (true), T* (True), y* (yes), Y* (YES)
+		return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y');
+	}
+
+	bool xml_attribute::empty() const
+	{
+		return !_attr;
+	}
+
+	const char_t* xml_attribute::name() const
+	{
+		return (_attr && _attr->name) ? _attr->name : PUGIXML_TEXT("");
+	}
+
+	const char_t* xml_attribute::value() const
+	{
+		return (_attr && _attr->value) ? _attr->value : PUGIXML_TEXT("");
+	}
+
+    size_t xml_attribute::hash_value() const
+    {
+        return static_cast<size_t>(reinterpret_cast<uintptr_t>(_attr) / sizeof(xml_attribute_struct));
+    }
+
+	xml_attribute_struct* xml_attribute::internal_object() const
+	{
+        return _attr;
+	}
+
+	xml_attribute& xml_attribute::operator=(const char_t* rhs)
+	{
+		set_value(rhs);
+		return *this;
+	}
+	
+	xml_attribute& xml_attribute::operator=(int rhs)
+	{
+		set_value(rhs);
+		return *this;
+	}
+
+	xml_attribute& xml_attribute::operator=(unsigned int rhs)
+	{
+		set_value(rhs);
+		return *this;
+	}
+
+	xml_attribute& xml_attribute::operator=(double rhs)
+	{
+		set_value(rhs);
+		return *this;
+	}
+	
+	xml_attribute& xml_attribute::operator=(bool rhs)
+	{
+		set_value(rhs);
+		return *this;
+	}
+
+	bool xml_attribute::set_name(const char_t* rhs)
+	{
+		if (!_attr) return false;
+		
+		return strcpy_insitu(_attr->name, _attr->header, xml_memory_page_name_allocated_mask, rhs);
+	}
+		
+	bool xml_attribute::set_value(const char_t* rhs)
+	{
+		if (!_attr) return false;
+
+		return strcpy_insitu(_attr->value, _attr->header, xml_memory_page_value_allocated_mask, rhs);
+	}
+
+	bool xml_attribute::set_value(int rhs)
+	{
+		char buf[128];
+		sprintf(buf, "%d", rhs);
+	
+	#ifdef PUGIXML_WCHAR_MODE
+		char_t wbuf[128];
+		widen_ascii(wbuf, buf);
+
+		return set_value(wbuf);
+	#else
+		return set_value(buf);
+	#endif
+	}
+
+	bool xml_attribute::set_value(unsigned int rhs)
+	{
+		char buf[128];
+		sprintf(buf, "%u", rhs);
+
+	#ifdef PUGIXML_WCHAR_MODE
+		char_t wbuf[128];
+		widen_ascii(wbuf, buf);
+
+		return set_value(wbuf);
+	#else
+		return set_value(buf);
+	#endif
+	}
+
+	bool xml_attribute::set_value(double rhs)
+	{
+		char buf[128];
+		sprintf(buf, "%g", rhs);
+
+	#ifdef PUGIXML_WCHAR_MODE
+		char_t wbuf[128];
+		widen_ascii(wbuf, buf);
+
+		return set_value(wbuf);
+	#else
+		return set_value(buf);
+	#endif
+	}
+	
+	bool xml_attribute::set_value(bool rhs)
+	{
+		return set_value(rhs ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));
+	}
+
+#ifdef __BORLANDC__
+	bool operator&&(const xml_attribute& lhs, bool rhs)
+	{
+		return (bool)lhs && rhs;
+	}
+
+	bool operator||(const xml_attribute& lhs, bool rhs)
+	{
+		return (bool)lhs || rhs;
+	}
+#endif
+
+	xml_node::xml_node(): _root(0)
+	{
+	}
+
+	xml_node::xml_node(xml_node_struct* p): _root(p)
+	{
+	}
+	
+	xml_node::operator xml_node::unspecified_bool_type() const
+	{
+      	return _root ? &xml_node::_root : 0;
+   	}
+
+   	bool xml_node::operator!() const
+   	{
+   		return !_root;
+   	}
+
+	xml_node::iterator xml_node::begin() const
+	{
+		return iterator(_root ? _root->first_child : 0, _root);
+	}
+
+	xml_node::iterator xml_node::end() const
+	{
+		return iterator(0, _root);
+	}
+	
+	xml_node::attribute_iterator xml_node::attributes_begin() const
+	{
+		return attribute_iterator(_root ? _root->first_attribute : 0, _root);
+	}
+
+	xml_node::attribute_iterator xml_node::attributes_end() const
+	{
+		return attribute_iterator(0, _root);
+	}
+
+	bool xml_node::operator==(const xml_node& r) const
+	{
+		return (_root == r._root);
+	}
+
+	bool xml_node::operator!=(const xml_node& r) const
+	{
+		return (_root != r._root);
+	}
+
+	bool xml_node::operator<(const xml_node& r) const
+	{
+		return (_root < r._root);
+	}
+	
+	bool xml_node::operator>(const xml_node& r) const
+	{
+		return (_root > r._root);
+	}
+	
+	bool xml_node::operator<=(const xml_node& r) const
+	{
+		return (_root <= r._root);
+	}
+	
+	bool xml_node::operator>=(const xml_node& r) const
+	{
+		return (_root >= r._root);
+	}
+
+	bool xml_node::empty() const
+	{
+		return !_root;
+	}
+	
+	const char_t* xml_node::name() const
+	{
+		return (_root && _root->name) ? _root->name : PUGIXML_TEXT("");
+	}
+
+	xml_node_type xml_node::type() const
+	{
+		return _root ? static_cast<xml_node_type>((_root->header & xml_memory_page_type_mask) + 1) : node_null;
+	}
+	
+	const char_t* xml_node::value() const
+	{
+		return (_root && _root->value) ? _root->value : PUGIXML_TEXT("");
+	}
+	
+	xml_node xml_node::child(const char_t* name) const
+	{
+		if (!_root) return xml_node();
+
+		for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+			if (i->name && strequal(name, i->name)) return xml_node(i);
+
+		return xml_node();
+	}
+
+	xml_attribute xml_node::attribute(const char_t* name) const
+	{
+		if (!_root) return xml_attribute();
+
+		for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
+			if (i->name && strequal(name, i->name))
+				return xml_attribute(i);
+		
+		return xml_attribute();
+	}
+	
+	xml_node xml_node::next_sibling(const char_t* name) const
+	{
+		if (!_root) return xml_node();
+		
+		for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling)
+			if (i->name && strequal(name, i->name)) return xml_node(i);
+
+		return xml_node();
+	}
+
+	xml_node xml_node::next_sibling() const
+	{
+		if (!_root) return xml_node();
+		
+		if (_root->next_sibling) return xml_node(_root->next_sibling);
+		else return xml_node();
+	}
+
+	xml_node xml_node::previous_sibling(const char_t* name) const
+	{
+		if (!_root) return xml_node();
+		
+		for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c)
+			if (i->name && strequal(name, i->name)) return xml_node(i);
+
+		return xml_node();
+	}
+
+	xml_node xml_node::previous_sibling() const
+	{
+		if (!_root) return xml_node();
+		
+		if (_root->prev_sibling_c->next_sibling) return xml_node(_root->prev_sibling_c);
+		else return xml_node();
+	}
+
+	xml_node xml_node::parent() const
+	{
+		return _root ? xml_node(_root->parent) : xml_node();
+	}
+
+	xml_node xml_node::root() const
+	{
+		if (!_root) return xml_node();
+
+		xml_memory_page* page = reinterpret_cast<xml_memory_page*>(_root->header & xml_memory_page_pointer_mask);
+
+		return xml_node(static_cast<xml_document_struct*>(page->allocator));
+	}
+
+	const char_t* xml_node::child_value() const
+	{
+		if (!_root) return PUGIXML_TEXT("");
+		
+		for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+		{
+			xml_node_type type = static_cast<xml_node_type>((i->header & xml_memory_page_type_mask) + 1);
+
+			if (i->value && (type == node_pcdata || type == node_cdata))
+				return i->value;
+		}
+
+		return PUGIXML_TEXT("");
+	}
+
+	const char_t* xml_node::child_value(const char_t* name) const
+	{
+		return child(name).child_value();
+	}
+
+	xml_attribute xml_node::first_attribute() const
+	{
+		return _root ? xml_attribute(_root->first_attribute) : xml_attribute();
+	}
+
+	xml_attribute xml_node::last_attribute() const
+	{
+		return _root && _root->first_attribute ? xml_attribute(_root->first_attribute->prev_attribute_c) : xml_attribute();
+	}
+
+	xml_node xml_node::first_child() const
+	{
+		return _root ? xml_node(_root->first_child) : xml_node();
+	}
+
+	xml_node xml_node::last_child() const
+	{
+		return _root && _root->first_child ? xml_node(_root->first_child->prev_sibling_c) : xml_node();
+	}
+
+	bool xml_node::set_name(const char_t* rhs)
+	{
+		switch (type())
+		{
+		case node_pi:
+		case node_declaration:
+		case node_element:
+			return strcpy_insitu(_root->name, _root->header, xml_memory_page_name_allocated_mask, rhs);
+
+		default:
+			return false;
+		}
+	}
+		
+	bool xml_node::set_value(const char_t* rhs)
+	{
+		switch (type())
+		{
+		case node_pi:
+		case node_cdata:
+		case node_pcdata:
+		case node_comment:
+        case node_doctype:
+			return strcpy_insitu(_root->value, _root->header, xml_memory_page_value_allocated_mask, rhs);
+
+		default:
+			return false;
+		}
+	}
+
+	xml_attribute xml_node::append_attribute(const char_t* name)
+	{
+		if (type() != node_element && type() != node_declaration) return xml_attribute();
+		
+		xml_attribute a(append_attribute_ll(_root, get_allocator(_root)));
+		a.set_name(name);
+		
+		return a;
+	}
+
+	xml_attribute xml_node::prepend_attribute(const char_t* name)
+	{
+		if (type() != node_element && type() != node_declaration) return xml_attribute();
+		
+		xml_attribute a(allocate_attribute(get_allocator(_root)));
+		if (!a) return xml_attribute();
+
+		a.set_name(name);
+		
+        xml_attribute_struct* head = _root->first_attribute;
+
+		if (head)
+        {
+            a._attr->prev_attribute_c = head->prev_attribute_c;
+            head->prev_attribute_c = a._attr;
+        }
+        else
+            a._attr->prev_attribute_c = a._attr;
+		
+		a._attr->next_attribute = head;
+        _root->first_attribute = a._attr;
+				
+		return a;
+	}
+
+	xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr)
+	{
+		if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute();
+		
+		// check that attribute belongs to *this
+		xml_attribute_struct* cur = attr._attr;
+
+		while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c;
+
+		if (cur != _root->first_attribute) return xml_attribute();
+
+		xml_attribute a(allocate_attribute(get_allocator(_root)));
+		if (!a) return xml_attribute();
+
+		a.set_name(name);
+
+		if (attr._attr->prev_attribute_c->next_attribute)
+			attr._attr->prev_attribute_c->next_attribute = a._attr;
+		else
+			_root->first_attribute = a._attr;
+		
+		a._attr->prev_attribute_c = attr._attr->prev_attribute_c;
+		a._attr->next_attribute = attr._attr;
+		attr._attr->prev_attribute_c = a._attr;
+				
+		return a;
+	}
+
+	xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr)
+	{
+		if ((type() != node_element && type() != node_declaration) || attr.empty()) return xml_attribute();
+		
+		// check that attribute belongs to *this
+		xml_attribute_struct* cur = attr._attr;
+
+		while (cur->prev_attribute_c->next_attribute) cur = cur->prev_attribute_c;
+
+		if (cur != _root->first_attribute) return xml_attribute();
+
+		xml_attribute a(allocate_attribute(get_allocator(_root)));
+		if (!a) return xml_attribute();
+
+		a.set_name(name);
+
+		if (attr._attr->next_attribute)
+			attr._attr->next_attribute->prev_attribute_c = a._attr;
+		else
+			_root->first_attribute->prev_attribute_c = a._attr;
+		
+		a._attr->next_attribute = attr._attr->next_attribute;
+		a._attr->prev_attribute_c = attr._attr;
+		attr._attr->next_attribute = a._attr;
+
+		return a;
+	}
+
+	xml_attribute xml_node::append_copy(const xml_attribute& proto)
+	{
+		if (!proto) return xml_attribute();
+
+		xml_attribute result = append_attribute(proto.name());
+		result.set_value(proto.value());
+
+		return result;
+	}
+
+	xml_attribute xml_node::prepend_copy(const xml_attribute& proto)
+	{
+		if (!proto) return xml_attribute();
+
+		xml_attribute result = prepend_attribute(proto.name());
+		result.set_value(proto.value());
+
+		return result;
+	}
+
+	xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr)
+	{
+		if (!proto) return xml_attribute();
+
+		xml_attribute result = insert_attribute_after(proto.name(), attr);
+		result.set_value(proto.value());
+
+		return result;
+	}
+
+	xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr)
+	{
+		if (!proto) return xml_attribute();
+
+		xml_attribute result = insert_attribute_before(proto.name(), attr);
+		result.set_value(proto.value());
+
+		return result;
+	}
+
+	xml_node xml_node::append_child(xml_node_type type)
+	{
+		if (!allow_insert_child(this->type(), type)) return xml_node();
+		
+		xml_node n(append_node(_root, get_allocator(_root), type));
+
+		if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
+
+		return n;
+	}
+
+	xml_node xml_node::prepend_child(xml_node_type type)
+	{
+		if (!allow_insert_child(this->type(), type)) return xml_node();
+		
+		xml_node n(allocate_node(get_allocator(_root), type));
+		if (!n) return xml_node();
+
+        n._root->parent = _root;
+
+        xml_node_struct* head = _root->first_child;
+
+		if (head)
+        {
+            n._root->prev_sibling_c = head->prev_sibling_c;
+            head->prev_sibling_c = n._root;
+        }
+        else
+            n._root->prev_sibling_c = n._root;
+		
+		n._root->next_sibling = head;
+        _root->first_child = n._root;
+				
+		if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
+
+		return n;
+	}
+
+	xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node)
+	{
+		if (!allow_insert_child(this->type(), type)) return xml_node();
+		if (!node._root || node._root->parent != _root) return xml_node();
+	
+		xml_node n(allocate_node(get_allocator(_root), type));
+		if (!n) return xml_node();
+
+		n._root->parent = _root;
+		
+		if (node._root->prev_sibling_c->next_sibling)
+			node._root->prev_sibling_c->next_sibling = n._root;
+		else
+			_root->first_child = n._root;
+		
+		n._root->prev_sibling_c = node._root->prev_sibling_c;
+		n._root->next_sibling = node._root;
+		node._root->prev_sibling_c = n._root;
+
+		if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
+
+		return n;
+	}
+
+	xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node)
+	{
+		if (!allow_insert_child(this->type(), type)) return xml_node();
+		if (!node._root || node._root->parent != _root) return xml_node();
+	
+		xml_node n(allocate_node(get_allocator(_root), type));
+		if (!n) return xml_node();
+
+		n._root->parent = _root;
+	
+		if (node._root->next_sibling)
+			node._root->next_sibling->prev_sibling_c = n._root;
+		else
+			_root->first_child->prev_sibling_c = n._root;
+		
+		n._root->next_sibling = node._root->next_sibling;
+		n._root->prev_sibling_c = node._root;
+		node._root->next_sibling = n._root;
+
+		if (type == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
+
+		return n;
+	}
+
+    xml_node xml_node::append_child(const char_t* name)
+    {
+        xml_node result = append_child(node_element);
+
+        result.set_name(name);
+
+        return result;
+    }
+
+    xml_node xml_node::prepend_child(const char_t* name)
+    {
+        xml_node result = prepend_child(node_element);
+
+        result.set_name(name);
+
+        return result;
+    }
+
+    xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node)
+    {
+        xml_node result = insert_child_after(node_element, node);
+
+        result.set_name(name);
+
+        return result;
+    }
+
+    xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node)
+    {
+        xml_node result = insert_child_before(node_element, node);
+
+        result.set_name(name);
+
+        return result;
+    }
+
+	xml_node xml_node::append_copy(const xml_node& proto)
+	{
+		xml_node result = append_child(proto.type());
+
+		if (result) recursive_copy_skip(result, proto, result);
+
+		return result;
+	}
+
+	xml_node xml_node::prepend_copy(const xml_node& proto)
+	{
+		xml_node result = prepend_child(proto.type());
+
+		if (result) recursive_copy_skip(result, proto, result);
+
+		return result;
+	}
+
+	xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node)
+	{
+		xml_node result = insert_child_after(proto.type(), node);
+
+		if (result) recursive_copy_skip(result, proto, result);
+
+		return result;
+	}
+
+	xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node)
+	{
+		xml_node result = insert_child_before(proto.type(), node);
+
+		if (result) recursive_copy_skip(result, proto, result);
+
+		return result;
+	}
+
+	bool xml_node::remove_attribute(const char_t* name)
+	{
+		return remove_attribute(attribute(name));
+	}
+
+	bool xml_node::remove_attribute(const xml_attribute& a)
+	{
+		if (!_root || !a._attr) return false;
+
+		// check that attribute belongs to *this
+		xml_attribute_struct* attr = a._attr;
+
+		while (attr->prev_attribute_c->next_attribute) attr = attr->prev_attribute_c;
+
+		if (attr != _root->first_attribute) return false;
+
+		if (a._attr->next_attribute) a._attr->next_attribute->prev_attribute_c = a._attr->prev_attribute_c;
+		else if (_root->first_attribute) _root->first_attribute->prev_attribute_c = a._attr->prev_attribute_c;
+		
+		if (a._attr->prev_attribute_c->next_attribute) a._attr->prev_attribute_c->next_attribute = a._attr->next_attribute;
+		else _root->first_attribute = a._attr->next_attribute;
+
+		destroy_attribute(a._attr, get_allocator(_root));
+
+		return true;
+	}
+
+	bool xml_node::remove_child(const char_t* name)
+	{
+		return remove_child(child(name));
+	}
+
+	bool xml_node::remove_child(const xml_node& n)
+	{
+		if (!_root || !n._root || n._root->parent != _root) return false;
+
+		if (n._root->next_sibling) n._root->next_sibling->prev_sibling_c = n._root->prev_sibling_c;
+		else if (_root->first_child) _root->first_child->prev_sibling_c = n._root->prev_sibling_c;
+		
+		if (n._root->prev_sibling_c->next_sibling) n._root->prev_sibling_c->next_sibling = n._root->next_sibling;
+		else _root->first_child = n._root->next_sibling;
+        
+        destroy_node(n._root, get_allocator(_root));
+
+		return true;
+	}
+
+	xml_node xml_node::find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const
+	{
+		if (!_root) return xml_node();
+		
+		for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+			if (i->name && strequal(name, i->name))
+			{
+				for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+					if (strequal(attr_name, a->name) && strequal(attr_value, a->value))
+						return xml_node(i);
+			}
+
+		return xml_node();
+	}
+
+	xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const
+	{
+		if (!_root) return xml_node();
+		
+		for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+			for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
+				if (strequal(attr_name, a->name) && strequal(attr_value, a->value))
+					return xml_node(i);
+
+		return xml_node();
+	}
+
+#ifndef PUGIXML_NO_STL
+	string_t xml_node::path(char_t delimiter) const
+	{
+		string_t path;
+
+		xml_node cursor = *this; // Make a copy.
+		
+		path = cursor.name();
+
+		while (cursor.parent())
+		{
+			cursor = cursor.parent();
+			
+			string_t temp = cursor.name();
+			temp += delimiter;
+			temp += path;
+			path.swap(temp);
+		}
+
+		return path;
+	}
+#endif
+
+	xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter) const
+	{
+		xml_node found = *this; // Current search context.
+
+		if (!_root || !path || !path[0]) return found;
+
+		if (path[0] == delimiter)
+		{
+			// Absolute path; e.g. '/foo/bar'
+			found = found.root();
+			++path;
+		}
+
+		const char_t* path_segment = path;
+
+		while (*path_segment == delimiter) ++path_segment;
+
+		const char_t* path_segment_end = path_segment;
+
+		while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end;
+
+		if (path_segment == path_segment_end) return found;
+
+		const char_t* next_segment = path_segment_end;
+
+		while (*next_segment == delimiter) ++next_segment;
+
+		if (*path_segment == '.' && path_segment + 1 == path_segment_end)
+			return found.first_element_by_path(next_segment, delimiter);
+		else if (*path_segment == '.' && *(path_segment+1) == '.' && path_segment + 2 == path_segment_end)
+			return found.parent().first_element_by_path(next_segment, delimiter);
+		else
+		{
+			for (xml_node_struct* j = found._root->first_child; j; j = j->next_sibling)
+			{
+				if (j->name && strequalrange(j->name, path_segment, static_cast<size_t>(path_segment_end - path_segment)))
+				{
+					xml_node subsearch = xml_node(j).first_element_by_path(next_segment, delimiter);
+
+					if (subsearch) return subsearch;
+				}
+			}
+
+			return xml_node();
+		}
+	}
+
+	bool xml_node::traverse(xml_tree_walker& walker)
+	{
+		walker._depth = -1;
+		
+		xml_node arg_begin = *this;
+		if (!walker.begin(arg_begin)) return false;
+
+		xml_node cur = first_child();
+				
+		if (cur)
+		{
+			++walker._depth;
+
+			do 
+			{
+				xml_node arg_for_each = cur;
+				if (!walker.for_each(arg_for_each))
+					return false;
+						
+				if (cur.first_child())
+				{
+					++walker._depth;
+					cur = cur.first_child();
+				}
+				else if (cur.next_sibling())
+					cur = cur.next_sibling();
+				else
+				{
+					// Borland C++ workaround
+					while (!cur.next_sibling() && cur != *this && (bool)cur.parent())
+					{
+						--walker._depth;
+						cur = cur.parent();
+					}
+						
+					if (cur != *this)
+						cur = cur.next_sibling();
+				}
+			}
+			while (cur && cur != *this);
+		}
+
+		assert(walker._depth == -1);
+
+		xml_node arg_end = *this;
+		return walker.end(arg_end);
+	}
+
+    size_t xml_node::hash_value() const
+    {
+        return static_cast<size_t>(reinterpret_cast<uintptr_t>(_root) / sizeof(xml_node_struct));
+    }
+
+	xml_node_struct* xml_node::internal_object() const
+	{
+        return _root;
+	}
+
+	void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const
+	{
+		if (!_root) return;
+
+		xml_buffered_writer buffered_writer(writer, encoding);
+
+		node_output(buffered_writer, *this, indent, flags, depth);
+	}
+
+#ifndef PUGIXML_NO_STL
+	void xml_node::print(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const
+	{
+		xml_writer_stream writer(stream);
+
+		print(writer, indent, flags, encoding, depth);
+	}
+
+	void xml_node::print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const
+	{
+		xml_writer_stream writer(stream);
+
+		print(writer, indent, flags, encoding_wchar, depth);
+	}
+#endif
+
+	ptrdiff_t xml_node::offset_debug() const
+	{
+		xml_node_struct* r = root()._root;
+
+		if (!r) return -1;
+
+		const char_t* buffer = static_cast<xml_document_struct*>(r)->buffer;
+
+		if (!buffer) return -1;
+
+		switch (type())
+		{
+		case node_document:
+			return 0;
+
+		case node_element:
+		case node_declaration:
+		case node_pi:
+			return (_root->header & xml_memory_page_name_allocated_mask) ? -1 : _root->name - buffer;
+
+		case node_pcdata:
+		case node_cdata:
+		case node_comment:
+		case node_doctype:
+			return (_root->header & xml_memory_page_value_allocated_mask) ? -1 : _root->value - buffer;
+
+		default:
+			return -1;
+		}
+	}
+
+#ifdef __BORLANDC__
+	bool operator&&(const xml_node& lhs, bool rhs)
+	{
+		return (bool)lhs && rhs;
+	}
+
+	bool operator||(const xml_node& lhs, bool rhs)
+	{
+		return (bool)lhs || rhs;
+	}
+#endif
+
+	xml_node_iterator::xml_node_iterator()
+	{
+	}
+
+	xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent())
+	{
+	}
+
+	xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent)
+	{
+	}
+
+	bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const
+	{
+		return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root;
+	}
+	
+	bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const
+	{
+		return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root;
+	}
+
+	xml_node& xml_node_iterator::operator*()
+	{
+		assert(_wrap._root);
+		return _wrap;
+	}
+
+	xml_node* xml_node_iterator::operator->()
+	{
+		assert(_wrap._root);
+		return &_wrap;
+	}
+
+	const xml_node_iterator& xml_node_iterator::operator++()
+	{
+		assert(_wrap._root);
+		_wrap._root = _wrap._root->next_sibling;
+		return *this;
+	}
+
+	xml_node_iterator xml_node_iterator::operator++(int)
+	{
+		xml_node_iterator temp = *this;
+		++*this;
+		return temp;
+	}
+
+	const xml_node_iterator& xml_node_iterator::operator--()
+	{
+		_wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child();
+		return *this;
+	}
+
+	xml_node_iterator xml_node_iterator::operator--(int)
+	{
+		xml_node_iterator temp = *this;
+		--*this;
+		return temp;
+	}
+
+	xml_attribute_iterator::xml_attribute_iterator()
+	{
+	}
+
+	xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent)
+	{
+	}
+
+	xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent)
+	{
+	}
+
+	bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const
+	{
+		return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root;
+	}
+	
+	bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const
+	{
+		return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root;
+	}
+
+	xml_attribute& xml_attribute_iterator::operator*()
+	{
+		assert(_wrap._attr);
+		return _wrap;
+	}
+
+	xml_attribute* xml_attribute_iterator::operator->()
+	{
+		assert(_wrap._attr);
+		return &_wrap;
+	}
+
+	const xml_attribute_iterator& xml_attribute_iterator::operator++()
+	{
+		assert(_wrap._attr);
+		_wrap._attr = _wrap._attr->next_attribute;
+		return *this;
+	}
+
+	xml_attribute_iterator xml_attribute_iterator::operator++(int)
+	{
+		xml_attribute_iterator temp = *this;
+		++*this;
+		return temp;
+	}
+
+	const xml_attribute_iterator& xml_attribute_iterator::operator--()
+	{
+		_wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute();
+		return *this;
+	}
+
+	xml_attribute_iterator xml_attribute_iterator::operator--(int)
+	{
+		xml_attribute_iterator temp = *this;
+		--*this;
+		return temp;
+	}
+
+    xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto)
+    {
+    }
+
+    xml_parse_result::operator bool() const
+    {
+        return status == status_ok;
+    }
+
+	const char* xml_parse_result::description() const
+	{
+		switch (status)
+		{
+		case status_ok: return "No error";
+
+		case status_file_not_found: return "File was not found";
+		case status_io_error: return "Error reading from file/stream";
+		case status_out_of_memory: return "Could not allocate memory";
+		case status_internal_error: return "Internal error occurred";
+
+		case status_unrecognized_tag: return "Could not determine tag type";
+
+		case status_bad_pi: return "Error parsing document declaration/processing instruction";
+		case status_bad_comment: return "Error parsing comment";
+		case status_bad_cdata: return "Error parsing CDATA section";
+		case status_bad_doctype: return "Error parsing document type declaration";
+		case status_bad_pcdata: return "Error parsing PCDATA section";
+		case status_bad_start_element: return "Error parsing start element tag";
+		case status_bad_attribute: return "Error parsing element attribute";
+		case status_bad_end_element: return "Error parsing end element tag";
+		case status_end_element_mismatch: return "Start-end tags mismatch";
+
+		default: return "Unknown error";
+		}
+	}
+
+	xml_document::xml_document(): _buffer(0)
+	{
+		create();
+	}
+
+	xml_document::~xml_document()
+	{
+		destroy();
+	}
+
+	void xml_document::reset()
+	{
+		destroy();
+		create();
+	}
+
+    void xml_document::reset(const xml_document& proto)
+    {
+        reset();
+
+        for (xml_node cur = proto.first_child(); cur; cur = cur.next_sibling())
+            append_copy(cur);
+    }
+
+	void xml_document::create()
+	{
+		// initialize sentinel page
+		STATIC_ASSERT(offsetof(xml_memory_page, data) + sizeof(xml_document_struct) + xml_memory_page_alignment <= sizeof(_memory));
+
+		// align upwards to page boundary
+		void* page_memory = reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(_memory) + (xml_memory_page_alignment - 1)) & ~(xml_memory_page_alignment - 1));
+
+		// prepare page structure
+		xml_memory_page* page = xml_memory_page::construct(page_memory);
+
+		page->busy_size = xml_memory_page_size;
+
+		// allocate new root
+		_root = new (page->data) xml_document_struct(page);
+		_root->prev_sibling_c = _root;
+
+		// setup sentinel page
+		page->allocator = static_cast<xml_document_struct*>(_root);
+	}
+
+	void xml_document::destroy()
+	{
+		// destroy static storage
+		if (_buffer)
+		{
+			global_deallocate(_buffer);
+			_buffer = 0;
+		}
+
+		// destroy dynamic storage, leave sentinel page (it's in static memory)
+		if (_root)
+		{
+			xml_memory_page* root_page = reinterpret_cast<xml_memory_page*>(_root->header & xml_memory_page_pointer_mask);
+			assert(root_page && !root_page->prev && !root_page->memory);
+
+			// destroy all pages
+			for (xml_memory_page* page = root_page->next; page; )
+			{
+				xml_memory_page* next = page->next;
+
+				xml_allocator::deallocate_page(page);
+
+				page = next;
+			}
+
+			// cleanup root page
+			root_page->allocator = 0;
+			root_page->next = 0;
+			root_page->busy_size = root_page->freed_size = 0;
+
+			_root = 0;
+		}
+	}
+
+#ifndef PUGIXML_NO_STL
+	xml_parse_result xml_document::load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options, xml_encoding encoding)
+	{
+		reset();
+
+		return load_stream_impl(*this, stream, options, encoding);
+	}
+
+	xml_parse_result xml_document::load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options)
+	{
+		reset();
+
+		return load_stream_impl(*this, stream, options, encoding_wchar);
+	}
+#endif
+
+	xml_parse_result xml_document::load(const char_t* contents, unsigned int options)
+	{
+		// Force native encoding (skip autodetection)
+	#ifdef PUGIXML_WCHAR_MODE
+		xml_encoding encoding = encoding_wchar;
+	#else
+		xml_encoding encoding = encoding_utf8;
+	#endif
+
+		return load_buffer(contents, strlength(contents) * sizeof(char_t), options, encoding);
+	}
+
+	xml_parse_result xml_document::load_file(const char* path, unsigned int options, xml_encoding encoding)
+	{
+		reset();
+
+		FILE* file = fopen(path, "rb");
+
+		return load_file_impl(*this, file, options, encoding);
+	}
+
+	xml_parse_result xml_document::load_file(const wchar_t* path, unsigned int options, xml_encoding encoding)
+	{
+		reset();
+
+		FILE* file = open_file_wide(path, L"rb");
+
+		return load_file_impl(*this, file, options, encoding);
+	}
+
+	xml_parse_result xml_document::load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own)
+	{
+		reset();
+
+		// check input buffer
+		assert(contents || size == 0);
+
+		// get actual encoding
+		xml_encoding buffer_encoding = get_buffer_encoding(encoding, contents, size);
+
+		// get private buffer
+		char_t* buffer = 0;
+		size_t length = 0;
+
+		if (!convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable)) return make_parse_result(status_out_of_memory);
+		
+		// delete original buffer if we performed a conversion
+		if (own && buffer != contents && contents) global_deallocate(contents);
+
+		// parse
+		xml_parse_result res = xml_parser::parse(buffer, length, _root, options);
+
+		// remember encoding
+		res.encoding = buffer_encoding;
+
+		// grab onto buffer if it's our buffer, user is responsible for deallocating contens himself
+		if (own || buffer != contents) _buffer = buffer;
+
+		return res;
+	}
+
+	xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding)
+	{
+		return load_buffer_impl(const_cast<void*>(contents), size, options, encoding, false, false);
+	}
+
+	xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding)
+	{
+		return load_buffer_impl(contents, size, options, encoding, true, false);
+	}
+		
+	xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding)
+	{
+		return load_buffer_impl(contents, size, options, encoding, true, true);
+	}
+
+	void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const
+	{
+		if (flags & format_write_bom) write_bom(writer, get_write_encoding(encoding));
+
+		xml_buffered_writer buffered_writer(writer, encoding);
+
+		if (!(flags & format_no_declaration) && !has_declaration(*this))
+		{
+			buffered_writer.write(PUGIXML_TEXT("<?xml version=\"1.0\"?>"));
+			if (!(flags & format_raw)) buffered_writer.write('\n');
+		}
+
+		node_output(buffered_writer, *this, indent, flags, 0);
+	}
+
+#ifndef PUGIXML_NO_STL
+	void xml_document::save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const
+	{
+		xml_writer_stream writer(stream);
+
+		save(writer, indent, flags, encoding);
+	}
+
+	void xml_document::save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags) const
+	{
+		xml_writer_stream writer(stream);
+
+		save(writer, indent, flags, encoding_wchar);
+	}
+#endif
+
+	bool xml_document::save_file(const char* path, const char_t* indent, unsigned int flags, xml_encoding encoding) const
+	{
+		FILE* file = fopen(path, "wb");
+		if (!file) return false;
+
+		xml_writer_file writer(file);
+		save(writer, indent, flags, encoding);
+
+		fclose(file);
+
+		return true;
+	}
+
+	bool xml_document::save_file(const wchar_t* path, const char_t* indent, unsigned int flags, xml_encoding encoding) const
+	{
+		FILE* file = open_file_wide(path, L"wb");
+		if (!file) return false;
+
+		xml_writer_file writer(file);
+		save(writer, indent, flags, encoding);
+
+		fclose(file);
+
+		return true;
+	}
+
+    xml_node xml_document::document_element() const
+    {
+		for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
+			if ((i->header & xml_memory_page_type_mask) + 1 == node_element)
+                return xml_node(i);
+
+        return xml_node();
+    }
+
+#ifndef PUGIXML_NO_STL
+	std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str)
+	{
+		assert(str);
+
+        return as_utf8_impl(str, wcslen(str));
+	}
+
+	std::string PUGIXML_FUNCTION as_utf8(const std::wstring& str)
+	{
+        return as_utf8_impl(str.c_str(), str.size());
+	}
+	
+	std::wstring PUGIXML_FUNCTION as_wide(const char* str)
+	{
+		assert(str);
+
+        return as_wide_impl(str, strlen(str));
+	}
+	
+	std::wstring PUGIXML_FUNCTION as_wide(const std::string& str)
+	{
+        return as_wide_impl(str.c_str(), str.size());
+	}
+#endif
+
+    void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate)
+    {
+    	global_allocate = allocate;
+    	global_deallocate = deallocate;
+    }
+
+    allocation_function PUGIXML_FUNCTION get_memory_allocation_function()
+    {
+    	return global_allocate;
+    }
+
+    deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function()
+    {
+    	return global_deallocate;
+    }
+}
+
+#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
+namespace std
+{
+	// Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier)
+	std::bidirectional_iterator_tag _Iter_cat(const xml_node_iterator&)
+	{
+		return std::bidirectional_iterator_tag();
+	}
+
+	std::bidirectional_iterator_tag _Iter_cat(const xml_attribute_iterator&)
+	{
+		return std::bidirectional_iterator_tag();
+	}
+}
+#endif
+
+#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
+namespace std
+{
+	// Workarounds for (non-standard) iterator category detection
+	std::bidirectional_iterator_tag __iterator_category(const xml_node_iterator&)
+	{
+		return std::bidirectional_iterator_tag();
+	}
+
+	std::bidirectional_iterator_tag __iterator_category(const xml_attribute_iterator&)
+	{
+		return std::bidirectional_iterator_tag();
+	}
+}
+#endif
+
+#ifndef PUGIXML_NO_XPATH
+
+// STL replacements
+namespace
+{
+	struct equal_to
+	{
+		template <typename T> bool operator()(const T& lhs, const T& rhs) const
+		{
+			return lhs == rhs;
+		}
+	};
+
+	struct not_equal_to
+	{
+		template <typename T> bool operator()(const T& lhs, const T& rhs) const
+		{
+			return lhs != rhs;
+		}
+	};
+
+	struct less
+	{
+		template <typename T> bool operator()(const T& lhs, const T& rhs) const
+		{
+			return lhs < rhs;
+		}
+	};
+
+	struct less_equal
+	{
+		template <typename T> bool operator()(const T& lhs, const T& rhs) const
+		{
+			return lhs <= rhs;
+		}
+	};
+
+	template <typename T> void swap(T& lhs, T& rhs)
+	{
+		T temp = lhs;
+		lhs = rhs;
+		rhs = temp;
+	}
+
+	template <typename I, typename Pred> I min_element(I begin, I end, const Pred& pred)
+	{
+		I result = begin;
+
+		for (I it = begin + 1; it != end; ++it)
+			if (pred(*it, *result))
+				result = it;
+
+		return result;
+	}
+
+	template <typename I> void reverse(I begin, I end)
+	{
+		while (begin + 1 < end) swap(*begin++, *--end);
+	}
+
+	template <typename I> I unique(I begin, I end)
+	{
+		// fast skip head
+		while (begin + 1 < end && *begin != *(begin + 1)) begin++;
+
+		if (begin == end) return begin;
+
+		// last written element
+		I write = begin++; 
+
+		// merge unique elements
+		while (begin != end)
+		{
+			if (*begin != *write)
+				*++write = *begin++;
+			else
+				begin++;
+		}
+
+		// past-the-end (write points to live element)
+		return write + 1;
+	}
+
+	template <typename I> void copy_backwards(I begin, I end, I target)
+	{
+		while (begin != end) *--target = *--end;
+	}
+
+	template <typename I, typename Pred, typename T> void insertion_sort(I begin, I end, const Pred& pred, T*)
+	{
+		assert(begin != end);
+
+		for (I it = begin + 1; it != end; ++it)
+		{
+			T val = *it;
+
+			if (pred(val, *begin))
+			{
+				// move to front
+				copy_backwards(begin, it, it + 1);
+				*begin = val;
+			}
+			else
+			{
+				I hole = it;
+
+				// move hole backwards
+				while (pred(val, *(hole - 1)))
+				{
+					*hole = *(hole - 1);
+					hole--;
+				}
+
+				// fill hole with element
+				*hole = val;
+			}
+		}
+	}
+
+	// std variant for elements with ==
+	template <typename I, typename Pred> void partition(I begin, I middle, I end, const Pred& pred, I* out_eqbeg, I* out_eqend)
+	{
+		I eqbeg = middle, eqend = middle + 1;
+
+		// expand equal range
+		while (eqbeg != begin && *(eqbeg - 1) == *eqbeg) --eqbeg;
+		while (eqend != end && *eqend == *eqbeg) ++eqend;
+
+		// process outer elements
+		I ltend = eqbeg, gtbeg = eqend;
+
+		for (;;)
+		{
+			// find the element from the right side that belongs to the left one
+			for (; gtbeg != end; ++gtbeg)
+				if (!pred(*eqbeg, *gtbeg))
+				{
+					if (*gtbeg == *eqbeg) swap(*gtbeg, *eqend++);
+					else break;
+				}
+
+			// find the element from the left side that belongs to the right one
+			for (; ltend != begin; --ltend)
+				if (!pred(*(ltend - 1), *eqbeg))
+				{
+					if (*eqbeg == *(ltend - 1)) swap(*(ltend - 1), *--eqbeg);
+					else break;
+				}
+
+			// scanned all elements
+			if (gtbeg == end && ltend == begin)
+			{
+				*out_eqbeg = eqbeg;
+				*out_eqend = eqend;
+				return;
+			}
+
+			// make room for elements by moving equal area
+			if (gtbeg == end)
+			{
+				if (--ltend != --eqbeg) swap(*ltend, *eqbeg);
+				swap(*eqbeg, *--eqend);
+			}
+			else if (ltend == begin)
+			{
+				if (eqend != gtbeg) swap(*eqbeg, *eqend);
+				++eqend;
+				swap(*gtbeg++, *eqbeg++);
+			}
+			else swap(*gtbeg++, *--ltend);
+		}
+	}
+
+	template <typename I, typename Pred> void median3(I first, I middle, I last, const Pred& pred)
+	{
+		if (pred(*middle, *first)) swap(*middle, *first);
+		if (pred(*last, *middle)) swap(*last, *middle);
+		if (pred(*middle, *first)) swap(*middle, *first);
+	}
+
+	template <typename I, typename Pred> void median(I first, I middle, I last, const Pred& pred)
+	{
+		if (last - first <= 40)
+		{
+			// median of three for small chunks
+			median3(first, middle, last, pred);
+		}
+		else
+		{
+			// median of nine
+			size_t step = (last - first + 1) / 8;
+
+			median3(first, first + step, first + 2 * step, pred);
+			median3(middle - step, middle, middle + step, pred);
+			median3(last - 2 * step, last - step, last, pred);
+			median3(first + step, middle, last - step, pred);
+		}
+	}
+
+	template <typename I, typename Pred> void sort(I begin, I end, const Pred& pred)
+	{
+		// sort large chunks
+		while (end - begin > 32)
+		{
+			// find median element
+			I middle = begin + (end - begin) / 2;
+			median(begin, middle, end - 1, pred);
+
+			// partition in three chunks (< = >)
+			I eqbeg, eqend;
+			partition(begin, middle, end, pred, &eqbeg, &eqend);
+
+			// loop on larger half
+			if (eqbeg - begin > end - eqend)
+			{
+				sort(eqend, end, pred);
+				end = eqbeg;
+			}
+			else
+			{
+				sort(begin, eqbeg, pred);
+				begin = eqend;
+			}
+		}
+
+		// insertion sort small chunk
+		if (begin != end) insertion_sort(begin, end, pred, &*begin);
+	}
+}
+
+// Allocator used for AST and evaluation stacks
+namespace
+{
+	struct xpath_memory_block
+	{	
+		xpath_memory_block* next;
+
+		char data[4096];
+	};
+		
+	class xpath_allocator
+	{
+		xpath_memory_block* _root;
+		size_t _root_size;
+
+	public:
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		jmp_buf* error_handler;
+	#endif
+
+		xpath_allocator(xpath_memory_block* root, size_t root_size = 0): _root(root), _root_size(root_size)
+		{
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			error_handler = 0;
+		#endif
+		}
+		
+		void* allocate_nothrow(size_t size)
+		{
+			const size_t block_capacity = sizeof(_root->data);
+
+			// align size so that we're able to store pointers in subsequent blocks
+			size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+
+			if (_root_size + size <= block_capacity)
+			{
+				void* buf = _root->data + _root_size;
+				_root_size += size;
+				return buf;
+			}
+			else
+			{
+				size_t block_data_size = (size > block_capacity) ? size : block_capacity;
+				size_t block_size = block_data_size + offsetof(xpath_memory_block, data);
+
+				xpath_memory_block* block = static_cast<xpath_memory_block*>(global_allocate(block_size));
+				if (!block) return 0;
+				
+				block->next = _root;
+				
+				_root = block;
+				_root_size = size;
+				
+				return block->data;
+			}
+		}
+
+		void* allocate(size_t size)
+		{
+			void* result = allocate_nothrow(size);
+
+			if (!result)
+			{
+			#ifdef PUGIXML_NO_EXCEPTIONS
+				assert(error_handler);
+				longjmp(*error_handler, 1);
+			#else
+				throw std::bad_alloc();
+			#endif
+			}
+
+			return result;
+		}
+
+		void* reallocate(void* ptr, size_t old_size, size_t new_size)
+		{
+			// align size so that we're able to store pointers in subsequent blocks
+			old_size = (old_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+			new_size = (new_size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
+
+			// we can only reallocate the last object
+			assert(ptr == 0 || static_cast<char*>(ptr) + old_size == _root->data + _root_size);
+
+			// adjust root size so that we have not allocated the object at all
+			bool only_object = (_root_size == old_size);
+
+			if (ptr) _root_size -= old_size;
+
+			// allocate a new version (this will obviously reuse the memory if possible)
+			void* result = allocate(new_size);
+			assert(result);
+
+			// we have a new block
+			if (result != ptr && ptr)
+			{
+				// copy old data
+				assert(new_size > old_size);
+				memcpy(result, ptr, old_size);
+
+				// free the previous page if it had no other objects
+				if (only_object)
+				{
+					assert(_root->data == result);
+					assert(_root->next);
+
+					xpath_memory_block* next = _root->next->next;
+
+					if (next)
+					{
+						// deallocate the whole page, unless it was the first one
+						global_deallocate(_root->next);
+						_root->next = next;
+					}
+				}
+			}
+
+			return result;
+		}
+
+		void revert(const xpath_allocator& state)
+		{
+			// free all new pages
+			xpath_memory_block* cur = _root;
+
+			while (cur != state._root)
+			{
+				xpath_memory_block* next = cur->next;
+
+				global_deallocate(cur);
+
+				cur = next;
+			}
+
+			// restore state
+			_root = state._root;
+			_root_size = state._root_size;
+		}
+
+		void release()
+		{
+			xpath_memory_block* cur = _root;
+			assert(cur);
+
+			while (cur->next)
+			{
+				xpath_memory_block* next = cur->next;
+
+				global_deallocate(cur);
+
+				cur = next;
+			}
+		}
+	};
+
+	struct xpath_allocator_capture
+	{
+		xpath_allocator_capture(xpath_allocator* alloc): _target(alloc), _state(*alloc)
+		{
+		}
+
+		~xpath_allocator_capture()
+		{
+			_target->revert(_state);
+		}
+
+		xpath_allocator* _target;
+		xpath_allocator _state;
+	};
+
+	struct xpath_stack
+	{
+		xpath_allocator* result;
+		xpath_allocator* temp;
+	};
+
+	struct xpath_stack_data
+	{
+		xpath_memory_block blocks[2];
+		xpath_allocator result;
+		xpath_allocator temp;
+		xpath_stack stack;
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		jmp_buf error_handler;
+	#endif
+
+		xpath_stack_data(): result(blocks + 0), temp(blocks + 1)
+		{
+			blocks[0].next = blocks[1].next = 0;
+
+			stack.result = &result;
+			stack.temp = &temp;
+
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			result.error_handler = temp.error_handler = &error_handler;
+		#endif
+		}
+
+		~xpath_stack_data()
+		{
+			result.release();
+			temp.release();
+		}
+	};
+}
+
+// String class
+namespace
+{
+	class xpath_string
+	{
+		const char_t* _buffer;
+		bool _uses_heap;
+
+		static char_t* duplicate_string(const char_t* string, size_t length, xpath_allocator* alloc)
+		{
+			char_t* result = static_cast<char_t*>(alloc->allocate((length + 1) * sizeof(char_t)));
+			assert(result);
+
+			memcpy(result, string, length * sizeof(char_t));
+			result[length] = 0;
+
+			return result;
+		}
+
+		static char_t* duplicate_string(const char_t* string, xpath_allocator* alloc)
+		{
+			return duplicate_string(string, strlength(string), alloc);
+		}
+
+	public:
+		xpath_string(): _buffer(PUGIXML_TEXT("")), _uses_heap(false)
+		{
+		}
+
+		explicit xpath_string(const char_t* str, xpath_allocator* alloc)
+		{
+			bool empty = (*str == 0);
+
+			_buffer = empty ? PUGIXML_TEXT("") : duplicate_string(str, alloc);
+			_uses_heap = !empty;
+		}
+
+		explicit xpath_string(const char_t* str, bool use_heap): _buffer(str), _uses_heap(use_heap)
+		{
+		}
+
+		xpath_string(const char_t* begin, const char_t* end, xpath_allocator* alloc)
+		{
+			assert(begin <= end);
+
+			bool empty = (begin == end);
+
+			_buffer = empty ? PUGIXML_TEXT("") : duplicate_string(begin, static_cast<size_t>(end - begin), alloc);
+			_uses_heap = !empty;
+		}
+
+		void append(const xpath_string& o, xpath_allocator* alloc)
+		{
+			// skip empty sources
+			if (!*o._buffer) return;
+
+			// fast append for constant empty target and constant source
+			if (!*_buffer && !_uses_heap && !o._uses_heap)
+			{
+				_buffer = o._buffer;
+			}
+			else
+			{
+				// need to make heap copy
+				size_t target_length = strlength(_buffer);
+				size_t source_length = strlength(o._buffer);
+				size_t length = target_length + source_length;
+
+				// allocate new buffer
+				char_t* result = static_cast<char_t*>(alloc->reallocate(_uses_heap ? const_cast<char_t*>(_buffer) : 0, (target_length + 1) * sizeof(char_t), (length + 1) * sizeof(char_t)));
+				assert(result);
+
+				// append first string to the new buffer in case there was no reallocation
+				if (!_uses_heap) memcpy(result, _buffer, target_length * sizeof(char_t));
+
+				// append second string to the new buffer
+				memcpy(result + target_length, o._buffer, source_length * sizeof(char_t));
+				result[length] = 0;
+
+				// finalize
+				_buffer = result;
+				_uses_heap = true;
+			}
+		}
+
+		const char_t* c_str() const
+		{
+			return _buffer;
+		}
+
+		size_t length() const
+		{
+			return strlength(_buffer);
+		}
+		
+		char_t* data(xpath_allocator* alloc)
+		{
+			// make private heap copy
+			if (!_uses_heap)
+			{
+				_buffer = duplicate_string(_buffer, alloc);
+				_uses_heap = true;
+			}
+
+			return const_cast<char_t*>(_buffer);
+		}
+
+		bool empty() const
+		{
+			return *_buffer == 0;
+		}
+
+		bool operator==(const xpath_string& o) const
+		{
+			return strequal(_buffer, o._buffer);
+		}
+
+		bool operator!=(const xpath_string& o) const
+		{
+			return !strequal(_buffer, o._buffer);
+		}
+
+		bool uses_heap() const
+		{
+			return _uses_heap;
+		}
+	};
+
+	xpath_string xpath_string_const(const char_t* str)
+	{
+		return xpath_string(str, false);
+	}
+}
+
+namespace
+{
+	bool starts_with(const char_t* string, const char_t* pattern)
+	{
+		while (*pattern && *string == *pattern)
+		{
+			string++;
+			pattern++;
+		}
+
+		return *pattern == 0;
+	}
+
+	const char_t* find_char(const char_t* s, char_t c)
+	{
+	#ifdef PUGIXML_WCHAR_MODE
+		return wcschr(s, c);
+	#else
+		return strchr(s, c);
+	#endif
+	}
+
+	const char_t* find_substring(const char_t* s, const char_t* p)
+	{
+	#ifdef PUGIXML_WCHAR_MODE
+		// MSVC6 wcsstr bug workaround (if s is empty it always returns 0)
+		return (*p == 0) ? s : wcsstr(s, p);
+	#else
+		return strstr(s, p);
+	#endif
+	}
+
+	// Converts symbol to lower case, if it is an ASCII one
+	char_t tolower_ascii(char_t ch)
+	{
+		return static_cast<unsigned int>(ch - 'A') < 26 ? static_cast<char_t>(ch | ' ') : ch;
+	}
+
+	xpath_string string_value(const xpath_node& na, xpath_allocator* alloc)
+	{
+		if (na.attribute())
+			return xpath_string_const(na.attribute().value());
+		else
+		{
+			const xml_node& n = na.node();
+
+			switch (n.type())
+			{
+			case node_pcdata:
+			case node_cdata:
+			case node_comment:
+			case node_pi:
+				return xpath_string_const(n.value());
+			
+			case node_document:
+			case node_element:
+			{
+				xpath_string result;
+
+				xml_node cur = n.first_child();
+				
+				while (cur && cur != n)
+				{
+					if (cur.type() == node_pcdata || cur.type() == node_cdata)
+						result.append(xpath_string_const(cur.value()), alloc);
+
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
+					{
+						while (!cur.next_sibling() && cur != n)
+							cur = cur.parent();
+
+						if (cur != n) cur = cur.next_sibling();
+					}
+				}
+				
+				return result;
+			}
+			
+			default:
+				return xpath_string();
+			}
+		}
+	}
+	
+	unsigned int node_height(xml_node n)
+	{
+	    unsigned int result = 0;
+	    
+	    while (n)
+	    {
+	        ++result;
+	        n = n.parent();
+	    }
+	    
+	    return result;
+	}
+	
+	bool node_is_before(xml_node ln, unsigned int lh, xml_node rn, unsigned int rh)
+	{
+		// normalize heights
+		for (unsigned int i = rh; i < lh; i++) ln = ln.parent();
+		for (unsigned int j = lh; j < rh; j++) rn = rn.parent();
+	    
+		// one node is the ancestor of the other
+	    if (ln == rn) return lh < rh;
+	    
+		// find common ancestor
+	    while (ln.parent() != rn.parent())
+	    {
+	        ln = ln.parent();
+	        rn = rn.parent();
+	    }
+
+		// there is no common ancestor (the shared parent is null), nodes are from different documents
+		if (!ln.parent()) return ln < rn;
+
+		// determine sibling order
+        for (; ln; ln = ln.next_sibling())
+            if (ln == rn)
+                return true;
+                
+        return false;
+    }
+
+    bool node_is_ancestor(xml_node parent, xml_node node)
+    {
+    	while (node && node != parent) node = node.parent();
+
+    	return parent && node == parent;
+    }
+
+    const void* document_order(const xpath_node& xnode)
+    {
+        xml_node_struct* node = xnode.node().internal_object();
+
+        if (node)
+        {
+            if (node->name && (node->header & xml_memory_page_name_allocated_mask) == 0) return node->name;
+            if (node->value && (node->header & xml_memory_page_value_allocated_mask) == 0) return node->value;
+            return 0;
+        }
+
+        xml_attribute_struct* attr = xnode.attribute().internal_object();
+
+        if (attr)
+        {
+            if ((attr->header & xml_memory_page_name_allocated_mask) == 0) return attr->name;
+            if ((attr->header & xml_memory_page_value_allocated_mask) == 0) return attr->value;
+            return 0;
+        }
+
+		return 0;
+    }
+    
+	struct document_order_comparator
+	{
+		bool operator()(const xpath_node& lhs, const xpath_node& rhs) const
+		{
+			// optimized document order based check
+			const void* lo = document_order(lhs);
+			const void* ro = document_order(rhs);
+
+			if (lo && ro) return lo < ro;
+
+            // slow comparison
+			xml_node ln = lhs.node(), rn = rhs.node();
+
+			// compare attributes
+			if (lhs.attribute() && rhs.attribute())
+			{
+				// shared parent
+				if (lhs.parent() == rhs.parent())
+				{
+					// determine sibling order
+				    for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute())
+				        if (a == rhs.attribute())
+				            return true;
+				    
+				    return false;
+				}
+				
+				// compare attribute parents
+				ln = lhs.parent();
+				rn = rhs.parent();
+			}
+			else if (lhs.attribute())
+			{
+				// attributes go after the parent element
+				if (lhs.parent() == rhs.node()) return false;
+				
+				ln = lhs.parent();
+			}
+			else if (rhs.attribute())
+			{
+				// attributes go after the parent element
+				if (rhs.parent() == lhs.node()) return true;
+				
+				rn = rhs.parent();
+			}
+
+			if (ln == rn) return false;
+			
+			unsigned int lh = node_height(ln);
+			unsigned int rh = node_height(rn);
+			
+			return node_is_before(ln, lh, rn, rh);
+		}
+	};
+
+	struct duplicate_comparator
+	{
+		bool operator()(const xpath_node& lhs, const xpath_node& rhs) const
+		{
+			if (lhs.attribute()) return rhs.attribute() ? lhs.attribute() < rhs.attribute() : true;
+			else return rhs.attribute() ? false : lhs.node() < rhs.node();
+		}
+	};
+	
+	double gen_nan()
+	{
+	#if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24))
+		union { float f; int32_t i; } u[sizeof(float) == sizeof(int32_t) ? 1 : -1];
+		u[0].i = 0x7fc00000;
+		return u[0].f;
+	#else
+		// fallback
+		const volatile double zero = 0.0;
+		return zero / zero;
+	#endif
+	}
+	
+	bool is_nan(double value)
+	{
+	#if defined(_MSC_VER) || defined(__BORLANDC__)
+		return !!_isnan(value);
+	#elif defined(fpclassify) && defined(FP_NAN)
+		return fpclassify(value) == FP_NAN;
+	#else
+		// fallback
+		const volatile double v = value;
+		return v != v;
+	#endif
+	}
+	
+	const char_t* convert_number_to_string_special(double value)
+	{
+	#if defined(_MSC_VER) || defined(__BORLANDC__)
+		if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0;
+		if (_isnan(value)) return PUGIXML_TEXT("NaN");
+		return PUGIXML_TEXT("-Infinity") + (value > 0);
+	#elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO)
+		switch (fpclassify(value))
+		{
+		case FP_NAN:
+			return PUGIXML_TEXT("NaN");
+
+		case FP_INFINITE:
+			return PUGIXML_TEXT("-Infinity") + (value > 0);
+
+		case FP_ZERO:
+			return PUGIXML_TEXT("0");
+
+		default:
+			return 0;
+		}
+	#else
+		// fallback
+		const volatile double v = value;
+
+		if (v == 0) return PUGIXML_TEXT("0");
+		if (v != v) return PUGIXML_TEXT("NaN");
+		if (v * 2 == v) return PUGIXML_TEXT("-Infinity") + (value > 0);
+		return 0;
+	#endif
+	}
+	
+	bool convert_number_to_boolean(double value)
+	{
+		return (value != 0 && !is_nan(value));
+	}
+	
+	void truncate_zeros(char* begin, char* end)
+	{
+		while (begin != end && end[-1] == '0') end--;
+
+		*end = 0;
+	}
+
+	// gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+	void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent)
+	{
+		// get base values
+		int sign, exponent;
+		_ecvt_s(buffer, buffer_size, value, DBL_DIG + 1, &exponent, &sign);
+
+		// truncate redundant zeros
+		truncate_zeros(buffer, buffer + strlen(buffer));
+
+		// fill results
+		*out_mantissa = buffer;
+		*out_exponent = exponent;
+	}
+#else
+	void convert_number_to_mantissa_exponent(double value, char* buffer, size_t buffer_size, char** out_mantissa, int* out_exponent)
+	{
+		// get a scientific notation value with IEEE DBL_DIG decimals
+		sprintf(buffer, "%.*e", DBL_DIG, value);
+		assert(strlen(buffer) < buffer_size);
+		(void)!buffer_size;
+
+		// get the exponent (possibly negative)
+		char* exponent_string = strchr(buffer, 'e');
+		assert(exponent_string);
+
+		int exponent = atoi(exponent_string + 1);
+
+		// extract mantissa string: skip sign
+		char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer;
+		assert(mantissa[0] != '0' && mantissa[1] == '.');
+
+		// divide mantissa by 10 to eliminate integer part
+		mantissa[1] = mantissa[0];
+		mantissa++;
+		exponent++;
+
+		// remove extra mantissa digits and zero-terminate mantissa
+		truncate_zeros(mantissa, exponent_string);
+
+		// fill results
+		*out_mantissa = mantissa;
+		*out_exponent = exponent;
+	}
+#endif
+
+	xpath_string convert_number_to_string(double value, xpath_allocator* alloc)
+	{
+		// try special number conversion
+		const char_t* special = convert_number_to_string_special(value);
+		if (special) return xpath_string_const(special);
+
+		// get mantissa + exponent form
+		char mantissa_buffer[64];
+
+		char* mantissa;
+		int exponent;
+		convert_number_to_mantissa_exponent(value, mantissa_buffer, sizeof(mantissa_buffer), &mantissa, &exponent);
+
+		// make the number!
+		char_t result[512];
+		char_t* s = result;
+
+		// sign
+		if (value < 0) *s++ = '-';
+
+		// integer part
+		if (exponent <= 0)
+		{
+			*s++ = '0';
+		}
+		else
+		{
+			while (exponent > 0)
+			{
+				assert(*mantissa == 0 || (unsigned)(*mantissa - '0') <= 9);
+				*s++ = *mantissa ? *mantissa++ : '0';
+				exponent--;
+			}
+		}
+
+		// fractional part
+		if (*mantissa)
+		{
+			// decimal point
+			*s++ = '.';
+
+			// extra zeroes from negative exponent
+			while (exponent < 0)
+			{
+				*s++ = '0';
+				exponent++;
+			}
+
+			// extra mantissa digits
+			while (*mantissa)
+			{
+				assert((unsigned)(*mantissa - '0') <= 9);
+				*s++ = *mantissa++;
+			}
+		}
+
+		// zero-terminate
+		assert(s < result + sizeof(result) / sizeof(result[0]));
+		*s = 0;
+
+		return xpath_string(result, alloc);
+	}
+	
+	bool check_string_to_number_format(const char_t* string)
+	{
+		// parse leading whitespace
+		while (IS_CHARTYPE(*string, ct_space)) ++string;
+
+		// parse sign
+		if (*string == '-') ++string;
+
+		if (!*string) return false;
+
+		// if there is no integer part, there should be a decimal part with at least one digit
+		if (!IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !IS_CHARTYPEX(string[1], ctx_digit))) return false;
+
+		// parse integer part
+		while (IS_CHARTYPEX(*string, ctx_digit)) ++string;
+
+		// parse decimal part
+		if (*string == '.')
+		{
+			++string;
+
+			while (IS_CHARTYPEX(*string, ctx_digit)) ++string;
+		}
+
+		// parse trailing whitespace
+		while (IS_CHARTYPE(*string, ct_space)) ++string;
+
+		return *string == 0;
+	}
+
+	double convert_string_to_number(const char_t* string)
+	{
+		// check string format
+		if (!check_string_to_number_format(string)) return gen_nan();
+
+		// parse string
+	#ifdef PUGIXML_WCHAR_MODE
+		return wcstod(string, 0);
+	#else
+		return atof(string);
+	#endif
+	}
+
+	bool convert_string_to_number(const char_t* begin, const char_t* end, double* out_result)
+	{
+		char_t buffer[32];
+
+		size_t length = static_cast<size_t>(end - begin);
+		char_t* scratch = buffer;
+
+		if (length >= sizeof(buffer) / sizeof(buffer[0]))
+		{
+			// need to make dummy on-heap copy
+			scratch = static_cast<char_t*>(global_allocate((length + 1) * sizeof(char_t)));
+			if (!scratch) return false;
+		}
+
+		// copy string to zero-terminated buffer and perform conversion
+		memcpy(scratch, begin, length * sizeof(char_t));
+		scratch[length] = 0;
+
+		*out_result = convert_string_to_number(scratch);
+
+		// free dummy buffer
+		if (scratch != buffer) global_deallocate(scratch);
+
+		return true;
+	}
+	
+	double round_nearest(double value)
+	{
+		return floor(value + 0.5);
+	}
+
+	double round_nearest_nzero(double value)
+	{
+		// same as round_nearest, but returns -0 for [-0.5, -0]
+		// ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0)
+		return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5);
+	}
+	
+	const char_t* qualified_name(const xpath_node& node)
+	{
+		return node.attribute() ? node.attribute().name() : node.node().name();
+	}
+	
+	const char_t* local_name(const xpath_node& node)
+	{
+		const char_t* name = qualified_name(node);
+		const char_t* p = find_char(name, ':');
+		
+		return p ? p + 1 : name;
+	}
+
+	struct namespace_uri_predicate
+	{
+		const char_t* prefix;
+		size_t prefix_length;
+
+		namespace_uri_predicate(const char_t* name)
+		{
+			const char_t* pos = find_char(name, ':');
+
+			prefix = pos ? name : 0;
+			prefix_length = pos ? static_cast<size_t>(pos - name) : 0;
+		}
+
+		bool operator()(const xml_attribute& a) const
+		{
+			const char_t* name = a.name();
+
+			if (!starts_with(name, PUGIXML_TEXT("xmlns"))) return false;
+
+			return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0;
+		}
+	};
+
+	const char_t* namespace_uri(const xml_node& node)
+	{
+		namespace_uri_predicate pred = node.name();
+		
+		xml_node p = node;
+		
+		while (p)
+		{
+			xml_attribute a = p.find_attribute(pred);
+			
+			if (a) return a.value();
+			
+			p = p.parent();
+		}
+		
+		return PUGIXML_TEXT("");
+	}
+
+	const char_t* namespace_uri(const xml_attribute& attr, const xml_node& parent)
+	{
+		namespace_uri_predicate pred = attr.name();
+		
+		// Default namespace does not apply to attributes
+		if (!pred.prefix) return PUGIXML_TEXT("");
+		
+		xml_node p = parent;
+		
+		while (p)
+		{
+			xml_attribute a = p.find_attribute(pred);
+			
+			if (a) return a.value();
+			
+			p = p.parent();
+		}
+		
+		return PUGIXML_TEXT("");
+	}
+
+	const char_t* namespace_uri(const xpath_node& node)
+	{
+		return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node());
+	}
+
+	void normalize_space(char_t* buffer)
+	{
+		char_t* write = buffer;
+
+		for (char_t* it = buffer; *it; )
+		{
+			char_t ch = *it++;
+
+			if (IS_CHARTYPE(ch, ct_space))
+			{
+				// replace whitespace sequence with single space
+				while (IS_CHARTYPE(*it, ct_space)) it++;
+
+				// avoid leading spaces
+				if (write != buffer) *write++ = ' ';
+			}
+			else *write++ = ch;
+		}
+
+		// remove trailing space
+		if (write != buffer && IS_CHARTYPE(write[-1], ct_space)) write--;
+
+		// zero-terminate
+		*write = 0;
+	}
+
+	void translate(char_t* buffer, const char_t* from, const char_t* to)
+	{
+		size_t to_length = strlength(to);
+
+		char_t* write = buffer;
+
+		while (*buffer)
+		{
+			DMC_VOLATILE char_t ch = *buffer++;
+
+			const char_t* pos = find_char(from, ch);
+
+			if (!pos)
+				*write++ = ch; // do not process
+			else if (static_cast<size_t>(pos - from) < to_length)
+				*write++ = to[pos - from]; // replace
+		}
+
+		// zero-terminate
+		*write = 0;
+	}
+
+	struct xpath_variable_boolean: xpath_variable
+	{
+		xpath_variable_boolean(): value(false)
+		{
+		}
+
+		bool value;
+		char_t name[1];
+	};
+
+	struct xpath_variable_number: xpath_variable
+	{
+		xpath_variable_number(): value(0)
+		{
+		}
+
+		double value;
+		char_t name[1];
+	};
+
+	struct xpath_variable_string: xpath_variable
+	{
+		xpath_variable_string(): value(0)
+		{
+		}
+
+		~xpath_variable_string()
+		{
+			if (value) global_deallocate(value);
+		}
+
+		char_t* value;
+		char_t name[1];
+	};
+
+	struct xpath_variable_node_set: xpath_variable
+	{
+		xpath_node_set value;
+		char_t name[1];
+	};
+
+	const xpath_node_set dummy_node_set;
+
+	unsigned int hash_string(const char_t* str)
+	{
+		// Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time)
+		unsigned int result = 0;
+
+		while (*str)
+		{
+			result += static_cast<unsigned int>(*str++);
+			result += result << 10;
+			result ^= result >> 6;
+		}
+	
+		result += result << 3;
+		result ^= result >> 11;
+		result += result << 15;
+	
+		return result;
+	}
+
+	template <typename T> T* new_xpath_variable(const char_t* name)
+	{
+		size_t length = strlength(name);
+		if (length == 0) return 0; // empty variable names are invalid
+
+		// $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters
+		void* memory = global_allocate(sizeof(T) + length * sizeof(char_t));
+		if (!memory) return 0;
+
+		T* result = new (memory) T();
+
+		memcpy(result->name, name, (length + 1) * sizeof(char_t));
+
+		return result;
+	}
+
+	xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name)
+	{
+		switch (type)
+		{
+		case xpath_type_node_set:
+			return new_xpath_variable<xpath_variable_node_set>(name);
+
+		case xpath_type_number:
+			return new_xpath_variable<xpath_variable_number>(name);
+
+		case xpath_type_string:
+			return new_xpath_variable<xpath_variable_string>(name);
+
+		case xpath_type_boolean:
+			return new_xpath_variable<xpath_variable_boolean>(name);
+
+		default:
+			return 0;
+		}
+	}
+
+	template <typename T> void delete_xpath_variable(T* var)
+	{
+		var->~T();
+		global_deallocate(var);
+	}
+
+	void delete_xpath_variable(xpath_value_type type, xpath_variable* var)
+	{
+		switch (type)
+		{
+		case xpath_type_node_set:
+			delete_xpath_variable(static_cast<xpath_variable_node_set*>(var));
+			break;
+
+		case xpath_type_number:
+			delete_xpath_variable(static_cast<xpath_variable_number*>(var));
+			break;
+
+		case xpath_type_string:
+			delete_xpath_variable(static_cast<xpath_variable_string*>(var));
+			break;
+
+		case xpath_type_boolean:
+			delete_xpath_variable(static_cast<xpath_variable_boolean*>(var));
+			break;
+
+		default:
+			assert(!"Invalid variable type");
+		}
+	}
+
+	xpath_variable* get_variable(xpath_variable_set* set, const char_t* begin, const char_t* end)
+	{
+		char_t buffer[32];
+
+		size_t length = static_cast<size_t>(end - begin);
+		char_t* scratch = buffer;
+
+		if (length >= sizeof(buffer) / sizeof(buffer[0]))
+		{
+			// need to make dummy on-heap copy
+			scratch = static_cast<char_t*>(global_allocate((length + 1) * sizeof(char_t)));
+			if (!scratch) return 0;
+		}
+
+		// copy string to zero-terminated buffer and perform lookup
+		memcpy(scratch, begin, length * sizeof(char_t));
+		scratch[length] = 0;
+
+		xpath_variable* result = set->get(scratch);
+
+		// free dummy buffer
+		if (scratch != buffer) global_deallocate(scratch);
+
+		return result;
+	}
+}
+
+// Internal node set class
+namespace
+{
+	xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev)
+	{
+		xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
+
+		if (type == xpath_node_set::type_unsorted)
+		{
+			sort(begin, end, document_order_comparator());
+
+			type = xpath_node_set::type_sorted;
+		}
+		
+		if (type != order) reverse(begin, end);
+			
+		return order;
+	}
+
+	xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type)
+	{
+		if (begin == end) return xpath_node();
+
+		switch (type)
+		{
+		case xpath_node_set::type_sorted:
+			return *begin;
+
+		case xpath_node_set::type_sorted_reverse:
+			return *(end - 1);
+
+		case xpath_node_set::type_unsorted:
+			return *min_element(begin, end, document_order_comparator());
+
+		default:
+			assert(!"Invalid node set type");
+			return xpath_node();
+		}
+	}
+	class xpath_node_set_raw
+	{
+		xpath_node_set::type_t _type;
+
+		xpath_node* _begin;
+		xpath_node* _end;
+		xpath_node* _eos;
+
+	public:
+		xpath_node_set_raw(): _type(xpath_node_set::type_unsorted), _begin(0), _end(0), _eos(0)
+		{
+		}
+
+		xpath_node* begin() const
+		{
+			return _begin;
+		}
+
+		xpath_node* end() const
+		{
+			return _end;
+		}
+
+		bool empty() const
+		{
+			return _begin == _end;
+		}
+
+		size_t size() const
+		{
+			return static_cast<size_t>(_end - _begin);
+		}
+
+		xpath_node first() const
+		{
+			return xpath_first(_begin, _end, _type);
+		}
+
+		void push_back(const xpath_node& node, xpath_allocator* alloc)
+		{
+			if (_end == _eos)
+			{
+				size_t capacity = static_cast<size_t>(_eos - _begin);
+
+				// get new capacity (1.5x rule)
+				size_t new_capacity = capacity + capacity / 2 + 1;
+
+				// reallocate the old array or allocate a new one
+				xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), new_capacity * sizeof(xpath_node)));
+				assert(data);
+
+				// finalize
+				_begin = data;
+				_end = data + capacity;
+				_eos = data + new_capacity;
+			}
+
+			*_end++ = node;
+		}
+
+		void append(const xpath_node* begin, const xpath_node* end, xpath_allocator* alloc)
+		{
+			size_t size = static_cast<size_t>(_end - _begin);
+			size_t capacity = static_cast<size_t>(_eos - _begin);
+			size_t count = static_cast<size_t>(end - begin);
+
+			if (size + count > capacity)
+			{
+				// reallocate the old array or allocate a new one
+				xpath_node* data = static_cast<xpath_node*>(alloc->reallocate(_begin, capacity * sizeof(xpath_node), (size + count) * sizeof(xpath_node)));
+				assert(data);
+
+				// finalize
+				_begin = data;
+				_end = data + size;
+				_eos = data + size + count;
+			}
+
+			memcpy(_end, begin, count * sizeof(xpath_node));
+			_end += count;
+		}
+
+		void sort_do()
+		{
+			_type = xpath_sort(_begin, _end, _type, false);
+		}
+
+		void truncate(xpath_node* pos)
+		{
+			assert(_begin <= pos && pos <= _end);
+
+			_end = pos;
+		}
+
+		void remove_duplicates()
+		{
+			if (_type == xpath_node_set::type_unsorted)
+				sort(_begin, _end, duplicate_comparator());
+		
+			_end = unique(_begin, _end);
+		}
+
+		xpath_node_set::type_t type() const
+		{
+			return _type;
+		}
+
+		void set_type(xpath_node_set::type_t type)
+		{
+			_type = type;
+		}
+	};
+}
+
+namespace
+{
+	struct xpath_context
+	{
+		xpath_node n;
+		size_t position, size;
+
+		xpath_context(const xpath_node& n, size_t position, size_t size): n(n), position(position), size(size)
+		{
+		}
+	};
+
+	enum lexeme_t
+	{
+		lex_none = 0,
+		lex_equal,
+		lex_not_equal,
+		lex_less,
+		lex_greater,
+		lex_less_or_equal,
+		lex_greater_or_equal,
+		lex_plus,
+		lex_minus,
+		lex_multiply,
+		lex_union,
+		lex_var_ref,
+		lex_open_brace,
+		lex_close_brace,
+		lex_quoted_string,
+		lex_number,
+		lex_slash,
+		lex_double_slash,
+		lex_open_square_brace,
+		lex_close_square_brace,
+		lex_string,
+		lex_comma,
+		lex_axis_attribute,
+		lex_dot,
+		lex_double_dot,
+		lex_double_colon,
+		lex_eof
+	};
+
+	struct xpath_lexer_string
+	{
+		const char_t* begin;
+		const char_t* end;
+
+		xpath_lexer_string(): begin(0), end(0)
+		{
+		}
+
+		bool operator==(const char_t* other) const
+		{
+			size_t length = static_cast<size_t>(end - begin);
+
+			return strequalrange(other, begin, length);
+		}
+	};
+
+	class xpath_lexer
+	{
+		const char_t* _cur;
+		const char_t* _cur_lexeme_pos;
+		xpath_lexer_string _cur_lexeme_contents;
+
+		lexeme_t _cur_lexeme;
+
+	public:
+		explicit xpath_lexer(const char_t* query): _cur(query)
+		{
+			next();
+		}
+		
+		const char_t* state() const
+		{
+			return _cur;
+		}
+		
+		void next()
+		{
+			const char_t* cur = _cur;
+
+			while (IS_CHARTYPE(*cur, ct_space)) ++cur;
+
+			// save lexeme position for error reporting
+			_cur_lexeme_pos = cur;
+
+			switch (*cur)
+			{
+			case 0:
+				_cur_lexeme = lex_eof;
+				break;
+			
+			case '>':
+				if (*(cur+1) == '=')
+				{
+					cur += 2;
+					_cur_lexeme = lex_greater_or_equal;
+				}
+				else
+				{
+					cur += 1;
+					_cur_lexeme = lex_greater;
+				}
+				break;
+
+			case '<':
+				if (*(cur+1) == '=')
+				{
+					cur += 2;
+					_cur_lexeme = lex_less_or_equal;
+				}
+				else
+				{
+					cur += 1;
+					_cur_lexeme = lex_less;
+				}
+				break;
+
+			case '!':
+				if (*(cur+1) == '=')
+				{
+					cur += 2;
+					_cur_lexeme = lex_not_equal;
+				}
+				else
+				{
+					_cur_lexeme = lex_none;
+				}
+				break;
+
+			case '=':
+				cur += 1;
+				_cur_lexeme = lex_equal;
+
+				break;
+			
+			case '+':
+				cur += 1;
+				_cur_lexeme = lex_plus;
+
+				break;
+
+			case '-':
+				cur += 1;
+				_cur_lexeme = lex_minus;
+
+				break;
+
+			case '*':
+				cur += 1;
+				_cur_lexeme = lex_multiply;
+
+				break;
+
+			case '|':
+				cur += 1;
+				_cur_lexeme = lex_union;
+
+				break;
+			
+			case '$':
+				cur += 1;
+
+				if (IS_CHARTYPEX(*cur, ctx_start_symbol))
+				{
+					_cur_lexeme_contents.begin = cur;
+
+					while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
+
+					if (cur[0] == ':' && IS_CHARTYPEX(cur[1], ctx_symbol)) // qname
+					{
+						cur++; // :
+
+						while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
+					}
+
+					_cur_lexeme_contents.end = cur;
+				
+					_cur_lexeme = lex_var_ref;
+				}
+				else
+				{
+					_cur_lexeme = lex_none;
+				}
+
+				break;
+
+			case '(':
+				cur += 1;
+				_cur_lexeme = lex_open_brace;
+
+				break;
+
+			case ')':
+				cur += 1;
+				_cur_lexeme = lex_close_brace;
+
+				break;
+			
+			case '[':
+				cur += 1;
+				_cur_lexeme = lex_open_square_brace;
+
+				break;
+
+			case ']':
+				cur += 1;
+				_cur_lexeme = lex_close_square_brace;
+
+				break;
+
+			case ',':
+				cur += 1;
+				_cur_lexeme = lex_comma;
+
+				break;
+
+			case '/':
+				if (*(cur+1) == '/')
+				{
+					cur += 2;
+					_cur_lexeme = lex_double_slash;
+				}
+				else
+				{
+					cur += 1;
+					_cur_lexeme = lex_slash;
+				}
+				break;
+		
+			case '.':
+				if (*(cur+1) == '.')
+				{
+					cur += 2;
+					_cur_lexeme = lex_double_dot;
+				}
+				else if (IS_CHARTYPEX(*(cur+1), ctx_digit))
+				{
+					_cur_lexeme_contents.begin = cur; // .
+
+					++cur;
+
+					while (IS_CHARTYPEX(*cur, ctx_digit)) cur++;
+
+					_cur_lexeme_contents.end = cur;
+					
+					_cur_lexeme = lex_number;
+				}
+				else
+				{
+					cur += 1;
+					_cur_lexeme = lex_dot;
+				}
+				break;
+
+			case '@':
+				cur += 1;
+				_cur_lexeme = lex_axis_attribute;
+
+				break;
+
+			case '"':
+			case '\'':
+			{
+				char_t terminator = *cur;
+
+				++cur;
+
+				_cur_lexeme_contents.begin = cur;
+				while (*cur && *cur != terminator) cur++;
+				_cur_lexeme_contents.end = cur;
+				
+				if (!*cur)
+					_cur_lexeme = lex_none;
+				else
+				{
+					cur += 1;
+					_cur_lexeme = lex_quoted_string;
+				}
+
+				break;
+			}
+
+			case ':':
+				if (*(cur+1) == ':')
+				{
+					cur += 2;
+					_cur_lexeme = lex_double_colon;
+				}
+				else
+				{
+					_cur_lexeme = lex_none;
+				}
+				break;
+
+			default:
+				if (IS_CHARTYPEX(*cur, ctx_digit))
+				{
+					_cur_lexeme_contents.begin = cur;
+
+					while (IS_CHARTYPEX(*cur, ctx_digit)) cur++;
+				
+					if (*cur == '.')
+					{
+						cur++;
+
+						while (IS_CHARTYPEX(*cur, ctx_digit)) cur++;
+					}
+
+					_cur_lexeme_contents.end = cur;
+
+					_cur_lexeme = lex_number;
+				}
+				else if (IS_CHARTYPEX(*cur, ctx_start_symbol))
+				{
+					_cur_lexeme_contents.begin = cur;
+
+					while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
+
+					if (cur[0] == ':')
+					{
+						if (cur[1] == '*') // namespace test ncname:*
+						{
+							cur += 2; // :*
+						}
+						else if (IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname
+						{
+							cur++; // :
+
+							while (IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
+						}
+					}
+
+					_cur_lexeme_contents.end = cur;
+				
+					_cur_lexeme = lex_string;
+				}
+				else
+				{
+					_cur_lexeme = lex_none;
+				}
+			}
+
+			_cur = cur;
+		}
+
+		lexeme_t current() const
+		{
+			return _cur_lexeme;
+		}
+
+		const char_t* current_pos() const
+		{
+			return _cur_lexeme_pos;
+		}
+
+		const xpath_lexer_string& contents() const
+		{
+			assert(_cur_lexeme == lex_var_ref || _cur_lexeme == lex_number || _cur_lexeme == lex_string || _cur_lexeme == lex_quoted_string);
+
+			return _cur_lexeme_contents;
+		}
+	};
+
+	enum ast_type_t
+	{
+		ast_op_or,						// left or right
+		ast_op_and,						// left and right
+		ast_op_equal,					// left = right
+		ast_op_not_equal, 				// left != right
+		ast_op_less,					// left < right
+		ast_op_greater,					// left > right
+		ast_op_less_or_equal,			// left <= right
+		ast_op_greater_or_equal,		// left >= right
+		ast_op_add,						// left + right
+		ast_op_subtract,				// left - right
+		ast_op_multiply,				// left * right
+		ast_op_divide,					// left / right
+		ast_op_mod,						// left % right
+		ast_op_negate,					// left - right
+		ast_op_union,					// left | right
+		ast_predicate,					// apply predicate to set; next points to next predicate
+		ast_filter,						// select * from left where right
+		ast_filter_posinv,				// select * from left where right; proximity position invariant
+		ast_string_constant,			// string constant
+		ast_number_constant,			// number constant
+		ast_variable,					// variable
+		ast_func_last,					// last()
+		ast_func_position,				// position()
+		ast_func_count,					// count(left)
+		ast_func_id,					// id(left)
+		ast_func_local_name_0,			// local-name()
+		ast_func_local_name_1,			// local-name(left)
+		ast_func_namespace_uri_0,		// namespace-uri()
+		ast_func_namespace_uri_1,		// namespace-uri(left)
+		ast_func_name_0,				// name()
+		ast_func_name_1,				// name(left)
+		ast_func_string_0,				// string()
+		ast_func_string_1,				// string(left)
+		ast_func_concat,				// concat(left, right, siblings)
+		ast_func_starts_with,			// starts_with(left, right)
+		ast_func_contains,				// contains(left, right)
+		ast_func_substring_before,		// substring-before(left, right)
+		ast_func_substring_after,		// substring-after(left, right)
+		ast_func_substring_2,			// substring(left, right)
+		ast_func_substring_3,			// substring(left, right, third)
+		ast_func_string_length_0,		// string-length()
+		ast_func_string_length_1,		// string-length(left)
+		ast_func_normalize_space_0,		// normalize-space()
+		ast_func_normalize_space_1,		// normalize-space(left)
+		ast_func_translate,				// translate(left, right, third)
+		ast_func_boolean,				// boolean(left)
+		ast_func_not,					// not(left)
+		ast_func_true,					// true()
+		ast_func_false,					// false()
+		ast_func_lang,					// lang(left)
+		ast_func_number_0,				// number()
+		ast_func_number_1,				// number(left)
+		ast_func_sum,					// sum(left)
+		ast_func_floor,					// floor(left)
+		ast_func_ceiling,				// ceiling(left)
+		ast_func_round,					// round(left)
+		ast_step,						// process set left with step
+		ast_step_root					// select root node
+	};
+
+	enum axis_t
+	{
+		axis_ancestor,
+		axis_ancestor_or_self,
+		axis_attribute,
+		axis_child,
+		axis_descendant,
+		axis_descendant_or_self,
+		axis_following,
+		axis_following_sibling,
+		axis_namespace,
+		axis_parent,
+		axis_preceding,
+		axis_preceding_sibling,
+		axis_self
+	};
+	
+	enum nodetest_t
+	{
+		nodetest_none,
+		nodetest_name,
+		nodetest_type_node,
+		nodetest_type_comment,
+		nodetest_type_pi,
+		nodetest_type_text,
+		nodetest_pi,
+		nodetest_all,
+		nodetest_all_in_namespace
+	};
+
+	template <axis_t N> struct axis_to_type
+	{
+		static const axis_t axis;
+	};
+
+	template <axis_t N> const axis_t axis_to_type<N>::axis = N;
+		
+	class xpath_ast_node
+	{
+	private:
+		// node type
+		char _type;
+		char _rettype;
+
+		// for ast_step / ast_predicate
+		char _axis;
+		char _test;
+
+		// tree node structure
+		xpath_ast_node* _left;
+		xpath_ast_node* _right;
+		xpath_ast_node* _next;
+
+		union
+		{
+			// value for ast_string_constant
+			const char_t* string;
+			// value for ast_number_constant
+			double number;
+			// variable for ast_variable
+			xpath_variable* variable;
+			// node test for ast_step (node name/namespace/node type/pi target)
+			const char_t* nodetest;
+		} _data;
+
+		xpath_ast_node(const xpath_ast_node&);
+		xpath_ast_node& operator=(const xpath_ast_node&);
+
+		template <class Comp> static bool compare_eq(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp)
+		{
+			xpath_value_type lt = lhs->rettype(), rt = rhs->rettype();
+
+			if (lt != xpath_type_node_set && rt != xpath_type_node_set)
+			{
+				if (lt == xpath_type_boolean || rt == xpath_type_boolean)
+					return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack));
+				else if (lt == xpath_type_number || rt == xpath_type_number)
+					return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack));
+				else if (lt == xpath_type_string || rt == xpath_type_string)
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					xpath_string ls = lhs->eval_string(c, stack);
+					xpath_string rs = rhs->eval_string(c, stack);
+
+					return comp(ls, rs);
+				}
+			}
+			else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
+				xpath_node_set_raw rs = rhs->eval_node_set(c, stack);
+
+				for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
+					for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
+					{
+						xpath_allocator_capture cri(stack.result);
+
+						if (comp(string_value(*li, stack.result), string_value(*ri, stack.result)))
+							return true;
+					}
+
+				return false;
+			}
+			else
+			{
+				if (lt == xpath_type_node_set)
+				{
+					swap(lhs, rhs);
+					swap(lt, rt);
+				}
+
+				if (lt == xpath_type_boolean)
+					return comp(lhs->eval_boolean(c, stack), rhs->eval_boolean(c, stack));
+				else if (lt == xpath_type_number)
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					double l = lhs->eval_number(c, stack);
+					xpath_node_set_raw rs = rhs->eval_node_set(c, stack);
+
+					for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
+					{
+						xpath_allocator_capture cri(stack.result);
+
+						if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
+							return true;
+					}
+
+					return false;
+				}
+				else if (lt == xpath_type_string)
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					xpath_string l = lhs->eval_string(c, stack);
+					xpath_node_set_raw rs = rhs->eval_node_set(c, stack);
+
+					for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
+					{
+						xpath_allocator_capture cri(stack.result);
+
+						if (comp(l, string_value(*ri, stack.result)))
+							return true;
+					}
+
+					return false;
+				}
+			}
+
+			assert(!"Wrong types");
+			return false;
+		}
+
+		template <class Comp> static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp)
+		{
+			xpath_value_type lt = lhs->rettype(), rt = rhs->rettype();
+
+			if (lt != xpath_type_node_set && rt != xpath_type_node_set)
+				return comp(lhs->eval_number(c, stack), rhs->eval_number(c, stack));
+			else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
+				xpath_node_set_raw rs = rhs->eval_node_set(c, stack);
+
+				for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
+				{
+					xpath_allocator_capture cri(stack.result);
+
+					double l = convert_string_to_number(string_value(*li, stack.result).c_str());
+
+					for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
+					{
+						xpath_allocator_capture crii(stack.result);
+
+						if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
+							return true;
+					}
+				}
+
+				return false;
+			}
+			else if (lt != xpath_type_node_set && rt == xpath_type_node_set)
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				double l = lhs->eval_number(c, stack);
+				xpath_node_set_raw rs = rhs->eval_node_set(c, stack);
+
+				for (const xpath_node* ri = rs.begin(); ri != rs.end(); ++ri)
+				{
+					xpath_allocator_capture cri(stack.result);
+
+					if (comp(l, convert_string_to_number(string_value(*ri, stack.result).c_str())))
+						return true;
+				}
+
+				return false;
+			}
+			else if (lt == xpath_type_node_set && rt != xpath_type_node_set)
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ls = lhs->eval_node_set(c, stack);
+				double r = rhs->eval_number(c, stack);
+
+				for (const xpath_node* li = ls.begin(); li != ls.end(); ++li)
+				{
+					xpath_allocator_capture cri(stack.result);
+
+					if (comp(convert_string_to_number(string_value(*li, stack.result).c_str()), r))
+						return true;
+				}
+
+				return false;
+			}
+			else
+			{
+				assert(!"Wrong types");
+				return false;
+			}
+		}
+
+		void apply_predicate(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack)
+		{
+			assert(ns.size() >= first);
+
+			size_t i = 1;
+			size_t size = ns.size() - first;
+				
+			xpath_node* last = ns.begin() + first;
+				
+			// remove_if... or well, sort of
+			for (xpath_node* it = last; it != ns.end(); ++it, ++i)
+			{
+				xpath_context c(*it, i, size);
+			
+				if (expr->rettype() == xpath_type_number)
+				{
+					if (expr->eval_number(c, stack) == i)
+						*last++ = *it;
+				}
+				else if (expr->eval_boolean(c, stack))
+					*last++ = *it;
+			}
+			
+			ns.truncate(last);
+		}
+
+		void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack)
+		{
+			if (ns.size() == first) return;
+			
+			for (xpath_ast_node* pred = _right; pred; pred = pred->_next)
+			{
+				apply_predicate(ns, first, pred->_left, stack);
+			}
+		}
+
+		void step_push(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& parent, xpath_allocator* alloc)
+		{
+			if (!a) return;
+
+			const char_t* name = a.name();
+
+			// There are no attribute nodes corresponding to attributes that declare namespaces
+			// That is, "xmlns:..." or "xmlns"
+			if (starts_with(name, PUGIXML_TEXT("xmlns")) && (name[5] == 0 || name[5] == ':')) return;
+			
+			switch (_test)
+			{
+			case nodetest_name:
+				if (strequal(name, _data.nodetest)) ns.push_back(xpath_node(a, parent), alloc);
+				break;
+				
+			case nodetest_type_node:
+			case nodetest_all:
+				ns.push_back(xpath_node(a, parent), alloc);
+				break;
+				
+			case nodetest_all_in_namespace:
+				if (starts_with(name, _data.nodetest))
+					ns.push_back(xpath_node(a, parent), alloc);
+				break;
+			
+			default:
+				;
+			}
+		}
+		
+		void step_push(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc)
+		{
+			if (!n) return;
+
+			switch (_test)
+			{
+			case nodetest_name:
+				if (n.type() == node_element && strequal(n.name(), _data.nodetest)) ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_type_node:
+				ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_type_comment:
+				if (n.type() == node_comment)
+					ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_type_text:
+				if (n.type() == node_pcdata || n.type() == node_cdata)
+					ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_type_pi:
+				if (n.type() == node_pi)
+					ns.push_back(n, alloc);
+				break;
+									
+			case nodetest_pi:
+				if (n.type() == node_pi && strequal(n.name(), _data.nodetest))
+					ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_all:
+				if (n.type() == node_element)
+					ns.push_back(n, alloc);
+				break;
+				
+			case nodetest_all_in_namespace:
+				if (n.type() == node_element && starts_with(n.name(), _data.nodetest))
+					ns.push_back(n, alloc);
+				break;
+
+			default:
+				assert(!"Unknown axis");
+			} 
+		}
+
+		template <class T> void step_fill(xpath_node_set_raw& ns, const xml_node& n, xpath_allocator* alloc, T)
+		{
+			const axis_t axis = T::axis;
+
+			switch (axis)
+			{
+			case axis_attribute:
+			{
+				for (xml_attribute a = n.first_attribute(); a; a = a.next_attribute())
+					step_push(ns, a, n, alloc);
+				
+				break;
+			}
+			
+			case axis_child:
+			{
+				for (xml_node c = n.first_child(); c; c = c.next_sibling())
+					step_push(ns, c, alloc);
+					
+				break;
+			}
+			
+			case axis_descendant:
+			case axis_descendant_or_self:
+			{
+				if (axis == axis_descendant_or_self)
+					step_push(ns, n, alloc);
+					
+				xml_node cur = n.first_child();
+				
+				while (cur && cur != n)
+				{
+					step_push(ns, cur, alloc);
+					
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
+					{
+						while (!cur.next_sibling() && cur != n)
+							cur = cur.parent();
+					
+						if (cur != n) cur = cur.next_sibling();
+					}
+				}
+				
+				break;
+			}
+			
+			case axis_following_sibling:
+			{
+				for (xml_node c = n.next_sibling(); c; c = c.next_sibling())
+					step_push(ns, c, alloc);
+				
+				break;
+			}
+			
+			case axis_preceding_sibling:
+			{
+				for (xml_node c = n.previous_sibling(); c; c = c.previous_sibling())
+					step_push(ns, c, alloc);
+				
+				break;
+			}
+			
+			case axis_following:
+			{
+				xml_node cur = n;
+
+				// exit from this node so that we don't include descendants
+				while (cur && !cur.next_sibling()) cur = cur.parent();
+				cur = cur.next_sibling();
+
+				for (;;)
+				{
+					step_push(ns, cur, alloc);
+
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
+					{
+						while (cur && !cur.next_sibling()) cur = cur.parent();
+						cur = cur.next_sibling();
+
+						if (!cur) break;
+					}
+				}
+
+				break;
+			}
+
+			case axis_preceding:
+			{
+				xml_node cur = n;
+
+				while (cur && !cur.previous_sibling()) cur = cur.parent();
+				cur = cur.previous_sibling();
+
+				for (;;)
+				{
+					if (cur.last_child())
+						cur = cur.last_child();
+					else
+					{
+						// leaf node, can't be ancestor
+						step_push(ns, cur, alloc);
+
+						if (cur.previous_sibling())
+							cur = cur.previous_sibling();
+						else
+						{
+							do 
+							{
+								cur = cur.parent();
+								if (!cur) break;
+
+								if (!node_is_ancestor(cur, n)) step_push(ns, cur, alloc);
+							}
+							while (!cur.previous_sibling());
+
+							cur = cur.previous_sibling();
+
+							if (!cur) break;
+						}
+					}
+				}
+
+				break;
+			}
+			
+			case axis_ancestor:
+			case axis_ancestor_or_self:
+			{
+				if (axis == axis_ancestor_or_self)
+					step_push(ns, n, alloc);
+
+				xml_node cur = n.parent();
+				
+				while (cur)
+				{
+					step_push(ns, cur, alloc);
+					
+					cur = cur.parent();
+				}
+				
+				break;
+			}
+
+			case axis_self:
+			{
+				step_push(ns, n, alloc);
+
+				break;
+			}
+
+			case axis_parent:
+			{
+				if (n.parent()) step_push(ns, n.parent(), alloc);
+
+				break;
+			}
+				
+			default:
+				assert(!"Unimplemented axis");
+			}
+		}
+		
+		template <class T> void step_fill(xpath_node_set_raw& ns, const xml_attribute& a, const xml_node& p, xpath_allocator* alloc, T v)
+		{
+			const axis_t axis = T::axis;
+
+			switch (axis)
+			{
+			case axis_ancestor:
+			case axis_ancestor_or_self:
+			{
+				if (axis == axis_ancestor_or_self && _test == nodetest_type_node) // reject attributes based on principal node type test
+					step_push(ns, a, p, alloc);
+
+				xml_node cur = p;
+				
+				while (cur)
+				{
+					step_push(ns, cur, alloc);
+					
+					cur = cur.parent();
+				}
+				
+				break;
+			}
+
+			case axis_descendant_or_self:
+			case axis_self:
+			{
+				if (_test == nodetest_type_node) // reject attributes based on principal node type test
+					step_push(ns, a, p, alloc);
+
+				break;
+			}
+
+			case axis_following:
+			{
+				xml_node cur = p;
+				
+				for (;;)
+				{
+					if (cur.first_child())
+						cur = cur.first_child();
+					else if (cur.next_sibling())
+						cur = cur.next_sibling();
+					else
+					{
+						while (cur && !cur.next_sibling()) cur = cur.parent();
+						cur = cur.next_sibling();
+						
+						if (!cur) break;
+					}
+
+					step_push(ns, cur, alloc);
+				}
+
+				break;
+			}
+
+			case axis_parent:
+			{
+				step_push(ns, p, alloc);
+
+				break;
+			}
+
+			case axis_preceding:
+			{
+				// preceding:: axis does not include attribute nodes and attribute ancestors (they are the same as parent's ancestors), so we can reuse node preceding
+				step_fill(ns, p, alloc, v);
+				break;
+			}
+			
+			default:
+				assert(!"Unimplemented axis");
+			}
+		}
+		
+		template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, T v)
+		{
+			const axis_t axis = T::axis;
+			bool attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self);
+
+			xpath_node_set_raw ns;
+			ns.set_type((axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling) ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted);
+
+			if (_left)
+			{
+				xpath_node_set_raw s = _left->eval_node_set(c, stack);
+
+				// self axis preserves the original order
+				if (axis == axis_self) ns.set_type(s.type());
+
+				for (const xpath_node* it = s.begin(); it != s.end(); ++it)
+				{
+					size_t size = ns.size();
+
+					// in general, all axes generate elements in a particular order, but there is no order guarantee if axis is applied to two nodes
+					if (axis != axis_self && size != 0) ns.set_type(xpath_node_set::type_unsorted);
+					
+					if (it->node())
+						step_fill(ns, it->node(), stack.result, v);
+					else if (attributes)
+						step_fill(ns, it->attribute(), it->parent(), stack.result, v);
+						
+					apply_predicates(ns, size, stack);
+				}
+			}
+			else
+			{
+				if (c.n.node())
+					step_fill(ns, c.n.node(), stack.result, v);
+				else if (attributes)
+					step_fill(ns, c.n.attribute(), c.n.parent(), stack.result, v);
+				
+				apply_predicates(ns, 0, stack);
+			}
+
+			// child, attribute and self axes always generate unique set of nodes
+			// for other axis, if the set stayed sorted, it stayed unique because the traversal algorithms do not visit the same node twice
+			if (axis != axis_child && axis != axis_attribute && axis != axis_self && ns.type() == xpath_node_set::type_unsorted)
+				ns.remove_duplicates();
+
+			return ns;
+		}
+		
+	public:
+		xpath_ast_node(ast_type_t type, xpath_value_type rettype, const char_t* value):
+			_type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0)
+		{
+			assert(type == ast_string_constant);
+			_data.string = value;
+		}
+
+		xpath_ast_node(ast_type_t type, xpath_value_type rettype, double value):
+			_type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0)
+		{
+			assert(type == ast_number_constant);
+			_data.number = value;
+		}
+		
+		xpath_ast_node(ast_type_t type, xpath_value_type rettype, xpath_variable* value):
+			_type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(0), _right(0), _next(0)
+		{
+			assert(type == ast_variable);
+			_data.variable = value;
+		}
+		
+		xpath_ast_node(ast_type_t type, xpath_value_type rettype, xpath_ast_node* left = 0, xpath_ast_node* right = 0):
+			_type((char)type), _rettype((char)rettype), _axis(0), _test(0), _left(left), _right(right), _next(0)
+		{
+		}
+
+		xpath_ast_node(ast_type_t type, xpath_ast_node* left, axis_t axis, nodetest_t test, const char_t* contents):
+			_type((char)type), _rettype(xpath_type_node_set), _axis((char)axis), _test((char)test), _left(left), _right(0), _next(0)
+		{
+			_data.nodetest = contents;
+		}
+
+		void set_next(xpath_ast_node* value)
+		{
+			_next = value;
+		}
+
+		void set_right(xpath_ast_node* value)
+		{
+			_right = value;
+		}
+
+		bool eval_boolean(const xpath_context& c, const xpath_stack& stack)
+		{
+			switch (_type)
+			{
+			case ast_op_or:
+				return _left->eval_boolean(c, stack) || _right->eval_boolean(c, stack);
+				
+			case ast_op_and:
+				return _left->eval_boolean(c, stack) && _right->eval_boolean(c, stack);
+				
+			case ast_op_equal:
+				return compare_eq(_left, _right, c, stack, equal_to());
+
+			case ast_op_not_equal:
+				return compare_eq(_left, _right, c, stack, not_equal_to());
+	
+			case ast_op_less:
+				return compare_rel(_left, _right, c, stack, less());
+			
+			case ast_op_greater:
+				return compare_rel(_right, _left, c, stack, less());
+
+			case ast_op_less_or_equal:
+				return compare_rel(_left, _right, c, stack, less_equal());
+			
+			case ast_op_greater_or_equal:
+				return compare_rel(_right, _left, c, stack, less_equal());
+
+			case ast_func_starts_with:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_string lr = _left->eval_string(c, stack);
+				xpath_string rr = _right->eval_string(c, stack);
+
+				return starts_with(lr.c_str(), rr.c_str());
+			}
+
+			case ast_func_contains:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_string lr = _left->eval_string(c, stack);
+				xpath_string rr = _right->eval_string(c, stack);
+
+				return find_substring(lr.c_str(), rr.c_str()) != 0;
+			}
+
+			case ast_func_boolean:
+				return _left->eval_boolean(c, stack);
+				
+			case ast_func_not:
+				return !_left->eval_boolean(c, stack);
+				
+			case ast_func_true:
+				return true;
+				
+			case ast_func_false:
+				return false;
+
+			case ast_func_lang:
+			{
+				if (c.n.attribute()) return false;
+				
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_string lang = _left->eval_string(c, stack);
+				
+				for (xml_node n = c.n.node(); n; n = n.parent())
+				{
+					xml_attribute a = n.attribute(PUGIXML_TEXT("xml:lang"));
+					
+					if (a)
+					{
+						const char_t* value = a.value();
+						
+						// strnicmp / strncasecmp is not portable
+						for (const char_t* lit = lang.c_str(); *lit; ++lit)
+						{
+							if (tolower_ascii(*lit) != tolower_ascii(*value)) return false;
+							++value;
+						}
+						
+						return *value == 0 || *value == '-';
+					}
+				}
+				
+				return false;
+			}
+
+			case ast_variable:
+			{
+				assert(_rettype == _data.variable->type());
+
+				if (_rettype == xpath_type_boolean)
+					return _data.variable->get_boolean();
+
+				// fallthrough to type conversion
+			}
+
+			default:
+			{
+				switch (_rettype)
+				{
+				case xpath_type_number:
+					return convert_number_to_boolean(eval_number(c, stack));
+					
+				case xpath_type_string:
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					return !eval_string(c, stack).empty();
+				}
+					
+				case xpath_type_node_set:				
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					return !eval_node_set(c, stack).empty();
+				}
+
+				default:
+					assert(!"Wrong expression for return type boolean");
+					return false;
+				}
+			}
+			}
+		}
+
+		double eval_number(const xpath_context& c, const xpath_stack& stack)
+		{
+			switch (_type)
+			{
+			case ast_op_add:
+				return _left->eval_number(c, stack) + _right->eval_number(c, stack);
+				
+			case ast_op_subtract:
+				return _left->eval_number(c, stack) - _right->eval_number(c, stack);
+
+			case ast_op_multiply:
+				return _left->eval_number(c, stack) * _right->eval_number(c, stack);
+
+			case ast_op_divide:
+				return _left->eval_number(c, stack) / _right->eval_number(c, stack);
+
+			case ast_op_mod:
+				return fmod(_left->eval_number(c, stack), _right->eval_number(c, stack));
+
+			case ast_op_negate:
+				return -_left->eval_number(c, stack);
+
+			case ast_number_constant:
+				return _data.number;
+
+			case ast_func_last:
+				return (double)c.size;
+			
+			case ast_func_position:
+				return (double)c.position;
+
+			case ast_func_count:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				return (double)_left->eval_node_set(c, stack).size();
+			}
+			
+			case ast_func_string_length_0:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				return (double)string_value(c.n, stack.result).length();
+			}
+			
+			case ast_func_string_length_1:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				return (double)_left->eval_string(c, stack).length();
+			}
+			
+			case ast_func_number_0:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				return convert_string_to_number(string_value(c.n, stack.result).c_str());
+			}
+			
+			case ast_func_number_1:
+				return _left->eval_number(c, stack);
+
+			case ast_func_sum:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				double r = 0;
+				
+				xpath_node_set_raw ns = _left->eval_node_set(c, stack);
+				
+				for (const xpath_node* it = ns.begin(); it != ns.end(); ++it)
+				{
+					xpath_allocator_capture cri(stack.result);
+
+					r += convert_string_to_number(string_value(*it, stack.result).c_str());
+				}
+			
+				return r;
+			}
+
+			case ast_func_floor:
+			{
+				double r = _left->eval_number(c, stack);
+				
+				return r == r ? floor(r) : r;
+			}
+
+			case ast_func_ceiling:
+			{
+				double r = _left->eval_number(c, stack);
+				
+				return r == r ? ceil(r) : r;
+			}
+
+			case ast_func_round:
+				return round_nearest_nzero(_left->eval_number(c, stack));
+			
+			case ast_variable:
+			{
+				assert(_rettype == _data.variable->type());
+
+				if (_rettype == xpath_type_number)
+					return _data.variable->get_number();
+
+				// fallthrough to type conversion
+			}
+
+			default:
+			{
+				switch (_rettype)
+				{
+				case xpath_type_boolean:
+					return eval_boolean(c, stack) ? 1 : 0;
+					
+				case xpath_type_string:
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					return convert_string_to_number(eval_string(c, stack).c_str());
+				}
+					
+				case xpath_type_node_set:
+				{
+					xpath_allocator_capture cr(stack.result);
+
+					return convert_string_to_number(eval_string(c, stack).c_str());
+				}
+					
+				default:
+					assert(!"Wrong expression for return type number");
+					return 0;
+				}
+				
+			}
+			}
+		}
+		
+		xpath_string eval_string_concat(const xpath_context& c, const xpath_stack& stack)
+		{
+			assert(_type == ast_func_concat);
+
+			xpath_allocator_capture ct(stack.temp);
+
+			// count the string number
+			size_t count = 1;
+			for (xpath_ast_node* nc = _right; nc; nc = nc->_next) count++;
+
+			// gather all strings
+			xpath_string static_buffer[4];
+			xpath_string* buffer = static_buffer;
+
+			// allocate on-heap for large concats
+			if (count > sizeof(static_buffer) / sizeof(static_buffer[0]))
+			{
+				buffer = static_cast<xpath_string*>(stack.temp->allocate(count * sizeof(xpath_string)));
+				assert(buffer);
+			}
+
+			// evaluate all strings to temporary stack
+			xpath_stack swapped_stack = {stack.temp, stack.result};
+
+			buffer[0] = _left->eval_string(c, swapped_stack);
+
+			size_t pos = 1;
+			for (xpath_ast_node* n = _right; n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack);
+			assert(pos == count);
+
+			// get total length
+			size_t length = 0;
+			for (size_t i = 0; i < count; ++i) length += buffer[i].length();
+
+			// create final string
+			char_t* result = static_cast<char_t*>(stack.result->allocate((length + 1) * sizeof(char_t)));
+			assert(result);
+
+			char_t* ri = result;
+
+			for (size_t j = 0; j < count; ++j)
+				for (const char_t* bi = buffer[j].c_str(); *bi; ++bi)
+					*ri++ = *bi;
+
+			*ri = 0;
+
+			return xpath_string(result, true);
+		}
+
+		xpath_string eval_string(const xpath_context& c, const xpath_stack& stack)
+		{
+			switch (_type)
+			{
+			case ast_string_constant:
+				return xpath_string_const(_data.string);
+			
+			case ast_func_local_name_0:
+			{
+				xpath_node na = c.n;
+				
+				return xpath_string_const(local_name(na));
+			}
+
+			case ast_func_local_name_1:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ns = _left->eval_node_set(c, stack);
+				xpath_node na = ns.first();
+				
+				return xpath_string_const(local_name(na));
+			}
+
+			case ast_func_name_0:
+			{
+				xpath_node na = c.n;
+				
+				return xpath_string_const(qualified_name(na));
+			}
+
+			case ast_func_name_1:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ns = _left->eval_node_set(c, stack);
+				xpath_node na = ns.first();
+				
+				return xpath_string_const(qualified_name(na));
+			}
+
+			case ast_func_namespace_uri_0:
+			{
+				xpath_node na = c.n;
+				
+				return xpath_string_const(namespace_uri(na));
+			}
+
+			case ast_func_namespace_uri_1:
+			{
+				xpath_allocator_capture cr(stack.result);
+
+				xpath_node_set_raw ns = _left->eval_node_set(c, stack);
+				xpath_node na = ns.first();
+				
+				return xpath_string_const(namespace_uri(na));
+			}
+
+			case ast_func_string_0:
+				return string_value(c.n, stack.result);
+
+			case ast_func_string_1:
+				return _left->eval_string(c, stack);
+
+			case ast_func_concat:
+				return eval_string_concat(c, stack);
+
+			case ast_func_substring_before:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_string s = _left->eval_string(c, swapped_stack);
+				xpath_string p = _right->eval_string(c, swapped_stack);
+
+				const char_t* pos = find_substring(s.c_str(), p.c_str());
+				
+				return pos ? xpath_string(s.c_str(), pos, stack.result) : xpath_string();
+			}
+			
+			case ast_func_substring_after:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_string s = _left->eval_string(c, swapped_stack);
+				xpath_string p = _right->eval_string(c, swapped_stack);
+				
+				const char_t* pos = find_substring(s.c_str(), p.c_str());
+				if (!pos) return xpath_string();
+
+				const char_t* result = pos + p.length();
+
+				return s.uses_heap() ? xpath_string(result, stack.result) : xpath_string_const(result);
+			}
+
+			case ast_func_substring_2:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_string s = _left->eval_string(c, swapped_stack);
+				size_t s_length = s.length();
+
+				double first = round_nearest(_right->eval_number(c, stack));
+				
+				if (is_nan(first)) return xpath_string(); // NaN
+				else if (first >= s_length + 1) return xpath_string();
+				
+				size_t pos = first < 1 ? 1 : (size_t)first;
+				assert(1 <= pos && pos <= s_length + 1);
+
+				const char_t* rbegin = s.c_str() + (pos - 1);
+				
+				return s.uses_heap() ? xpath_string(rbegin, stack.result) : xpath_string_const(rbegin);
+			}
+			
+			case ast_func_substring_3:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_string s = _left->eval_string(c, swapped_stack);
+				size_t s_length = s.length();
+
+				double first = round_nearest(_right->eval_number(c, stack));
+				double last = first + round_nearest(_right->_next->eval_number(c, stack));
+				
+				if (is_nan(first) || is_nan(last)) return xpath_string();
+				else if (first >= s_length + 1) return xpath_string();
+				else if (first >= last) return xpath_string();
+				else if (last < 1) return xpath_string();
+				
+				size_t pos = first < 1 ? 1 : (size_t)first;
+				size_t end = last >= s_length + 1 ? s_length + 1 : (size_t)last;
+
+				assert(1 <= pos && pos <= end && end <= s_length + 1);
+				const char_t* rbegin = s.c_str() + (pos - 1);
+				const char_t* rend = s.c_str() + (end - 1);
+
+				return (end == s_length + 1 && !s.uses_heap()) ? xpath_string_const(rbegin) : xpath_string(rbegin, rend, stack.result);
+			}
+
+			case ast_func_normalize_space_0:
+			{
+				xpath_string s = string_value(c.n, stack.result);
+
+				normalize_space(s.data(stack.result));
+
+				return s;
+			}
+
+			case ast_func_normalize_space_1:
+			{
+				xpath_string s = _left->eval_string(c, stack);
+
+				normalize_space(s.data(stack.result));
+			
+				return s;
+			}
+
+			case ast_func_translate:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_string s = _left->eval_string(c, stack);
+				xpath_string from = _right->eval_string(c, swapped_stack);
+				xpath_string to = _right->_next->eval_string(c, swapped_stack);
+
+				translate(s.data(stack.result), from.c_str(), to.c_str());
+
+				return s;
+			}
+
+			case ast_variable:
+			{
+				assert(_rettype == _data.variable->type());
+
+				if (_rettype == xpath_type_string)
+					return xpath_string_const(_data.variable->get_string());
+
+				// fallthrough to type conversion
+			}
+
+			default:
+			{
+				switch (_rettype)
+				{
+				case xpath_type_boolean:
+					return xpath_string_const(eval_boolean(c, stack) ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"));
+					
+				case xpath_type_number:
+					return convert_number_to_string(eval_number(c, stack), stack.result);
+					
+				case xpath_type_node_set:
+				{
+					xpath_allocator_capture cr(stack.temp);
+
+					xpath_stack swapped_stack = {stack.temp, stack.result};
+
+					xpath_node_set_raw ns = eval_node_set(c, swapped_stack);
+					return ns.empty() ? xpath_string() : string_value(ns.first(), stack.result);
+				}
+				
+				default:
+					assert(!"Wrong expression for return type string");
+					return xpath_string();
+				}
+			}
+			}
+		}
+
+		xpath_node_set_raw eval_node_set(const xpath_context& c, const xpath_stack& stack)
+		{
+			switch (_type)
+			{
+			case ast_op_union:
+			{
+				xpath_allocator_capture cr(stack.temp);
+
+				xpath_stack swapped_stack = {stack.temp, stack.result};
+
+				xpath_node_set_raw ls = _left->eval_node_set(c, swapped_stack);
+				xpath_node_set_raw rs = _right->eval_node_set(c, stack);
+				
+				// we can optimize merging two sorted sets, but this is a very rare operation, so don't bother
+  		        rs.set_type(xpath_node_set::type_unsorted);
+
+				rs.append(ls.begin(), ls.end(), stack.result);
+				rs.remove_duplicates();
+				
+				return rs;
+			}
+
+			case ast_filter:
+			case ast_filter_posinv:
+			{
+				xpath_node_set_raw set = _left->eval_node_set(c, stack);
+
+				// either expression is a number or it contains position() call; sort by document order
+				if (_type == ast_filter) set.sort_do();
+
+				apply_predicate(set, 0, _right, stack);
+			
+				return set;
+			}
+			
+			case ast_func_id:
+				return xpath_node_set_raw();
+			
+			case ast_step:
+			{
+				switch (_axis)
+				{
+				case axis_ancestor:
+					return step_do(c, stack, axis_to_type<axis_ancestor>());
+					
+				case axis_ancestor_or_self:
+					return step_do(c, stack, axis_to_type<axis_ancestor_or_self>());
+
+				case axis_attribute:
+					return step_do(c, stack, axis_to_type<axis_attribute>());
+
+				case axis_child:
+					return step_do(c, stack, axis_to_type<axis_child>());
+				
+				case axis_descendant:
+					return step_do(c, stack, axis_to_type<axis_descendant>());
+
+				case axis_descendant_or_self:
+					return step_do(c, stack, axis_to_type<axis_descendant_or_self>());
+
+				case axis_following:
+					return step_do(c, stack, axis_to_type<axis_following>());
+				
+				case axis_following_sibling:
+					return step_do(c, stack, axis_to_type<axis_following_sibling>());
+				
+				case axis_namespace:
+					// namespaced axis is not supported
+					return xpath_node_set_raw();
+				
+				case axis_parent:
+					return step_do(c, stack, axis_to_type<axis_parent>());
+				
+				case axis_preceding:
+					return step_do(c, stack, axis_to_type<axis_preceding>());
+
+				case axis_preceding_sibling:
+					return step_do(c, stack, axis_to_type<axis_preceding_sibling>());
+				
+				case axis_self:
+					return step_do(c, stack, axis_to_type<axis_self>());
+				}
+			}
+
+			case ast_step_root:
+			{
+				assert(!_right); // root step can't have any predicates
+
+				xpath_node_set_raw ns;
+
+				ns.set_type(xpath_node_set::type_sorted);
+
+				if (c.n.node()) ns.push_back(c.n.node().root(), stack.result);
+				else if (c.n.attribute()) ns.push_back(c.n.parent().root(), stack.result);
+
+				return ns;
+			}
+
+			case ast_variable:
+			{
+				assert(_rettype == _data.variable->type());
+
+				if (_rettype == xpath_type_node_set)
+				{
+					const xpath_node_set& s = _data.variable->get_node_set();
+
+					xpath_node_set_raw ns;
+
+					ns.set_type(s.type());
+					ns.append(s.begin(), s.end(), stack.result);
+
+					return ns;
+				}
+
+				// fallthrough to type conversion
+			}
+
+			default:
+				assert(!"Wrong expression for return type node set");
+				return xpath_node_set_raw();
+			}
+		}
+		
+		bool is_posinv()
+		{
+			switch (_type)
+			{
+			case ast_func_position:
+				return false;
+
+			case ast_string_constant:
+			case ast_number_constant:
+			case ast_variable:
+				return true;
+
+			case ast_step:
+			case ast_step_root:
+				return true;
+
+			case ast_predicate:
+			case ast_filter:
+			case ast_filter_posinv:
+				return true;
+
+			default:
+				if (_left && !_left->is_posinv()) return false;
+				
+				for (xpath_ast_node* n = _right; n; n = n->_next)
+					if (!n->is_posinv()) return false;
+					
+				return true;
+			}
+		}
+
+		xpath_value_type rettype() const
+		{
+			return static_cast<xpath_value_type>(_rettype);
+		}
+	};
+
+	struct xpath_parser
+	{
+	    xpath_allocator* _alloc;
+	    xpath_lexer _lexer;
+
+		const char_t* _query;
+		xpath_variable_set* _variables;
+
+		xpath_parse_result* _result;
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		jmp_buf _error_handler;
+	#endif
+
+		void throw_error(const char* message)
+		{
+			_result->error = message;
+			_result->offset = _lexer.current_pos() - _query;
+
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			longjmp(_error_handler, 1);
+		#else
+			throw xpath_exception(*_result);
+		#endif
+		}
+
+		void throw_error_oom()
+        {
+        #ifdef PUGIXML_NO_EXCEPTIONS
+            throw_error("Out of memory");
+        #else
+            throw std::bad_alloc();
+        #endif
+        }
+
+		void* alloc_node()
+		{
+			void* result = _alloc->allocate_nothrow(sizeof(xpath_ast_node));
+
+			if (!result) throw_error_oom();
+
+			return result;
+		}
+
+		const char_t* alloc_string(const xpath_lexer_string& value)
+		{
+			if (value.begin)
+			{
+				size_t length = static_cast<size_t>(value.end - value.begin);
+
+				char_t* c = static_cast<char_t*>(_alloc->allocate_nothrow((length + 1) * sizeof(char_t)));
+				if (!c) throw_error_oom();
+
+				memcpy(c, value.begin, length * sizeof(char_t));
+				c[length] = 0;
+
+				return c;
+			}
+			else return 0;
+		}
+
+		xpath_ast_node* parse_function_helper(ast_type_t type0, ast_type_t type1, size_t argc, xpath_ast_node* args[2])
+		{
+			assert(argc <= 1);
+
+			if (argc == 1 && args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set");
+
+			return new (alloc_node()) xpath_ast_node(argc == 0 ? type0 : type1, xpath_type_string, args[0]);
+		}
+
+		xpath_ast_node* parse_function(const xpath_lexer_string& name, size_t argc, xpath_ast_node* args[2])
+		{
+			switch (name.begin[0])
+			{
+			case 'b':
+				if (name == PUGIXML_TEXT("boolean") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_boolean, xpath_type_boolean, args[0]);
+					
+				break;
+			
+			case 'c':
+				if (name == PUGIXML_TEXT("count") && argc == 1)
+				{
+					if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set");
+					return new (alloc_node()) xpath_ast_node(ast_func_count, xpath_type_number, args[0]);
+				}
+				else if (name == PUGIXML_TEXT("contains") && argc == 2)
+					return new (alloc_node()) xpath_ast_node(ast_func_contains, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("concat") && argc >= 2)
+					return new (alloc_node()) xpath_ast_node(ast_func_concat, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("ceiling") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_ceiling, xpath_type_number, args[0]);
+					
+				break;
+			
+			case 'f':
+				if (name == PUGIXML_TEXT("false") && argc == 0)
+					return new (alloc_node()) xpath_ast_node(ast_func_false, xpath_type_boolean);
+				else if (name == PUGIXML_TEXT("floor") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_floor, xpath_type_number, args[0]);
+					
+				break;
+			
+			case 'i':
+				if (name == PUGIXML_TEXT("id") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_id, xpath_type_node_set, args[0]);
+					
+				break;
+			
+			case 'l':
+				if (name == PUGIXML_TEXT("last") && argc == 0)
+					return new (alloc_node()) xpath_ast_node(ast_func_last, xpath_type_number);
+				else if (name == PUGIXML_TEXT("lang") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_lang, xpath_type_boolean, args[0]);
+				else if (name == PUGIXML_TEXT("local-name") && argc <= 1)
+					return parse_function_helper(ast_func_local_name_0, ast_func_local_name_1, argc, args);
+			
+				break;
+			
+			case 'n':
+				if (name == PUGIXML_TEXT("name") && argc <= 1)
+					return parse_function_helper(ast_func_name_0, ast_func_name_1, argc, args);
+				else if (name == PUGIXML_TEXT("namespace-uri") && argc <= 1)
+					return parse_function_helper(ast_func_namespace_uri_0, ast_func_namespace_uri_1, argc, args);
+				else if (name == PUGIXML_TEXT("normalize-space") && argc <= 1)
+					return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_normalize_space_0 : ast_func_normalize_space_1, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("not") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_not, xpath_type_boolean, args[0]);
+				else if (name == PUGIXML_TEXT("number") && argc <= 1)
+					return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_number_0 : ast_func_number_1, xpath_type_number, args[0]);
+			
+				break;
+			
+			case 'p':
+				if (name == PUGIXML_TEXT("position") && argc == 0)
+					return new (alloc_node()) xpath_ast_node(ast_func_position, xpath_type_number);
+				
+				break;
+			
+			case 'r':
+				if (name == PUGIXML_TEXT("round") && argc == 1)
+					return new (alloc_node()) xpath_ast_node(ast_func_round, xpath_type_number, args[0]);
+
+				break;
+			
+			case 's':
+				if (name == PUGIXML_TEXT("string") && argc <= 1)
+					return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_0 : ast_func_string_1, xpath_type_string, args[0]);
+				else if (name == PUGIXML_TEXT("string-length") && argc <= 1)
+					return new (alloc_node()) xpath_ast_node(argc == 0 ? ast_func_string_length_0 : ast_func_string_length_1, xpath_type_string, args[0]);
+				else if (name == PUGIXML_TEXT("starts-with") && argc == 2)
+					return new (alloc_node()) xpath_ast_node(ast_func_starts_with, xpath_type_boolean, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("substring-before") && argc == 2)
+					return new (alloc_node()) xpath_ast_node(ast_func_substring_before, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("substring-after") && argc == 2)
+					return new (alloc_node()) xpath_ast_node(ast_func_substring_after, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("substring") && (argc == 2 || argc == 3))
+					return new (alloc_node()) xpath_ast_node(argc == 2 ? ast_func_substring_2 : ast_func_substring_3, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("sum") && argc == 1)
+				{
+					if (args[0]->rettype() != xpath_type_node_set) throw_error("Function has to be applied to node set");
+					return new (alloc_node()) xpath_ast_node(ast_func_sum, xpath_type_number, args[0]);
+				}
+
+				break;
+			
+			case 't':
+				if (name == PUGIXML_TEXT("translate") && argc == 3)
+					return new (alloc_node()) xpath_ast_node(ast_func_translate, xpath_type_string, args[0], args[1]);
+				else if (name == PUGIXML_TEXT("true") && argc == 0)
+					return new (alloc_node()) xpath_ast_node(ast_func_true, xpath_type_boolean);
+					
+				break;
+			}
+
+			throw_error("Unrecognized function or wrong parameter count");
+
+			return 0;
+		}
+
+		axis_t parse_axis_name(const xpath_lexer_string& name, bool& specified)
+		{
+			specified = true;
+
+			switch (name.begin[0])
+			{
+			case 'a':
+				if (name == PUGIXML_TEXT("ancestor"))
+					return axis_ancestor;
+				else if (name == PUGIXML_TEXT("ancestor-or-self"))
+					return axis_ancestor_or_self;
+				else if (name == PUGIXML_TEXT("attribute"))
+					return axis_attribute;
+				
+				break;
+			
+			case 'c':
+				if (name == PUGIXML_TEXT("child"))
+					return axis_child;
+				
+				break;
+			
+			case 'd':
+				if (name == PUGIXML_TEXT("descendant"))
+					return axis_descendant;
+				else if (name == PUGIXML_TEXT("descendant-or-self"))
+					return axis_descendant_or_self;
+				
+				break;
+			
+			case 'f':
+				if (name == PUGIXML_TEXT("following"))
+					return axis_following;
+				else if (name == PUGIXML_TEXT("following-sibling"))
+					return axis_following_sibling;
+				
+				break;
+			
+			case 'n':
+				if (name == PUGIXML_TEXT("namespace"))
+					return axis_namespace;
+				
+				break;
+			
+			case 'p':
+				if (name == PUGIXML_TEXT("parent"))
+					return axis_parent;
+				else if (name == PUGIXML_TEXT("preceding"))
+					return axis_preceding;
+				else if (name == PUGIXML_TEXT("preceding-sibling"))
+					return axis_preceding_sibling;
+				
+				break;
+			
+			case 's':
+				if (name == PUGIXML_TEXT("self"))
+					return axis_self;
+				
+				break;
+			}
+
+			specified = false;
+			return axis_child;
+		}
+
+		nodetest_t parse_node_test_type(const xpath_lexer_string& name)
+		{
+			switch (name.begin[0])
+			{
+			case 'c':
+				if (name == PUGIXML_TEXT("comment"))
+					return nodetest_type_comment;
+
+				break;
+
+			case 'n':
+				if (name == PUGIXML_TEXT("node"))
+					return nodetest_type_node;
+
+				break;
+
+			case 'p':
+				if (name == PUGIXML_TEXT("processing-instruction"))
+					return nodetest_type_pi;
+
+				break;
+
+			case 't':
+				if (name == PUGIXML_TEXT("text"))
+					return nodetest_type_text;
+
+				break;
+			}
+
+			return nodetest_none;
+		}
+
+	    // PrimaryExpr ::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall
+	    xpath_ast_node* parse_primary_expression()
+	    {
+	    	switch (_lexer.current())
+	    	{
+	    	case lex_var_ref:
+	    	{
+				xpath_lexer_string name = _lexer.contents();
+
+				if (!_variables)
+					throw_error("Unknown variable: variable set is not provided");
+
+				xpath_variable* var = get_variable(_variables, name.begin, name.end);
+
+				if (!var)
+					throw_error("Unknown variable: variable set does not contain the given name");
+
+				_lexer.next();
+
+	    		return new (alloc_node()) xpath_ast_node(ast_variable, var->type(), var);
+			}
+
+			case lex_open_brace:
+			{
+				_lexer.next();
+
+				xpath_ast_node* n = parse_expression();
+
+				if (_lexer.current() != lex_close_brace)
+					throw_error("Unmatched braces");
+
+				_lexer.next();
+
+				return n;
+			}
+
+			case lex_quoted_string:
+			{
+				const char_t* value = alloc_string(_lexer.contents());
+
+				xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_string_constant, xpath_type_string, value);
+				_lexer.next();
+
+				return n;
+			}
+
+			case lex_number:
+			{
+				double value = 0;
+
+				if (!convert_string_to_number(_lexer.contents().begin, _lexer.contents().end, &value))
+					throw_error_oom();
+
+				xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_number_constant, xpath_type_number, value);
+				_lexer.next();
+
+				return n;
+			}
+
+			case lex_string:
+			{
+				xpath_ast_node* args[2] = {0};
+				size_t argc = 0;
+				
+				xpath_lexer_string function = _lexer.contents();
+				_lexer.next();
+				
+				xpath_ast_node* last_arg = 0;
+				
+				if (_lexer.current() != lex_open_brace)
+					throw_error("Unrecognized function call");
+				_lexer.next();
+
+				if (_lexer.current() != lex_close_brace)
+					args[argc++] = parse_expression();
+
+				while (_lexer.current() != lex_close_brace)
+				{
+					if (_lexer.current() != lex_comma)
+						throw_error("No comma between function arguments");
+					_lexer.next();
+					
+					xpath_ast_node* n = parse_expression();
+					
+					if (argc < 2) args[argc] = n;
+					else last_arg->set_next(n);
+
+					argc++;
+					last_arg = n;
+				}
+				
+				_lexer.next();
+
+				return parse_function(function, argc, args);
+			}
+
+	    	default:
+	    		throw_error("Unrecognizable primary expression");
+
+	    		return 0;
+	    	}
+	    }
+	    
+	    // FilterExpr ::= PrimaryExpr | FilterExpr Predicate
+	    // Predicate ::= '[' PredicateExpr ']'
+	    // PredicateExpr ::= Expr
+	    xpath_ast_node* parse_filter_expression()
+	    {
+	    	xpath_ast_node* n = parse_primary_expression();
+
+	    	while (_lexer.current() == lex_open_square_brace)
+	    	{
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_expression();
+
+				if (n->rettype() != xpath_type_node_set) throw_error("Predicate has to be applied to node set");
+
+				bool posinv = expr->rettype() != xpath_type_number && expr->is_posinv();
+
+	    		n = new (alloc_node()) xpath_ast_node(posinv ? ast_filter_posinv : ast_filter, xpath_type_node_set, n, expr);
+
+	    		if (_lexer.current() != lex_close_square_brace)
+	    			throw_error("Unmatched square brace");
+	    	
+	    		_lexer.next();
+	    	}
+	    	
+	    	return n;
+	    }
+	    
+	    // Step ::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep
+	    // AxisSpecifier ::= AxisName '::' | '@'?
+	    // NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')'
+	    // NameTest ::= '*' | NCName ':' '*' | QName
+	    // AbbreviatedStep ::= '.' | '..'
+	    xpath_ast_node* parse_step(xpath_ast_node* set)
+	    {
+			if (set && set->rettype() != xpath_type_node_set)
+				throw_error("Step has to be applied to node set");
+
+			bool axis_specified = false;
+			axis_t axis = axis_child; // implied child axis
+
+			if (_lexer.current() == lex_axis_attribute)
+			{
+				axis = axis_attribute;
+				axis_specified = true;
+				
+				_lexer.next();
+			}
+			else if (_lexer.current() == lex_dot)
+			{
+				_lexer.next();
+				
+				return new (alloc_node()) xpath_ast_node(ast_step, set, axis_self, nodetest_type_node, 0);
+			}
+			else if (_lexer.current() == lex_double_dot)
+			{
+				_lexer.next();
+				
+				return new (alloc_node()) xpath_ast_node(ast_step, set, axis_parent, nodetest_type_node, 0);
+			}
+	    
+			nodetest_t nt_type = nodetest_none;
+			xpath_lexer_string nt_name;
+			
+			if (_lexer.current() == lex_string)
+			{
+				// node name test
+				nt_name = _lexer.contents();
+				_lexer.next();
+
+				// was it an axis name?
+				if (_lexer.current() == lex_double_colon)
+				{
+					// parse axis name
+					if (axis_specified) throw_error("Two axis specifiers in one step");
+
+					axis = parse_axis_name(nt_name, axis_specified);
+
+					if (!axis_specified) throw_error("Unknown axis");
+
+					// read actual node test
+					_lexer.next();
+
+					if (_lexer.current() == lex_multiply)
+					{
+						nt_type = nodetest_all;
+						nt_name = xpath_lexer_string();
+						_lexer.next();
+					}
+					else if (_lexer.current() == lex_string)
+					{
+						nt_name = _lexer.contents();
+						_lexer.next();
+					}
+					else throw_error("Unrecognized node test");
+				}
+				
+				if (nt_type == nodetest_none)
+				{
+					// node type test or processing-instruction
+					if (_lexer.current() == lex_open_brace)
+					{
+						_lexer.next();
+						
+						if (_lexer.current() == lex_close_brace)
+						{
+							_lexer.next();
+
+							nt_type = parse_node_test_type(nt_name);
+
+							if (nt_type == nodetest_none) throw_error("Unrecognized node type");
+							
+							nt_name = xpath_lexer_string();
+						}
+						else if (nt_name == PUGIXML_TEXT("processing-instruction"))
+						{
+							if (_lexer.current() != lex_quoted_string)
+								throw_error("Only literals are allowed as arguments to processing-instruction()");
+						
+							nt_type = nodetest_pi;
+							nt_name = _lexer.contents();
+							_lexer.next();
+							
+							if (_lexer.current() != lex_close_brace)
+								throw_error("Unmatched brace near processing-instruction()");
+							_lexer.next();
+						}
+						else
+							throw_error("Unmatched brace near node type test");
+
+					}
+					// QName or NCName:*
+					else
+					{
+						if (nt_name.end - nt_name.begin > 2 && nt_name.end[-2] == ':' && nt_name.end[-1] == '*') // NCName:*
+						{
+							nt_name.end--; // erase *
+							
+							nt_type = nodetest_all_in_namespace;
+						}
+						else nt_type = nodetest_name;
+					}
+				}
+			}
+			else if (_lexer.current() == lex_multiply)
+			{
+				nt_type = nodetest_all;
+				_lexer.next();
+			}
+			else throw_error("Unrecognized node test");
+			
+			xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step, set, axis, nt_type, alloc_string(nt_name));
+			
+			xpath_ast_node* last = 0;
+			
+			while (_lexer.current() == lex_open_square_brace)
+			{
+				_lexer.next();
+				
+				xpath_ast_node* expr = parse_expression();
+
+				xpath_ast_node* pred = new (alloc_node()) xpath_ast_node(ast_predicate, xpath_type_node_set, expr);
+				
+				if (_lexer.current() != lex_close_square_brace)
+	    			throw_error("Unmatched square brace");
+				_lexer.next();
+				
+				if (last) last->set_next(pred);
+				else n->set_right(pred);
+				
+				last = pred;
+			}
+			
+			return n;
+	    }
+	    
+	    // RelativeLocationPath ::= Step | RelativeLocationPath '/' Step | RelativeLocationPath '//' Step
+	    xpath_ast_node* parse_relative_location_path(xpath_ast_node* set)
+	    {
+			xpath_ast_node* n = parse_step(set);
+			
+			while (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash)
+			{
+				lexeme_t l = _lexer.current();
+				_lexer.next();
+
+				if (l == lex_double_slash)
+					n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0);
+				
+				n = parse_step(n);
+			}
+			
+			return n;
+	    }
+	    
+	    // LocationPath ::= RelativeLocationPath | AbsoluteLocationPath
+	    // AbsoluteLocationPath ::= '/' RelativeLocationPath? | '//' RelativeLocationPath
+	    xpath_ast_node* parse_location_path()
+	    {
+			if (_lexer.current() == lex_slash)
+			{
+				_lexer.next();
+				
+				xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set);
+
+				// relative location path can start from axis_attribute, dot, double_dot, multiply and string lexemes; any other lexeme means standalone root path
+				lexeme_t l = _lexer.current();
+
+				if (l == lex_string || l == lex_axis_attribute || l == lex_dot || l == lex_double_dot || l == lex_multiply)
+					return parse_relative_location_path(n);
+				else
+					return n;
+			}
+			else if (_lexer.current() == lex_double_slash)
+			{
+				_lexer.next();
+				
+				xpath_ast_node* n = new (alloc_node()) xpath_ast_node(ast_step_root, xpath_type_node_set);
+				n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0);
+				
+				return parse_relative_location_path(n);
+			}
+
+			// else clause moved outside of if because of bogus warning 'control may reach end of non-void function being inlined' in gcc 4.0.1
+			return parse_relative_location_path(0);
+	    }
+	    
+	    // PathExpr ::= LocationPath
+	    //				| FilterExpr
+	    //				| FilterExpr '/' RelativeLocationPath
+	    //				| FilterExpr '//' RelativeLocationPath
+	    xpath_ast_node* parse_path_expression()
+	    {
+			// Clarification.
+			// PathExpr begins with either LocationPath or FilterExpr.
+			// FilterExpr begins with PrimaryExpr
+			// PrimaryExpr begins with '$' in case of it being a variable reference,
+			// '(' in case of it being an expression, string literal, number constant or
+			// function call.
+
+			if (_lexer.current() == lex_var_ref || _lexer.current() == lex_open_brace || 
+				_lexer.current() == lex_quoted_string || _lexer.current() == lex_number ||
+				_lexer.current() == lex_string)
+	    	{
+	    		if (_lexer.current() == lex_string)
+	    		{
+	    			// This is either a function call, or not - if not, we shall proceed with location path
+	    			const char_t* state = _lexer.state();
+	    			
+					while (IS_CHARTYPE(*state, ct_space)) ++state;
+	    			
+	    			if (*state != '(') return parse_location_path();
+
+					// This looks like a function call; however this still can be a node-test. Check it.
+					if (parse_node_test_type(_lexer.contents()) != nodetest_none) return parse_location_path();
+	    		}
+	    		
+	    		xpath_ast_node* n = parse_filter_expression();
+
+	    		if (_lexer.current() == lex_slash || _lexer.current() == lex_double_slash)
+	    		{
+					lexeme_t l = _lexer.current();
+	    			_lexer.next();
+	    			
+					if (l == lex_double_slash)
+					{
+						if (n->rettype() != xpath_type_node_set) throw_error("Step has to be applied to node set");
+
+						n = new (alloc_node()) xpath_ast_node(ast_step, n, axis_descendant_or_self, nodetest_type_node, 0);
+					}
+	
+	    			// select from location path
+	    			return parse_relative_location_path(n);
+	    		}
+
+	    		return n;
+	    	}
+	    	else return parse_location_path();
+	    }
+
+	    // UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
+	    xpath_ast_node* parse_union_expression()
+	    {
+	    	xpath_ast_node* n = parse_path_expression();
+
+	    	while (_lexer.current() == lex_union)
+	    	{
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_union_expression();
+
+				if (n->rettype() != xpath_type_node_set || expr->rettype() != xpath_type_node_set)
+					throw_error("Union operator has to be applied to node sets");
+
+	    		n = new (alloc_node()) xpath_ast_node(ast_op_union, xpath_type_node_set, n, expr);
+	    	}
+
+	    	return n;
+	    }
+
+	    // UnaryExpr ::= UnionExpr | '-' UnaryExpr
+	    xpath_ast_node* parse_unary_expression()
+	    {
+	    	if (_lexer.current() == lex_minus)
+	    	{
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_unary_expression();
+
+	    		return new (alloc_node()) xpath_ast_node(ast_op_negate, xpath_type_number, expr);
+	    	}
+	    	else return parse_union_expression();
+	    }
+	    
+	    // MultiplicativeExpr ::= UnaryExpr
+	    //						  | MultiplicativeExpr '*' UnaryExpr
+	    //						  | MultiplicativeExpr 'div' UnaryExpr
+	    //						  | MultiplicativeExpr 'mod' UnaryExpr
+	    xpath_ast_node* parse_multiplicative_expression()
+	    {
+	    	xpath_ast_node* n = parse_unary_expression();
+
+	    	while (_lexer.current() == lex_multiply || (_lexer.current() == lex_string &&
+	    		   (_lexer.contents() == PUGIXML_TEXT("mod") || _lexer.contents() == PUGIXML_TEXT("div"))))
+	    	{
+	    		ast_type_t op = _lexer.current() == lex_multiply ? ast_op_multiply :
+	    			_lexer.contents().begin[0] == 'd' ? ast_op_divide : ast_op_mod;
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_unary_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(op, xpath_type_number, n, expr);
+	    	}
+
+	    	return n;
+	    }
+
+	    // AdditiveExpr ::= MultiplicativeExpr
+	    //					| AdditiveExpr '+' MultiplicativeExpr
+	    //					| AdditiveExpr '-' MultiplicativeExpr
+	    xpath_ast_node* parse_additive_expression()
+	    {
+	    	xpath_ast_node* n = parse_multiplicative_expression();
+
+	    	while (_lexer.current() == lex_plus || _lexer.current() == lex_minus)
+	    	{
+	    		lexeme_t l = _lexer.current();
+
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_multiplicative_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(l == lex_plus ? ast_op_add : ast_op_subtract, xpath_type_number, n, expr);
+	    	}
+
+	    	return n;
+	    }
+
+	    // RelationalExpr ::= AdditiveExpr
+	    //					  | RelationalExpr '<' AdditiveExpr
+	    //					  | RelationalExpr '>' AdditiveExpr
+	    //					  | RelationalExpr '<=' AdditiveExpr
+	    //					  | RelationalExpr '>=' AdditiveExpr
+	    xpath_ast_node* parse_relational_expression()
+	    {
+	    	xpath_ast_node* n = parse_additive_expression();
+
+	    	while (_lexer.current() == lex_less || _lexer.current() == lex_less_or_equal || 
+	    		   _lexer.current() == lex_greater || _lexer.current() == lex_greater_or_equal)
+	    	{
+	    		lexeme_t l = _lexer.current();
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_additive_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(l == lex_less ? ast_op_less : l == lex_greater ? ast_op_greater :
+	    						l == lex_less_or_equal ? ast_op_less_or_equal : ast_op_greater_or_equal, xpath_type_boolean, n, expr);
+	    	}
+
+	    	return n;
+	    }
+	    
+	    // EqualityExpr ::= RelationalExpr
+	    //					| EqualityExpr '=' RelationalExpr
+	    //					| EqualityExpr '!=' RelationalExpr
+	    xpath_ast_node* parse_equality_expression()
+	    {
+	    	xpath_ast_node* n = parse_relational_expression();
+
+	    	while (_lexer.current() == lex_equal || _lexer.current() == lex_not_equal)
+	    	{
+	    		lexeme_t l = _lexer.current();
+
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_relational_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(l == lex_equal ? ast_op_equal : ast_op_not_equal, xpath_type_boolean, n, expr);
+	    	}
+
+	    	return n;
+	    }
+	    
+	    // AndExpr ::= EqualityExpr | AndExpr 'and' EqualityExpr
+	    xpath_ast_node* parse_and_expression()
+	    {
+	    	xpath_ast_node* n = parse_equality_expression();
+
+	    	while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("and"))
+	    	{
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_equality_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(ast_op_and, xpath_type_boolean, n, expr);
+	    	}
+
+	    	return n;
+	    }
+
+	    // OrExpr ::= AndExpr | OrExpr 'or' AndExpr
+	    xpath_ast_node* parse_or_expression()
+	    {
+	    	xpath_ast_node* n = parse_and_expression();
+
+	    	while (_lexer.current() == lex_string && _lexer.contents() == PUGIXML_TEXT("or"))
+	    	{
+	    		_lexer.next();
+
+				xpath_ast_node* expr = parse_and_expression();
+
+	    		n = new (alloc_node()) xpath_ast_node(ast_op_or, xpath_type_boolean, n, expr);
+	    	}
+
+	    	return n;
+	    }
+		
+		// Expr ::= OrExpr
+		xpath_ast_node* parse_expression()
+		{
+			return parse_or_expression();
+		}
+
+		xpath_parser(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result)
+		{
+		}
+
+		xpath_ast_node* parse()
+		{
+			xpath_ast_node* result = parse_expression();
+			
+			if (_lexer.current() != lex_eof)
+			{
+				// there are still unparsed tokens left, error
+				throw_error("Incorrect query");
+			}
+			
+			return result;
+		}
+
+		static xpath_ast_node* parse(const char_t* query, xpath_variable_set* variables, xpath_allocator* alloc, xpath_parse_result* result)
+		{
+			xpath_parser parser(query, variables, alloc, result);
+
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			int error = setjmp(parser._error_handler);
+
+			return (error == 0) ? parser.parse() : 0;
+		#else
+			return parser.parse();
+		#endif
+		}
+	};
+
+    struct xpath_query_impl
+    {
+		static xpath_query_impl* create()
+		{
+			void* memory = global_allocate(sizeof(xpath_query_impl));
+
+            return new (memory) xpath_query_impl();
+		}
+
+		static void destroy(void* ptr)
+		{
+			if (!ptr) return;
+			
+			// free all allocated pages
+			static_cast<xpath_query_impl*>(ptr)->alloc.release();
+
+			// free allocator memory (with the first page)
+			global_deallocate(ptr);
+		}
+
+        xpath_query_impl(): root(0), alloc(&block)
+        {
+            block.next = 0;
+        }
+
+        xpath_ast_node* root;
+        xpath_allocator alloc;
+        xpath_memory_block block;
+    };
+
+	xpath_string evaluate_string_impl(xpath_query_impl* impl, const xpath_node& n, xpath_stack_data& sd)
+	{
+		if (!impl) return xpath_string();
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		if (setjmp(sd.error_handler)) return xpath_string();
+	#endif
+
+		xpath_context c(n, 1, 1);
+
+		return impl->root->eval_string(c, sd.stack);
+	}
+}
+
+namespace pugi
+{
+#ifndef PUGIXML_NO_EXCEPTIONS
+	xpath_exception::xpath_exception(const xpath_parse_result& result): _result(result)
+	{
+		assert(result.error);
+	}
+	
+	const char* xpath_exception::what() const throw()
+	{
+		return _result.error;
+	}
+
+	const xpath_parse_result& xpath_exception::result() const
+	{
+		return _result;
+	}
+#endif
+	
+	xpath_node::xpath_node()
+	{
+	}
+		
+	xpath_node::xpath_node(const xml_node& node): _node(node)
+	{
+	}
+		
+	xpath_node::xpath_node(const xml_attribute& attribute, const xml_node& parent): _node(attribute ? parent : xml_node()), _attribute(attribute)
+	{
+	}
+
+	xml_node xpath_node::node() const
+	{
+		return _attribute ? xml_node() : _node;
+	}
+		
+	xml_attribute xpath_node::attribute() const
+	{
+		return _attribute;
+	}
+	
+	xml_node xpath_node::parent() const
+	{
+		return _attribute ? _node : _node.parent();
+	}
+
+	xpath_node::operator xpath_node::unspecified_bool_type() const
+	{
+		return (_node || _attribute) ? &xpath_node::_node : 0;
+	}
+	
+	bool xpath_node::operator!() const
+	{
+		return !(_node || _attribute);
+	}
+
+	bool xpath_node::operator==(const xpath_node& n) const
+	{
+		return _node == n._node && _attribute == n._attribute;
+	}
+	
+	bool xpath_node::operator!=(const xpath_node& n) const
+	{
+		return _node != n._node || _attribute != n._attribute;
+	}
+
+#ifdef __BORLANDC__
+	bool operator&&(const xpath_node& lhs, bool rhs)
+	{
+		return (bool)lhs && rhs;
+	}
+
+	bool operator||(const xpath_node& lhs, bool rhs)
+	{
+		return (bool)lhs || rhs;
+	}
+#endif
+
+	void xpath_node_set::_assign(const_iterator begin, const_iterator end)
+	{
+		assert(begin <= end);
+
+		size_t size = static_cast<size_t>(end - begin);
+
+		if (size <= 1)
+		{
+			// deallocate old buffer
+			if (_begin != &_storage) global_deallocate(_begin);
+
+			// use internal buffer
+			if (begin != end) _storage = *begin;
+
+			_begin = &_storage;
+			_end = &_storage + size;
+		}
+		else
+		{
+			// make heap copy
+			xpath_node* storage = static_cast<xpath_node*>(global_allocate(size * sizeof(xpath_node)));
+
+			if (!storage)
+			{
+			#ifdef PUGIXML_NO_EXCEPTIONS
+				return;
+			#else
+				throw std::bad_alloc();
+			#endif
+			}
+
+			memcpy(storage, begin, size * sizeof(xpath_node));
+			
+			// deallocate old buffer
+			if (_begin != &_storage) global_deallocate(_begin);
+
+			// finalize
+			_begin = storage;
+			_end = storage + size;
+		}
+	}
+
+	xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(&_storage), _end(&_storage)
+	{
+	}
+
+	xpath_node_set::xpath_node_set(const_iterator begin, const_iterator end, type_t type): _type(type), _begin(&_storage), _end(&_storage)
+	{
+		_assign(begin, end);
+	}
+
+	xpath_node_set::~xpath_node_set()
+	{
+		if (_begin != &_storage) global_deallocate(_begin);
+	}
+		
+	xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(ns._type), _begin(&_storage), _end(&_storage)
+	{
+		_assign(ns._begin, ns._end);
+	}
+	
+	xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns)
+	{
+		if (this == &ns) return *this;
+		
+		_type = ns._type;
+		_assign(ns._begin, ns._end);
+
+		return *this;
+	}
+
+	xpath_node_set::type_t xpath_node_set::type() const
+	{
+		return _type;
+	}
+		
+	size_t xpath_node_set::size() const
+	{
+		return _end - _begin;
+	}
+		
+	bool xpath_node_set::empty() const
+	{
+		return _begin == _end;
+	}
+		
+	const xpath_node& xpath_node_set::operator[](size_t index) const
+	{
+		assert(index < size());
+		return _begin[index];
+	}
+
+	xpath_node_set::const_iterator xpath_node_set::begin() const
+	{
+		return _begin;
+	}
+		
+	xpath_node_set::const_iterator xpath_node_set::end() const
+	{
+		return _end;
+	}
+	
+	void xpath_node_set::sort(bool reverse)
+	{
+		_type = xpath_sort(_begin, _end, _type, reverse);
+	}
+
+	xpath_node xpath_node_set::first() const
+	{
+		return xpath_first(_begin, _end, _type);
+	}
+
+    xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0)
+    {
+    }
+
+    xpath_parse_result::operator bool() const
+    {
+        return error == 0;
+    }
+	const char* xpath_parse_result::description() const
+	{
+		return error ? error : "No error";
+	}
+
+	xpath_variable::xpath_variable()
+    {
+    }
+
+	const char_t* xpath_variable::name() const
+	{
+		switch (_type)
+		{
+		case xpath_type_node_set:
+			return static_cast<const xpath_variable_node_set*>(this)->name;
+
+		case xpath_type_number:
+			return static_cast<const xpath_variable_number*>(this)->name;
+
+		case xpath_type_string:
+			return static_cast<const xpath_variable_string*>(this)->name;
+
+		case xpath_type_boolean:
+			return static_cast<const xpath_variable_boolean*>(this)->name;
+
+		default:
+			assert(!"Invalid variable type");
+			return 0;
+		}
+	}
+
+	xpath_value_type xpath_variable::type() const
+	{
+		return _type;
+	}
+
+	bool xpath_variable::get_boolean() const
+	{
+		return (_type == xpath_type_boolean) ? static_cast<const xpath_variable_boolean*>(this)->value : false;
+	}
+
+	double xpath_variable::get_number() const
+	{
+		return (_type == xpath_type_number) ? static_cast<const xpath_variable_number*>(this)->value : gen_nan();
+	}
+
+	const char_t* xpath_variable::get_string() const
+	{
+		const char_t* value = (_type == xpath_type_string) ? static_cast<const xpath_variable_string*>(this)->value : 0;
+		return value ? value : PUGIXML_TEXT("");
+	}
+
+	const xpath_node_set& xpath_variable::get_node_set() const
+	{
+		return (_type == xpath_type_node_set) ? static_cast<const xpath_variable_node_set*>(this)->value : dummy_node_set;
+	}
+
+	bool xpath_variable::set(bool value)
+	{
+		if (_type != xpath_type_boolean) return false;
+
+		static_cast<xpath_variable_boolean*>(this)->value = value;
+		return true;
+	}
+
+	bool xpath_variable::set(double value)
+	{
+		if (_type != xpath_type_number) return false;
+
+		static_cast<xpath_variable_number*>(this)->value = value;
+		return true;
+	}
+
+	bool xpath_variable::set(const char_t* value)
+	{
+		if (_type != xpath_type_string) return false;
+
+		xpath_variable_string* var = static_cast<xpath_variable_string*>(this);
+
+		// duplicate string
+		size_t size = (strlength(value) + 1) * sizeof(char_t);
+
+		char_t* copy = static_cast<char_t*>(global_allocate(size));
+		if (!copy) return false;
+
+		memcpy(copy, value, size);
+
+		// replace old string
+		if (var->value) global_deallocate(var->value);
+		var->value = copy;
+
+		return true;
+	}
+
+	bool xpath_variable::set(const xpath_node_set& value)
+	{
+		if (_type != xpath_type_node_set) return false;
+
+		static_cast<xpath_variable_node_set*>(this)->value = value;
+		return true;
+	}
+
+	xpath_variable_set::xpath_variable_set()
+	{
+		for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) _data[i] = 0;
+	}
+
+	xpath_variable_set::~xpath_variable_set()
+	{
+		for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
+		{
+			xpath_variable* var = _data[i];
+
+			while (var)
+			{
+				xpath_variable* next = var->_next;
+
+				delete_xpath_variable(var->_type, var);
+
+				var = next;
+			}
+		}
+	}
+
+	xpath_variable* xpath_variable_set::find(const char_t* name) const
+	{
+		const size_t hash_size = sizeof(_data) / sizeof(_data[0]);
+		size_t hash = hash_string(name) % hash_size;
+
+		// look for existing variable
+		for (xpath_variable* var = _data[hash]; var; var = var->_next)
+			if (strequal(var->name(), name))
+				return var;
+
+		return 0;
+	}
+
+	xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type)
+	{
+		const size_t hash_size = sizeof(_data) / sizeof(_data[0]);
+		size_t hash = hash_string(name) % hash_size;
+
+		// look for existing variable
+		for (xpath_variable* var = _data[hash]; var; var = var->_next)
+			if (strequal(var->name(), name))
+				return var->type() == type ? var : 0;
+
+		// add new variable
+		xpath_variable* result = new_xpath_variable(type, name);
+
+		if (result)
+		{
+			result->_type = type;
+			result->_next = _data[hash];
+
+			_data[hash] = result;
+		}
+
+		return result;
+	}
+
+	bool xpath_variable_set::set(const char_t* name, bool value)
+	{
+		xpath_variable* var = add(name, xpath_type_boolean);
+		return var ? var->set(value) : false;
+	}
+
+	bool xpath_variable_set::set(const char_t* name, double value)
+	{
+		xpath_variable* var = add(name, xpath_type_number);
+		return var ? var->set(value) : false;
+	}
+
+	bool xpath_variable_set::set(const char_t* name, const char_t* value)
+	{
+		xpath_variable* var = add(name, xpath_type_string);
+		return var ? var->set(value) : false;
+	}
+
+	bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value)
+	{
+		xpath_variable* var = add(name, xpath_type_node_set);
+		return var ? var->set(value) : false;
+	}
+
+	xpath_variable* xpath_variable_set::get(const char_t* name)
+	{
+		return find(name);
+	}
+
+	const xpath_variable* xpath_variable_set::get(const char_t* name) const
+	{
+		return find(name);
+	}
+
+	xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0)
+	{
+		xpath_query_impl* impl = xpath_query_impl::create();
+
+		if (!impl)
+		{
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			_result.error = "Out of memory";
+        #else
+			throw std::bad_alloc();
+		#endif
+		}
+		else
+		{
+			buffer_holder impl_holder(impl, xpath_query_impl::destroy);
+
+			impl->root = xpath_parser::parse(query, variables, &impl->alloc, &_result);
+
+			if (impl->root)
+			{
+                _impl = static_cast<xpath_query_impl*>(impl_holder.release());
+				_result.error = 0;
+			}
+		}
+	}
+
+	xpath_query::~xpath_query()
+	{
+		xpath_query_impl::destroy(_impl);
+	}
+
+	xpath_value_type xpath_query::return_type() const
+	{
+		if (!_impl) return xpath_type_none;
+
+		return static_cast<xpath_query_impl*>(_impl)->root->rettype();
+	}
+
+	bool xpath_query::evaluate_boolean(const xpath_node& n) const
+	{
+		if (!_impl) return false;
+		
+		xpath_context c(n, 1, 1);
+		xpath_stack_data sd;
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		if (setjmp(sd.error_handler)) return false;
+	#endif
+		
+		return static_cast<xpath_query_impl*>(_impl)->root->eval_boolean(c, sd.stack);
+	}
+	
+	double xpath_query::evaluate_number(const xpath_node& n) const
+	{
+		if (!_impl) return gen_nan();
+		
+		xpath_context c(n, 1, 1);
+		xpath_stack_data sd;
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		if (setjmp(sd.error_handler)) return gen_nan();
+	#endif
+
+		return static_cast<xpath_query_impl*>(_impl)->root->eval_number(c, sd.stack);
+	}
+
+#ifndef PUGIXML_NO_STL
+	string_t xpath_query::evaluate_string(const xpath_node& n) const
+	{
+		xpath_stack_data sd;
+
+		return evaluate_string_impl(static_cast<xpath_query_impl*>(_impl), n, sd).c_str();
+	}
+#endif
+
+	size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const
+	{
+		xpath_stack_data sd;
+
+		xpath_string r = evaluate_string_impl(static_cast<xpath_query_impl*>(_impl), n, sd);
+
+		size_t full_size = r.length() + 1;
+		
+		if (capacity > 0)
+        {
+            size_t size = (full_size < capacity) ? full_size : capacity;
+            assert(size > 0);
+
+            memcpy(buffer, r.c_str(), (size - 1) * sizeof(char_t));
+            buffer[size - 1] = 0;
+        }
+		
+		return full_size;
+	}
+
+	xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const
+	{
+		if (!_impl) return xpath_node_set();
+
+        xpath_ast_node* root = static_cast<xpath_query_impl*>(_impl)->root;
+
+		if (root->rettype() != xpath_type_node_set)
+		{
+		#ifdef PUGIXML_NO_EXCEPTIONS
+			return xpath_node_set();
+		#else
+			xpath_parse_result result;
+			result.error = "Expression does not evaluate to node set";
+
+			throw xpath_exception(result);
+		#endif
+		}
+		
+		xpath_context c(n, 1, 1);
+		xpath_stack_data sd;
+
+	#ifdef PUGIXML_NO_EXCEPTIONS
+		if (setjmp(sd.error_handler)) return xpath_node_set();
+	#endif
+
+		xpath_node_set_raw r = root->eval_node_set(c, sd.stack);
+
+		return xpath_node_set(r.begin(), r.end(), r.type());
+	}
+
+	const xpath_parse_result& xpath_query::result() const
+	{
+		return _result;
+	}
+
+	xpath_query::operator xpath_query::unspecified_bool_type() const
+	{
+		return _impl ? &xpath_query::_impl : 0;
+	}
+
+	bool xpath_query::operator!() const
+	{
+		return !_impl;
+	}
+
+	xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const
+	{
+		xpath_query q(query, variables);
+		return select_single_node(q);
+	}
+
+	xpath_node xml_node::select_single_node(const xpath_query& query) const
+	{
+		xpath_node_set s = query.evaluate_node_set(*this);
+		return s.empty() ? xpath_node() : s.first();
+	}
+
+	xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const
+	{
+		xpath_query q(query, variables);
+		return select_nodes(q);
+	}
+
+	xpath_node_set xml_node::select_nodes(const xpath_query& query) const
+	{
+		return query.evaluate_node_set(*this);
+	}
+}
+
+#endif
+
+/**
+ * Copyright (c) 2006-2010 Arseny Kapoulkine
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
diff --git a/extensions/pugixml/src/pugixml.hpp b/extensions/pugixml/src/pugixml.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..4360996282234d5b917c8955b9d024e58533ac73
--- /dev/null
+++ b/extensions/pugixml/src/pugixml.hpp
@@ -0,0 +1,1131 @@
+/**
+ * pugixml parser - version 1.0
+ * --------------------------------------------------------
+ * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
+ * Report bugs and download new versions at http://pugixml.org/
+ *
+ * This library is distributed under the MIT License. See notice at the end
+ * of this file.
+ *
+ * This work is based on the pugxml parser, which is:
+ * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
+ */
+
+#ifndef HEADER_PUGIXML_HPP
+#define HEADER_PUGIXML_HPP
+
+#include "pugiconfig.hpp"
+
+#ifndef PUGIXML_NO_STL
+namespace std
+{
+	struct bidirectional_iterator_tag;
+
+#ifdef __SUNPRO_CC
+	// Sun C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions
+	template <class _T> class allocator;
+	template <class _charT> struct char_traits;
+	template <class _charT, class _Traits> class basic_istream;
+	template <class _charT, class _Traits> class basic_ostream;
+	template <class _charT, class _Traits, class _Allocator> class basic_string;
+#else
+	// Borland C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions
+	template <class _Ty> class allocator;
+	template <class _Ty> struct char_traits;
+	template <class _Elem, class _Traits> class basic_istream;
+	template <class _Elem, class _Traits> class basic_ostream;
+	template <class _Elem, class _Traits, class _Ax> class basic_string;
+#endif
+
+	// Digital Mars compiler has a bug which requires a forward declaration for explicit instantiation (otherwise type selection is messed up later, producing link errors)
+	// Also note that we have to declare char_traits as a class here, since it's defined that way
+#ifdef __DMC__
+	template <> class char_traits<char>;
+#endif
+}
+#endif
+
+// Macro for deprecated features
+#ifndef PUGIXML_DEPRECATED
+#	if defined(__GNUC__)
+#		define PUGIXML_DEPRECATED __attribute__((deprecated))
+#	elif defined(_MSC_VER) && _MSC_VER >= 1300
+#		define PUGIXML_DEPRECATED __declspec(deprecated)
+#	else
+#		define PUGIXML_DEPRECATED
+#	endif
+#endif
+
+// Include exception header for XPath
+#if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS)
+#	include <exception>
+#endif
+
+// If no API is defined, assume default
+#ifndef PUGIXML_API
+#   define PUGIXML_API
+#endif
+
+// If no API for classes is defined, assume default
+#ifndef PUGIXML_CLASS
+#   define PUGIXML_CLASS PUGIXML_API
+#endif
+
+// If no API for functions is defined, assume default
+#ifndef PUGIXML_FUNCTION
+#   define PUGIXML_FUNCTION PUGIXML_API
+#endif
+
+#include <stddef.h>
+
+// Character interface macros
+#ifdef PUGIXML_WCHAR_MODE
+#	define PUGIXML_TEXT(t) L ## t
+#	define PUGIXML_CHAR wchar_t
+#else
+#	define PUGIXML_TEXT(t) t
+#	define PUGIXML_CHAR char
+#endif
+
+namespace pugi
+{
+	// Character type used for all internal storage and operations; depends on PUGIXML_WCHAR_MODE
+	typedef PUGIXML_CHAR char_t;
+
+#ifndef PUGIXML_NO_STL
+	// String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE
+	typedef std::basic_string<PUGIXML_CHAR, std::char_traits<PUGIXML_CHAR>, std::allocator<PUGIXML_CHAR> > string_t;
+#endif
+}
+
+// The PugiXML namespace
+namespace pugi
+{
+	// Tree node types
+	enum xml_node_type
+	{
+		node_null,          // Empty (null) node handle
+		node_document,		// A document tree's absolute root
+		node_element,		// Element tag, i.e. '<node/>'
+		node_pcdata,		// Plain character data, i.e. 'text'
+		node_cdata,			// Character data, i.e. '<![CDATA[text]]>'
+		node_comment,		// Comment tag, i.e. '<!-- text -->'
+		node_pi,			// Processing instruction, i.e. '<?name?>'
+		node_declaration,	// Document declaration, i.e. '<?xml version="1.0"?>'
+        node_doctype        // Document type declaration, i.e. '<!DOCTYPE doc>'
+	};
+
+	// Parsing options
+
+	// Minimal parsing mode (equivalent to turning all other flags off).
+    // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed.
+	const unsigned int parse_minimal = 0x0000;
+
+	// This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default.
+	const unsigned int parse_pi = 0x0001;
+
+	// This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default.
+	const unsigned int parse_comments = 0x0002;
+
+	// This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default.
+	const unsigned int parse_cdata = 0x0004;
+
+	// This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree.
+    // This flag is off by default; turning it on usually results in slower parsing and more memory consumption.
+	const unsigned int parse_ws_pcdata = 0x0008;
+
+	// This flag determines if character and entity references are expanded during parsing. This flag is on by default.
+	const unsigned int parse_escapes = 0x0010;
+
+	// This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default.
+	const unsigned int parse_eol = 0x0020;
+	
+ 	// This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default.
+ 	const unsigned int parse_wconv_attribute = 0x0040;
+
+ 	// This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default.
+ 	const unsigned int parse_wnorm_attribute = 0x0080;
+	
+    // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default.
+	const unsigned int parse_declaration = 0x0100;
+
+    // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default.
+	const unsigned int parse_doctype = 0x0200;
+
+	// The default parsing mode.
+    // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded,
+    // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
+	const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol;
+
+    // The full parsing mode.
+    // Nodes of all types are added to the DOM tree, character/reference entities are expanded,
+    // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
+    const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype;
+
+	// These flags determine the encoding of input data for XML document
+	enum xml_encoding
+	{
+		encoding_auto,      // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found
+		encoding_utf8,      // UTF8 encoding
+		encoding_utf16_le,  // Little-endian UTF16
+		encoding_utf16_be,  // Big-endian UTF16
+		encoding_utf16,     // UTF16 with native endianness
+		encoding_utf32_le,  // Little-endian UTF32
+		encoding_utf32_be,  // Big-endian UTF32
+		encoding_utf32,     // UTF32 with native endianness
+		encoding_wchar      // The same encoding wchar_t has (either UTF16 or UTF32)
+	};
+
+	// Formatting flags
+	
+	// Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default.
+	const unsigned int format_indent = 0x01;
+	
+	// Write encoding-specific BOM to the output stream. This flag is off by default.
+	const unsigned int format_write_bom = 0x02;
+
+	// Use raw output mode (no indentation and no line breaks are written). This flag is off by default.
+	const unsigned int format_raw = 0x04;
+	
+	// Omit default XML declaration even if there is no declaration in the document. This flag is off by default.
+	const unsigned int format_no_declaration = 0x08;
+
+	// The default set of formatting flags.
+    // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none.
+	const unsigned int format_default = format_indent;
+		
+	// Forward declarations
+	struct xml_attribute_struct;
+	struct xml_node_struct;
+
+	class xml_node_iterator;
+	class xml_attribute_iterator;
+
+	class xml_tree_walker;
+	
+	class xml_node;
+
+	#ifndef PUGIXML_NO_XPATH
+	class xpath_node;
+	class xpath_node_set;
+	class xpath_query;
+	class xpath_variable_set;
+	#endif
+
+	// Writer interface for node printing (see xml_node::print)
+	class PUGIXML_CLASS xml_writer
+	{
+	public:
+		virtual ~xml_writer() {}
+
+		// Write memory chunk into stream/file/whatever
+		virtual void write(const void* data, size_t size) = 0;
+	};
+
+	// xml_writer implementation for FILE*
+	class PUGIXML_CLASS xml_writer_file: public xml_writer
+	{
+	public:
+        // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio
+		xml_writer_file(void* file);
+
+		virtual void write(const void* data, size_t size);
+
+	private:
+		void* file;
+	};
+
+	#ifndef PUGIXML_NO_STL
+	// xml_writer implementation for streams
+	class PUGIXML_CLASS xml_writer_stream: public xml_writer
+	{
+	public:
+        // Construct writer from an output stream object
+		xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream);
+		xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream);
+
+		virtual void write(const void* data, size_t size);
+
+	private:
+		std::basic_ostream<char, std::char_traits<char> >* narrow_stream;
+		std::basic_ostream<wchar_t, std::char_traits<wchar_t> >* wide_stream;
+	};
+	#endif
+
+	// A light-weight handle for manipulating attributes in DOM tree
+	class PUGIXML_CLASS xml_attribute
+	{
+		friend class xml_attribute_iterator;
+		friend class xml_node;
+
+	private:
+		xml_attribute_struct* _attr;
+	
+    	typedef xml_attribute_struct* xml_attribute::*unspecified_bool_type;
+
+	public:
+        // Default constructor. Constructs an empty attribute.
+		xml_attribute();
+		
+        // Constructs attribute from internal pointer
+		explicit xml_attribute(xml_attribute_struct* attr);
+
+    	// Safe bool conversion operator
+    	operator unspecified_bool_type() const;
+
+    	// Borland C++ workaround
+    	bool operator!() const;
+
+		// Comparison operators (compares wrapped attribute pointers)
+		bool operator==(const xml_attribute& r) const;
+		bool operator!=(const xml_attribute& r) const;
+		bool operator<(const xml_attribute& r) const;
+		bool operator>(const xml_attribute& r) const;
+		bool operator<=(const xml_attribute& r) const;
+		bool operator>=(const xml_attribute& r) const;
+
+		// Check if attribute is empty
+		bool empty() const;
+
+		// Get attribute name/value, or "" if attribute is empty
+		const char_t* name() const;
+		const char_t* value() const;
+
+		// Get attribute value as a number, or 0 if conversion did not succeed or attribute is empty
+		int as_int() const;
+		unsigned int as_uint() const;
+		double as_double() const;
+		float as_float() const;
+
+        // Get attribute value as bool (returns true if first character is in '1tTyY' set), or false if attribute is empty
+		bool as_bool() const;
+
+        // Set attribute name/value (returns false if attribute is empty or there is not enough memory)
+		bool set_name(const char_t* rhs);
+		bool set_value(const char_t* rhs);
+
+        // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
+		bool set_value(int rhs);
+		bool set_value(unsigned int rhs);
+		bool set_value(double rhs);
+		bool set_value(bool rhs);
+
+		// Set attribute value (equivalent to set_value without error checking)
+		xml_attribute& operator=(const char_t* rhs);
+		xml_attribute& operator=(int rhs);
+		xml_attribute& operator=(unsigned int rhs);
+		xml_attribute& operator=(double rhs);
+		xml_attribute& operator=(bool rhs);
+
+        // Get next/previous attribute in the attribute list of the parent node
+    	xml_attribute next_attribute() const;
+    	xml_attribute previous_attribute() const;
+
+        // Get hash value (unique for handles to the same object)
+        size_t hash_value() const;
+
+		// Get internal pointer
+		xml_attribute_struct* internal_object() const;
+	};
+
+#ifdef __BORLANDC__
+	// Borland C++ workaround
+	bool PUGIXML_FUNCTION operator&&(const xml_attribute& lhs, bool rhs);
+	bool PUGIXML_FUNCTION operator||(const xml_attribute& lhs, bool rhs);
+#endif
+
+	// A light-weight handle for manipulating nodes in DOM tree
+	class PUGIXML_CLASS xml_node
+	{
+		friend class xml_attribute_iterator;
+		friend class xml_node_iterator;
+
+	protected:
+		xml_node_struct* _root;
+
+    	typedef xml_node_struct* xml_node::*unspecified_bool_type;
+
+	public:
+		// Default constructor. Constructs an empty node.
+		xml_node();
+
+        // Constructs node from internal pointer
+		explicit xml_node(xml_node_struct* p);
+
+    	// Safe bool conversion operator
+		operator unspecified_bool_type() const;
+
+		// Borland C++ workaround
+		bool operator!() const;
+	
+		// Comparison operators (compares wrapped node pointers)
+		bool operator==(const xml_node& r) const;
+		bool operator!=(const xml_node& r) const;
+		bool operator<(const xml_node& r) const;
+		bool operator>(const xml_node& r) const;
+		bool operator<=(const xml_node& r) const;
+		bool operator>=(const xml_node& r) const;
+
+		// Check if node is empty.
+		bool empty() const;
+
+		// Get node type
+		xml_node_type type() const;
+
+		// Get node name/value, or "" if node is empty or it has no name/value
+		const char_t* name() const;
+		const char_t* value() const;
+	
+		// Get attribute list
+		xml_attribute first_attribute() const;
+        xml_attribute last_attribute() const;
+
+        // Get children list
+		xml_node first_child() const;
+        xml_node last_child() const;
+
+        // Get next/previous sibling in the children list of the parent node
+		xml_node next_sibling() const;
+		xml_node previous_sibling() const;
+		
+        // Get parent node
+		xml_node parent() const;
+
+		// Get root of DOM tree this node belongs to
+		xml_node root() const;
+
+		// Get child, attribute or next/previous sibling with the specified name
+		xml_node child(const char_t* name) const;
+		xml_attribute attribute(const char_t* name) const;
+		xml_node next_sibling(const char_t* name) const;
+		xml_node previous_sibling(const char_t* name) const;
+
+		// Get child value of current node; that is, value of the first child node of type PCDATA/CDATA
+		const char_t* child_value() const;
+
+		// Get child value of child with specified name. Equivalent to child(name).child_value().
+		const char_t* child_value(const char_t* name) const;
+
+		// Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value)
+		bool set_name(const char_t* rhs);
+		bool set_value(const char_t* rhs);
+		
+		// Add attribute with specified name. Returns added attribute, or empty attribute on errors.
+		xml_attribute append_attribute(const char_t* name);
+		xml_attribute prepend_attribute(const char_t* name);
+		xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
+		xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
+
+		// Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors.
+		xml_attribute append_copy(const xml_attribute& proto);
+		xml_attribute prepend_copy(const xml_attribute& proto);
+		xml_attribute insert_copy_after(const xml_attribute& proto, const xml_attribute& attr);
+		xml_attribute insert_copy_before(const xml_attribute& proto, const xml_attribute& attr);
+
+		// Add child node with specified type. Returns added node, or empty node on errors.
+		xml_node append_child(xml_node_type type = node_element);
+		xml_node prepend_child(xml_node_type type = node_element);
+		xml_node insert_child_after(xml_node_type type, const xml_node& node);
+		xml_node insert_child_before(xml_node_type type, const xml_node& node);
+
+		// Add child element with specified name. Returns added node, or empty node on errors.
+		xml_node append_child(const char_t* name);
+		xml_node prepend_child(const char_t* name);
+		xml_node insert_child_after(const char_t* name, const xml_node& node);
+		xml_node insert_child_before(const char_t* name, const xml_node& node);
+
+		// Add a copy of the specified node as a child. Returns added node, or empty node on errors.
+		xml_node append_copy(const xml_node& proto);
+		xml_node prepend_copy(const xml_node& proto);
+		xml_node insert_copy_after(const xml_node& proto, const xml_node& node);
+		xml_node insert_copy_before(const xml_node& proto, const xml_node& node);
+
+		// Remove specified attribute
+		bool remove_attribute(const xml_attribute& a);
+		bool remove_attribute(const char_t* name);
+
+		// Remove specified child
+		bool remove_child(const xml_node& n);
+		bool remove_child(const char_t* name);
+
+		// Find attribute using predicate. Returns first attribute for which predicate returned true.
+		template <typename Predicate> xml_attribute find_attribute(Predicate pred) const
+		{
+			if (!_root) return xml_attribute();
+			
+			for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute())
+				if (pred(attrib))
+					return attrib;
+		
+			return xml_attribute();
+		}
+
+		// Find child node using predicate. Returns first child for which predicate returned true.
+		template <typename Predicate> xml_node find_child(Predicate pred) const
+		{
+			if (!_root) return xml_node();
+	
+			for (xml_node node = first_child(); node; node = node.next_sibling())
+				if (pred(node))
+					return node;
+        
+	        return xml_node();
+		}
+
+		// Find node from subtree using predicate. Returns first node from subtree (depth-first), for which predicate returned true.
+		template <typename Predicate> xml_node find_node(Predicate pred) const
+		{
+			if (!_root) return xml_node();
+
+			xml_node cur = first_child();
+			
+			while (cur._root && cur._root != _root)
+			{
+				if (pred(cur)) return cur;
+
+				if (cur.first_child()) cur = cur.first_child();
+				else if (cur.next_sibling()) cur = cur.next_sibling();
+				else
+				{
+					while (!cur.next_sibling() && cur._root != _root) cur = cur.parent();
+
+					if (cur._root != _root) cur = cur.next_sibling();
+				}
+			}
+
+			return xml_node();
+		}
+
+		// Find child node by attribute name/value
+		xml_node find_child_by_attribute(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
+		xml_node find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const;
+
+	#ifndef PUGIXML_NO_STL
+		// Get the absolute node path from root as a text string.
+		string_t path(char_t delimiter = '/') const;
+	#endif
+
+		// Search for a node by path consisting of node names and . or .. elements.
+		xml_node first_element_by_path(const char_t* path, char_t delimiter = '/') const;
+
+		// Recursively traverse subtree with xml_tree_walker
+		bool traverse(xml_tree_walker& walker);
+	
+	#ifndef PUGIXML_NO_XPATH
+		// Select single node by evaluating XPath query. Returns first node from the resulting node set.
+		xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const;
+		xpath_node select_single_node(const xpath_query& query) const;
+
+		// Select node set by evaluating XPath query
+		xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const;
+		xpath_node_set select_nodes(const xpath_query& query) const;
+	#endif
+		
+		// Print subtree using a writer object
+		void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
+
+	#ifndef PUGIXML_NO_STL
+		// Print subtree to stream
+		void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
+		void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
+	#endif
+
+		// Child nodes iterators
+		typedef xml_node_iterator iterator;
+
+		iterator begin() const;
+		iterator end() const;
+
+		// Attribute iterators
+		typedef xml_attribute_iterator attribute_iterator;
+
+		attribute_iterator attributes_begin() const;
+		attribute_iterator attributes_end() const;
+
+		// Get node offset in parsed file/string (in char_t units) for debugging purposes
+		ptrdiff_t offset_debug() const;
+
+        // Get hash value (unique for handles to the same object)
+        size_t hash_value() const;
+
+		// Get internal pointer
+		xml_node_struct* internal_object() const;
+	};
+
+#ifdef __BORLANDC__
+	// Borland C++ workaround
+	bool PUGIXML_FUNCTION operator&&(const xml_node& lhs, bool rhs);
+	bool PUGIXML_FUNCTION operator||(const xml_node& lhs, bool rhs);
+#endif
+
+	// Child node iterator (a bidirectional iterator over a collection of xml_node)
+	class PUGIXML_CLASS xml_node_iterator
+	{
+		friend class xml_node;
+
+	private:
+		xml_node _wrap;
+		xml_node _parent;
+
+		xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent);
+
+	public:
+		// Iterator traits
+		typedef ptrdiff_t difference_type;
+		typedef xml_node value_type;
+		typedef xml_node* pointer;
+		typedef xml_node& reference;
+
+	#ifndef PUGIXML_NO_STL
+		typedef std::bidirectional_iterator_tag iterator_category;
+	#endif
+
+        // Default constructor
+		xml_node_iterator();
+
+        // Construct an iterator which points to the specified node
+		xml_node_iterator(const xml_node& node);
+
+        // Iterator operators
+		bool operator==(const xml_node_iterator& rhs) const;
+		bool operator!=(const xml_node_iterator& rhs) const;
+
+		xml_node& operator*();
+		xml_node* operator->();
+
+		const xml_node_iterator& operator++();
+		xml_node_iterator operator++(int);
+
+		const xml_node_iterator& operator--();
+		xml_node_iterator operator--(int);
+	};
+
+	// Attribute iterator (a bidirectional iterator over a collection of xml_attribute)
+	class PUGIXML_CLASS xml_attribute_iterator
+	{
+		friend class xml_node;
+
+	private:
+		xml_attribute _wrap;
+		xml_node _parent;
+
+		xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent);
+
+	public:
+		// Iterator traits
+		typedef ptrdiff_t difference_type;
+		typedef xml_attribute value_type;
+		typedef xml_attribute* pointer;
+		typedef xml_attribute& reference;
+
+	#ifndef PUGIXML_NO_STL
+		typedef std::bidirectional_iterator_tag iterator_category;
+	#endif
+
+        // Default constructor
+		xml_attribute_iterator();
+
+        // Construct an iterator which points to the specified attribute
+		xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent);
+
+		// Iterator operators
+		bool operator==(const xml_attribute_iterator& rhs) const;
+		bool operator!=(const xml_attribute_iterator& rhs) const;
+
+		xml_attribute& operator*();
+		xml_attribute* operator->();
+
+		const xml_attribute_iterator& operator++();
+		xml_attribute_iterator operator++(int);
+
+		const xml_attribute_iterator& operator--();
+		xml_attribute_iterator operator--(int);
+	};
+
+	// Abstract tree walker class (see xml_node::traverse)
+	class PUGIXML_CLASS xml_tree_walker
+	{
+		friend class xml_node;
+
+	private:
+		int _depth;
+	
+	protected:
+		// Get current traversal depth
+		int depth() const;
+	
+	public:
+		xml_tree_walker();
+		virtual ~xml_tree_walker();
+
+		// Callback that is called when traversal begins
+		virtual bool begin(xml_node& node);
+
+		// Callback that is called for each node traversed
+		virtual bool for_each(xml_node& node) = 0;
+
+		// Callback that is called when traversal ends
+		virtual bool end(xml_node& node);
+	};
+
+	// Parsing status, returned as part of xml_parse_result object
+	enum xml_parse_status
+	{
+		status_ok = 0,              // No error
+
+		status_file_not_found,      // File was not found during load_file()
+		status_io_error,            // Error reading from file/stream
+		status_out_of_memory,       // Could not allocate memory
+		status_internal_error,      // Internal error occurred
+
+		status_unrecognized_tag,    // Parser could not determine tag type
+
+		status_bad_pi,              // Parsing error occurred while parsing document declaration/processing instruction
+		status_bad_comment,         // Parsing error occurred while parsing comment
+		status_bad_cdata,           // Parsing error occurred while parsing CDATA section
+		status_bad_doctype,         // Parsing error occurred while parsing document type declaration
+		status_bad_pcdata,          // Parsing error occurred while parsing PCDATA section
+		status_bad_start_element,   // Parsing error occurred while parsing start element tag
+		status_bad_attribute,       // Parsing error occurred while parsing element attribute
+		status_bad_end_element,     // Parsing error occurred while parsing end element tag
+		status_end_element_mismatch // There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag)
+	};
+
+	// Parsing result
+	struct PUGIXML_CLASS xml_parse_result
+	{
+		// Parsing status (see xml_parse_status)
+		xml_parse_status status;
+
+		// Last parsed offset (in char_t units from start of input data)
+		ptrdiff_t offset;
+
+		// Source document encoding
+		xml_encoding encoding;
+
+        // Default constructor, initializes object to failed state
+		xml_parse_result();
+
+		// Cast to bool operator
+		operator bool() const;
+
+		// Get error description
+		const char* description() const;
+	};
+
+	// Document class (DOM tree root)
+	class PUGIXML_CLASS xml_document: public xml_node
+	{
+	private:
+		char_t* _buffer;
+
+		char _memory[192];
+		
+		// Non-copyable semantics
+		xml_document(const xml_document&);
+		const xml_document& operator=(const xml_document&);
+
+		void create();
+		void destroy();
+
+		xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own);
+
+	public:
+		// Default constructor, makes empty document
+		xml_document();
+
+		// Destructor, invalidates all node/attribute handles to this document
+		~xml_document();
+
+        // Removes all nodes, leaving the empty document
+		void reset();
+
+        // Removes all nodes, then copies the entire contents of the specified document
+		void reset(const xml_document& proto);
+
+	#ifndef PUGIXML_NO_STL
+		// Load document from stream.
+		xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+		xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default);
+	#endif
+
+		// Load document from zero-terminated string. No encoding conversions are applied.
+		xml_parse_result load(const char_t* contents, unsigned int options = parse_default);
+
+		// Load document from file
+		xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+		xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
+		// Load document from buffer. Copies/converts the buffer, so it may be deleted or changed after the function returns.
+		xml_parse_result load_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
+		// Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data).
+        // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed.
+		xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
+		// Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data).
+        // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore).
+		xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
+
+		// Save XML document to writer (semantics is slightly different from xml_node::print, see documentation for details).
+		void save(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+
+	#ifndef PUGIXML_NO_STL
+		// Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details).
+		void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+		void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
+	#endif
+
+		// Save XML to file
+		bool save_file(const char* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+		bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
+
+        // Get document element
+        xml_node document_element() const;
+	};
+
+#ifndef PUGIXML_NO_XPATH
+	// XPath query return type
+	enum xpath_value_type
+	{
+		xpath_type_none,      // Unknown type (query failed to compile)
+		xpath_type_node_set,  // Node set (xpath_node_set)
+		xpath_type_number,    // Number
+		xpath_type_string,    // String
+		xpath_type_boolean    // Boolean
+	};
+
+    // XPath parsing result
+	struct PUGIXML_CLASS xpath_parse_result
+	{
+		// Error message (0 if no error)
+		const char* error;
+
+		// Last parsed offset (in char_t units from string start)
+		ptrdiff_t offset;
+
+        // Default constructor, initializes object to failed state
+		xpath_parse_result();
+
+		// Cast to bool operator
+		operator bool() const;
+
+		// Get error description
+		const char* description() const;
+	};
+
+	// A single XPath variable
+	class PUGIXML_CLASS xpath_variable
+	{
+		friend class xpath_variable_set;
+
+	protected:
+		xpath_value_type _type;
+		xpath_variable* _next;
+
+		xpath_variable();
+
+		// Non-copyable semantics
+		xpath_variable(const xpath_variable&);
+		xpath_variable& operator=(const xpath_variable&);
+		
+	public:
+        // Get variable name
+		const char_t* name() const;
+
+        // Get variable type
+		xpath_value_type type() const;
+
+        // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error
+		bool get_boolean() const;
+		double get_number() const;
+		const char_t* get_string() const;
+		const xpath_node_set& get_node_set() const;
+
+        // Set variable value; no type conversion is performed, false is returned on type mismatch error
+		bool set(bool value);
+		bool set(double value);
+		bool set(const char_t* value);
+		bool set(const xpath_node_set& value);
+	};
+
+	// A set of XPath variables
+	class PUGIXML_CLASS xpath_variable_set
+	{
+	private:
+		xpath_variable* _data[64];
+
+		// Non-copyable semantics
+		xpath_variable_set(const xpath_variable_set&);
+		xpath_variable_set& operator=(const xpath_variable_set&);
+
+		xpath_variable* find(const char_t* name) const;
+
+	public:
+        // Default constructor/destructor
+		xpath_variable_set();
+		~xpath_variable_set();
+
+        // Add a new variable or get the existing one, if the types match
+		xpath_variable* add(const char_t* name, xpath_value_type type);
+
+        // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch
+		bool set(const char_t* name, bool value);
+		bool set(const char_t* name, double value);
+		bool set(const char_t* name, const char_t* value);
+		bool set(const char_t* name, const xpath_node_set& value);
+
+        // Get existing variable by name
+		xpath_variable* get(const char_t* name);
+		const xpath_variable* get(const char_t* name) const;
+	};
+
+	// A compiled XPath query object
+	class PUGIXML_CLASS xpath_query
+	{
+	private:
+		void* _impl;
+		xpath_parse_result _result;
+
+    	typedef void* xpath_query::*unspecified_bool_type;
+
+		// Non-copyable semantics
+		xpath_query(const xpath_query&);
+		xpath_query& operator=(const xpath_query&);
+
+	public:
+        // Construct a compiled object from XPath expression.
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors.
+		explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0);
+
+		// Destructor
+		~xpath_query();
+
+		// Get query expression return type
+		xpath_value_type return_type() const;
+		
+		// Evaluate expression as boolean value in the specified context; performs type conversion if necessary.
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
+		bool evaluate_boolean(const xpath_node& n) const;
+		
+		// Evaluate expression as double value in the specified context; performs type conversion if necessary.
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
+		double evaluate_number(const xpath_node& n) const;
+		
+	#ifndef PUGIXML_NO_STL
+		// Evaluate expression as string value in the specified context; performs type conversion if necessary.
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
+		string_t evaluate_string(const xpath_node& n) const;
+	#endif
+		
+		// Evaluate expression as string value in the specified context; performs type conversion if necessary.
+        // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero).
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
+        // If PUGIXML_NO_EXCEPTIONS is defined, returns empty  set instead.
+		size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
+
+		// Evaluate expression as node set in the specified context.
+        // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors.
+        // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead.
+		xpath_node_set evaluate_node_set(const xpath_node& n) const;
+
+		// Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode)
+		const xpath_parse_result& result() const;
+
+		// Safe bool conversion operator
+		operator unspecified_bool_type() const;
+
+    	// Borland C++ workaround
+		bool operator!() const;
+	};
+	
+	#ifndef PUGIXML_NO_EXCEPTIONS
+	// XPath exception class
+	class PUGIXML_CLASS xpath_exception: public std::exception
+	{
+	private:
+		xpath_parse_result _result;
+
+	public:
+		// Construct exception from parse result
+		explicit xpath_exception(const xpath_parse_result& result);
+
+		// Get error message
+		virtual const char* what() const throw();
+
+        // Get parse result
+		const xpath_parse_result& result() const;
+	};
+	#endif
+	
+	// XPath node class (either xml_node or xml_attribute)
+	class PUGIXML_CLASS xpath_node
+	{
+	private:
+		xml_node _node;
+		xml_attribute _attribute;
+	
+    	typedef xml_node xpath_node::*unspecified_bool_type;
+
+	public:
+		// Default constructor; constructs empty XPath node
+		xpath_node();
+		
+		// Construct XPath node from XML node/attribute
+		xpath_node(const xml_node& node);
+		xpath_node(const xml_attribute& attribute, const xml_node& parent);
+
+		// Get node/attribute, if any
+		xml_node node() const;
+		xml_attribute attribute() const;
+		
+		// Get parent of contained node/attribute
+		xml_node parent() const;
+
+    	// Safe bool conversion operator
+		operator unspecified_bool_type() const;
+		
+    	// Borland C++ workaround
+    	bool operator!() const;
+
+		// Comparison operators
+		bool operator==(const xpath_node& n) const;
+		bool operator!=(const xpath_node& n) const;
+	};
+
+#ifdef __BORLANDC__
+	// Borland C++ workaround
+	bool PUGIXML_FUNCTION operator&&(const xpath_node& lhs, bool rhs);
+	bool PUGIXML_FUNCTION operator||(const xpath_node& lhs, bool rhs);
+#endif
+
+	// A fixed-size collection of XPath nodes
+	class PUGIXML_CLASS xpath_node_set
+	{
+	public:
+		// Collection type
+		enum type_t
+		{
+			type_unsorted,			// Not ordered
+			type_sorted,			// Sorted by document order (ascending)
+			type_sorted_reverse		// Sorted by document order (descending)
+		};
+		
+		// Constant iterator type
+		typedef const xpath_node* const_iterator;
+	
+		// Default constructor. Constructs empty set.
+		xpath_node_set();
+
+		// Constructs a set from iterator range; data is not checked for duplicates and is not sorted according to provided type, so be careful
+		xpath_node_set(const_iterator begin, const_iterator end, type_t type = type_unsorted);
+
+		// Destructor
+		~xpath_node_set();
+		
+		// Copy constructor/assignment operator
+		xpath_node_set(const xpath_node_set& ns);
+		xpath_node_set& operator=(const xpath_node_set& ns);
+
+		// Get collection type
+		type_t type() const;
+		
+		// Get collection size
+		size_t size() const;
+
+        // Indexing operator
+		const xpath_node& operator[](size_t index) const;
+		
+		// Collection iterators
+		const_iterator begin() const;
+		const_iterator end() const;
+
+		// Sort the collection in ascending/descending order by document order
+		void sort(bool reverse = false);
+		
+		// Get first node in the collection by document order
+		xpath_node first() const;
+		
+		// Check if collection is empty
+		bool empty() const;
+    
+	private:
+		type_t _type;
+		
+		xpath_node _storage;
+		
+		xpath_node* _begin;
+		xpath_node* _end;
+
+		void _assign(const_iterator begin, const_iterator end);
+	};
+#endif
+
+#ifndef PUGIXML_NO_STL
+	// Convert wide string to UTF8
+	std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str);
+	std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str);
+	
+	// Convert UTF8 to wide string
+	std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str);
+	std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >& str);
+#endif
+
+	// Memory allocation function interface; returns pointer to allocated memory or NULL on failure
+	typedef void* (*allocation_function)(size_t size);
+	
+	// Memory deallocation function interface
+    typedef void (*deallocation_function)(void* ptr);
+
+    // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions.
+    void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate);
+    
+    // Get current memory management functions
+    allocation_function PUGIXML_FUNCTION get_memory_allocation_function();
+    deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function();
+}
+
+#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
+namespace std
+{
+	// Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier)
+	std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&);
+	std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&);
+}
+#endif
+
+#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
+namespace std
+{
+	// Workarounds for (non-standard) iterator category detection
+	std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&);
+	std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&);
+}
+#endif
+
+#endif
+
+/**
+ * Copyright (c) 2006-2010 Arseny Kapoulkine
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
diff --git a/extensions/time/ExtendedRosenbrockAdaptInstationary.h b/extensions/time/ExtendedRosenbrockAdaptInstationary.h
new file mode 100644
index 0000000000000000000000000000000000000000..d41c6e5d241f6e778ca32b7e8e4636ebb2e6be65
--- /dev/null
+++ b/extensions/time/ExtendedRosenbrockAdaptInstationary.h
@@ -0,0 +1,131 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ==  http://www.amdis-fem.org                                              ==
+// ==                                                                        ==
+// ============================================================================
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+
+/** \file ExtendedRosenbrockAdaptInstationary.h */
+
+#ifndef MY_ROSENBROCKADAPTINSTATIONARY_H
+#define MY_ROSENBROCKADAPTINSTATIONARY_H
+
+#include "AMDiS_fwd.h"
+#include "time/RosenbrockMethod.h"
+#include "AdaptInstationary.h"
+#include "CreatorMap.h"
+
+namespace AMDiS {
+
+  template<typename ProblemStationary>
+  class ExtendedRosenbrockAdaptInstationary : public AdaptInstationary
+  { 
+  public:
+    /** \brief
+     * Creates a AdaptInstationary object for Rosenbrock method
+     * with the given name for the time 
+     * dependent problem problemInstat. TODO: Make obsolete!
+     */
+    ExtendedRosenbrockAdaptInstationary(std::string name,
+				ProblemStationary *problemStat,
+				AdaptInfo *info,
+				ProblemTimeInterface *problemInstat,
+				AdaptInfo *initialInfo,
+				time_t initialTimestamp = 0);
+
+    /** \brief
+     * Creates a AdaptInstationary object for Rosenbrock method
+     * with the given name for the time 
+     * dependent problem problemInstat. 
+     */
+    ExtendedRosenbrockAdaptInstationary(std::string name,
+				ProblemStationary &problemStat,
+				AdaptInfo &info,
+				ProblemTimeInterface &problemInstat,
+				AdaptInfo &initialInfo,
+				time_t initialTimestamp = 0);
+
+    /// Runs the Rosenbrock loop until one timestep is accepted.
+    void oneTimestep();
+
+    /** \brief
+     * This funciton is used only to avoid double code in both constructors. If the
+     * obsolte constructure, which uses pointers instead of references, will be
+     * removed, remove also this function.
+     * TODO: Remove if obsolete constructor will be removed.
+     */
+    void initConstructor(ProblemStationary *problemStat);
+
+    void reset();
+
+  protected:
+    /// Pointer to the Rosenbrock method that should be used.
+    RosenbrockMethod *rosenbrockMethod;
+
+    /// Pointer to the stationary problem;
+    ProblemStationary *rosenbrockStat;
+
+    /// Indicates, if this is the very first timestep.
+    bool firstTimestep;
+
+    /// If true, the last timestep was rejected.
+    bool lastTimestepRejected;
+
+
+    /// If true, more than one of the last timesteps were rejected.
+    bool succRejection;
+
+    /// If greater than 0, than for the first given number of timesteps the timestep
+    /// will be not changed and is set to the very first one.
+    int fixFirstTimesteps;
+    
+    /// Timestep of the last accepted time iteration.
+    double tauAcc;
+
+    /// Error estimation of the last accepted time iteration.
+    double estAcc;
+
+    /// Timestep of the last rejected time iteration.
+    double tauRej;
+
+    /// Error estimation of the last rejected time iteration.
+    double estRej;
+
+    /// Current timestep.
+    double tau;
+
+    /// The value tau * gamma, where gamma is a value of the used 
+    /// Rosenbrock method.
+    double tauGamma, minusTauGamma, invTauGamma, minusInvTauGamma;
+
+    /// If true, the first timestep is calculated with different timesteps. 
+    /// This is usually used to make a study how the time error estimator 
+    /// behavous for different timesteps.
+    bool dbgTimestepStudy;
+
+    /// If \ref dbgTimestepStudy is set to true, then this array contains the
+    /// timesteps for which the first timestep should be calculated.
+    vector<double> dbgTimesteps;
+
+    vector<double> errorEstWeights;
+      
+  };
+ 
+}
+
+#include "ExtendedRosenbrockAdaptInstationary.hh"
+
+#endif // MY_ROSENBROCKADAPTINSTATIONARY_H
diff --git a/extensions/time/ExtendedRosenbrockAdaptInstationary.hh b/extensions/time/ExtendedRosenbrockAdaptInstationary.hh
new file mode 100644
index 0000000000000000000000000000000000000000..7a4192fdd84eba96ae1095552193922c600ec603
--- /dev/null
+++ b/extensions/time/ExtendedRosenbrockAdaptInstationary.hh
@@ -0,0 +1,273 @@
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+#include "time/ExtendedRosenbrockAdaptInstationary.h"
+#include "AdaptInfo.h"
+#include "ProblemTimeInterface.h"
+#include "VectorOperations.h"
+
+namespace AMDiS {
+
+  template<typename ProblemStationary>
+  ExtendedRosenbrockAdaptInstationary<ProblemStationary>::ExtendedRosenbrockAdaptInstationary(std::string name,
+							   ProblemStationary *problemStat,
+							   AdaptInfo *info,
+							   ProblemTimeInterface *problemInstat,
+							   AdaptInfo *initialInfo,
+							   time_t initialTimestamp)
+    : AdaptInstationary(name, problemStat, info, problemInstat, initialInfo, initialTimestamp),
+      rosenbrockStat(problemStat),
+      firstTimestep(true),
+      lastTimestepRejected(false),
+      succRejection(false),
+      fixFirstTimesteps(0),
+      tau(1.0),
+      tauGamma(1.0),
+      minusTauGamma(-1.0),
+      invTauGamma(1.0),
+      minusInvTauGamma(-1.0),
+      dbgTimestepStudy(false)
+  {
+    FUNCNAME("ExtendedRosenbrockAdaptInstationary::ExtendedRosenbrockAdaptInstationary()");
+    initConstructor(problemStat);
+  }
+
+
+  template<typename ProblemStationary>
+  ExtendedRosenbrockAdaptInstationary<ProblemStationary>::ExtendedRosenbrockAdaptInstationary(std::string name,
+							   ProblemStationary &problemStat,
+							   AdaptInfo &info,
+							   ProblemTimeInterface &problemInstat,
+							   AdaptInfo &initialInfo,
+							   time_t initialTimestamp)
+    : AdaptInstationary(name, problemStat, info, problemInstat, initialInfo, initialTimestamp),
+      rosenbrockStat(&problemStat),
+      firstTimestep(true),
+      lastTimestepRejected(false),
+      succRejection(false),
+      fixFirstTimesteps(0),
+      tau(1.0),
+      tauGamma(1.0),
+      minusTauGamma(-1.0),
+      invTauGamma(1.0),
+      minusInvTauGamma(-1.0),
+      dbgTimestepStudy(false)
+  {
+    FUNCNAME("ExtendedRosenbrockAdaptInstationary::ExtendedRosenbrockAdaptInstationary()");
+    initConstructor(&problemStat);
+  }
+
+
+  template<typename ProblemStationary>
+  void ExtendedRosenbrockAdaptInstationary<ProblemStationary>::initConstructor(ProblemStationary *problemStat)
+  {
+    FUNCNAME("ExtendedRosenbrockAdaptInstationary::initConstructor()");
+
+    std::string str("");
+    std::string initFileStr(name + "->rosenbrock method");
+    Parameters::get(initFileStr, str);
+    RosenbrockMethodCreator *creator = 
+      dynamic_cast<RosenbrockMethodCreator*>(CreatorMap<RosenbrockMethod>::getCreator(str, initFileStr));
+    rosenbrockMethod = creator->create();
+    
+    TEST_EXIT_DBG(rosenbrockMethod)("This should not happen!\n");
+    
+    Parameters::get(name + "->fix first timesteps", fixFirstTimesteps);
+    rosenbrockStat->setRosenbrockMethod(rosenbrockMethod);
+    
+    adaptInfo->setRosenbrockMode(true);
+    
+    rosenbrockStat->setTauGamma(&tauGamma, &minusTauGamma,
+			     &invTauGamma, &minusInvTauGamma);
+    rosenbrockStat->setTau(&tau);
+    
+    Parameters::get(name + "->rosenbrock->timestep study", dbgTimestepStudy);
+    Parameters::get(name + "->rosenbrock->timestep study steps", dbgTimesteps);
+
+    Parameters::get(name + "->rosenbrock->error weights", errorEstWeights);
+    if (errorEstWeights.size() == 0) {
+      WARNING("No weights for time-error estimation given.\n");
+    }
+
+    errorEstWeights.resize(adaptInfo->getSize(), 0.0);
+    double SumErrorEstWeights = vector_operations::sum(errorEstWeights);
+    if (SumErrorEstWeights<DBL_TOL) {
+      WARNING("Using equal weights for all components!\n");
+      for (size_t i = 0; i < errorEstWeights.size(); i++)
+	errorEstWeights[i] = 1.0/static_cast<double>(adaptInfo->getSize());
+    } else {
+      for (size_t i = 0; i < errorEstWeights.size(); i++)
+	errorEstWeights[i] *= 1.0/SumErrorEstWeights;
+    }
+  }
+
+
+  template<typename ProblemStationary>
+  void ExtendedRosenbrockAdaptInstationary<ProblemStationary>::reset()
+  {
+    FUNCNAME("ExtendedRosenbrockAdaptInstationary::reset()");
+
+    firstTimestep = true;
+    lastTimestepRejected = false;
+    succRejection = false;
+    fixFirstTimesteps = 0;
+    tau = 1.0;
+    tauGamma = 1.0;    
+    minusTauGamma = -1.0;
+    invTauGamma = 1.0;
+    minusInvTauGamma = -1.0;
+  }
+
+
+  template<typename ProblemStationary>
+  void ExtendedRosenbrockAdaptInstationary<ProblemStationary>::oneTimestep()
+  {
+    FUNCNAME("ExtendedRosenbrockAdaptInstationary::oneTimestep()");
+    
+    // estimate before first adaption
+    if (adaptInfo->getTime() <= adaptInfo->getStartTime())
+      problemIteration->oneIteration(adaptInfo, ESTIMATE);
+    
+    bool rejected = false;
+    double timeTol = adaptInfo->getTimeTolerance(0);
+
+    int studyTimestep = -1;
+
+    do {
+      if (dbgTimestepStudy) {
+	if (studyTimestep >= 0)
+	  adaptInfo->setTime(adaptInfo->getTime() - dbgTimesteps[studyTimestep]);
+
+	studyTimestep++;
+	TEST_EXIT(studyTimestep < dbgTimesteps.size())("Should not happen!\n");
+	
+	adaptInfo->setTimestep(dbgTimesteps[studyTimestep]);
+      }
+
+      // increment time
+      adaptInfo->setTime(adaptInfo->getTime() + adaptInfo->getTimestep());
+      problemTime->setTime(adaptInfo);
+      tau = adaptInfo->getTimestep();
+
+      tauGamma = tau * rosenbrockMethod->getGamma();
+      minusTauGamma = -tauGamma;
+      invTauGamma = 1.0 / (tau * rosenbrockMethod->getGamma());
+      minusInvTauGamma = -1.0;
+      
+      INFO(info, 6)("time = %e   timestep = %e\n",
+		    adaptInfo->getTime(), adaptInfo->getTimestep());
+      
+      adaptInfo->setSpaceIteration(0);
+      
+      // do the iteration
+      problemIteration->beginIteration(adaptInfo);
+      problemIteration->oneIteration(adaptInfo, FULL_ITERATION);
+      problemIteration->endIteration(adaptInfo);
+
+      double errorEst = 0.0;
+      for (size_t i = 0; i < adaptInfo->getSize(); i++) {
+	errorEst += errorEstWeights[i] * adaptInfo->getTimeEstSum(i);
+      }
+      
+      double newTimestep = 0.0;
+      double order = rosenbrockMethod->getOrder();
+
+      if (errorEst < timeTol || fixFirstTimesteps > 0 || firstTimestep) {
+	double fac = 1.0;
+	
+	if (fixFirstTimesteps > 0) {
+	  newTimestep = adaptInfo->getTimestep();
+	} else {
+	  if (firstTimestep || succRejection) {
+	    fac = pow((timeTol / errorEst), 1.0 / order);
+	  } else {
+	    fac = adaptInfo->getTimestep() / tauAcc * 
+	      pow((timeTol * estAcc / (errorEst * errorEst)), 1.0 / order);
+	  }
+	  fac = std::min(fac, 3.0);
+	  newTimestep = fac * adaptInfo->getTimestep();
+	  newTimestep *= 0.95;
+	}
+
+	tauAcc = adaptInfo->getTimestep();
+	estAcc = errorEst;
+	
+	lastTimestepRejected = false;
+	succRejection = false;
+      } else {
+	if (lastTimestepRejected) {
+	  succRejection = true;  
+	  
+	  double reducedP = 
+	    log(errorEst / estRej) / log(adaptInfo->getTimestep() / tauRej);
+	  
+	  if (reducedP < order && reducedP > 0.0)
+	    order = reducedP;
+	} 
+	
+	newTimestep = pow((timeTol / errorEst), 1.0 / order) * adaptInfo->getTimestep();
+	newTimestep *= 0.95;
+
+	tauRej = adaptInfo->getTimestep();
+	estRej = errorEst;
+	
+	lastTimestepRejected = true;
+      }
+      
+      
+      if (errorEst < timeTol || fixFirstTimesteps 
+	  || !(adaptInfo->getTimestep()>adaptInfo->getMinTimestep()) ) {
+	INFO(info, 6)("Accepted timestep at time = %e   with timestep = %e\n",
+		      adaptInfo->getTime()  - adaptInfo->getTimestep(),
+		      adaptInfo->getTimestep());
+
+	adaptInfo->setTimestep(newTimestep);
+
+	rejected = false;
+
+	for (int i = 0; i < adaptInfo->getSize(); i++)
+	  INFO(info, 6)("time estimate for component %d = %e\n", 
+			i, adaptInfo->getTimeEstSum(i));
+
+        if (errorEst > timeTol)
+	  MSG("Accepted timestep but tolerance not reached \n");
+
+      } else {
+	for (int i = 0; i < adaptInfo->getSize(); i++)
+	  INFO(info, 6)("time estimate for component %d = %e\n", 
+			i, adaptInfo->getTimeEstSum(i));
+
+	INFO(info, 6)("Rejected timestep at time = %e   with timestep = %e\n",
+		      adaptInfo->getTime()  - adaptInfo->getTimestep(),
+		      adaptInfo->getTimestep());
+	
+	adaptInfo->setTime(adaptInfo->getTime() - adaptInfo->getTimestep());
+	adaptInfo->setTimestep(newTimestep);
+
+	rejected = true;
+      }
+
+      if (firstTimestep)
+	firstTimestep = false;
+
+      if (fixFirstTimesteps > 0)
+	fixFirstTimesteps--;     
+    } while (rejected || 
+	     (dbgTimestepStudy && (studyTimestep + 1 < dbgTimesteps.size())));
+
+    rosenbrockStat->acceptTimestep();
+
+    adaptInfo->setLastProcessedTimestep(adaptInfo->getTimestep());
+    adaptInfo->incTimestepNumber();
+  }
+
+}
diff --git a/extensions/time/ExtendedRosenbrockStationary.cc b/extensions/time/ExtendedRosenbrockStationary.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e8c5db1028c6aeebfe93d6aa25b97f88ffd15765
--- /dev/null
+++ b/extensions/time/ExtendedRosenbrockStationary.cc
@@ -0,0 +1,232 @@
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+#include "time/ExtendedRosenbrockStationary.h"
+#include "io/VtkWriter.h"
+#include "ExtendedRosenbrockStationary.h"
+#include "SystemVector.h"
+#include "OEMSolver.h"
+#include "Debug.h"
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+#include "parallel/MeshDistributor.h"
+#endif
+
+using namespace AMDiS;
+
+  void ExtendedRosenbrockStationary::acceptTimestep()
+  {
+    *solution = *newUn;
+    *unVec = *newUn;
+  }
+
+
+  void ExtendedRosenbrockStationary::init()
+  {
+    stageSolution = new SystemVector(*solution);
+    unVec = new SystemVector(*solution);
+    timeRhsVec = new SystemVector(*solution);
+    newUn = new SystemVector(*solution);
+    tmp = new SystemVector(*solution);
+    lowSol = new SystemVector(*solution);    
+
+    stageSolution->set(0.0);
+    unVec->set(0.0);
+    
+    stageSolutions.resize(rm->getStages());
+    for (int i = 0; i < rm->getStages(); i++) {
+      stageSolutions[i] = new SystemVector(*solution);
+      stageSolutions[i]->set(0.0);
+    }
+  }
+
+
+  void ExtendedRosenbrockStationary::buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
+					       bool asmMatrix, bool asmVector)
+  {        
+    FUNCNAME("ExtendedRosenbrockStationary::buildAfterCoarsen()");
+
+    TEST_EXIT(tauPtr)("No tau pointer defined in stationary problem!\n");
+
+    if (first) {
+      first = false;
+      *unVec = *solution;
+    }
+    
+    *newUn = *unVec;    
+    *lowSol = *unVec;
+
+    for (int i = 0; i < rm->getStages(); i++) {      
+      *stageSolution = *unVec;
+      for (int j = 0; j < i; j++) {
+	*tmp = *(stageSolutions[j]);
+	*tmp *= rm->getA(i, j);
+	*stageSolution += *tmp;
+      }
+
+      for (unsigned int j = 0; j < boundaries.size(); j++) {
+	boundaries[j].vec->interpol(boundaries[j].fct);
+	*(boundaries[j].vec) -= *(stageSolution->getDOFVector(boundaries[j].row));
+      }
+
+      timeRhsVec->set(0.0);
+      for (int j = 0; j < i; j++) {
+	*tmp = *(stageSolutions[j]);
+	*tmp *= (rm->getC(i, j) / *tauPtr);
+	*timeRhsVec += *tmp;
+      }
+
+      super::buildAfterCoarsen(adaptInfo, flag | UPDATE_DIRICHLET_BC, (i == 0), asmVector);
+      super::solve(adaptInfo, i == 0, i + 1 < rm->getStages());
+
+      *(stageSolutions[i]) = *solution;
+      
+      *tmp = *solution;
+      *tmp *= rm->getM1(i);
+
+      *newUn += *tmp;
+
+      *tmp = *solution;
+      *tmp *= rm->getM2(i);
+      *lowSol += *tmp;
+    }
+    
+    for (int i = 0; i < nComponents; i++) {
+      (*(lowSol->getDOFVector(i))) -= (*(newUn->getDOFVector(i)));
+      adaptInfo->setTimeEstSum(lowSol->getDOFVector(i)->l2norm(), i+componentShift);
+    }   
+  }
+
+
+  void ExtendedRosenbrockStationary::solve(AdaptInfo *adaptInfo, bool, bool)
+  {}
+
+
+  void ExtendedRosenbrockStationary::addOperator(Operator &op, int row, int col,
+					 double *factor, double *estFactor)
+  {
+    FUNCNAME("ExtendedRosenbrockStationary::addOperator()");
+
+    TEST_EXIT(op.getUhOld() == NULL)("UhOld is not allowed to be set!\n");
+
+    op.setUhOld(stageSolution->getDOFVector(col));
+    super::addVectorOperator(op, row, factor, estFactor);
+  }
+  
+
+  void ExtendedRosenbrockStationary::addJacobianOperator(Operator &op, int row, int col,
+						 double *factor, double *estFactor)
+  {
+    FUNCNAME("ExtendedRosenbrockStationary::addJacobianOperator()");
+    
+    TEST_EXIT(factor == NULL)("Not yet implemented!\n");
+    TEST_EXIT(estFactor == NULL)("Not yet implemented!\n");
+
+    super::addMatrixOperator(op, row, col, &minusOne, &minusOne);
+  }
+
+
+  void ExtendedRosenbrockStationary::addTimeOperator(int row, int col)
+  {
+    FUNCNAME("ExtendedRosenbrockStationary::addTimeOperator()");
+
+    TEST_EXIT(invTauGamma)("This should not happen!\n");
+
+    Operator *op = new Operator(componentSpaces[row], componentSpaces[col]);
+    op->addZeroOrderTerm(new Simple_ZOT);
+    super::addMatrixOperator(op, row, col, invTauGamma, invTauGamma);
+
+    Operator *opRhs = new Operator(componentSpaces[row]);
+    opRhs->addZeroOrderTerm(new VecAtQP_ZOT(timeRhsVec->getDOFVector(col)));
+    super::addVectorOperator(opRhs, row, &minusOne, &minusOne);
+  }
+
+  
+  void ExtendedRosenbrockStationary::addDirichletBC(BoundaryType type, int row, int col,
+					    AbstractFunction<double, WorldVector<double> > *fct)
+  {
+    FUNCNAME("ExtendedRosenbrockStationary::addDirichletBC()");
+
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addDirichletBC(type, row, col, vec);
+  }
+
+
+  void ExtendedRosenbrockStationary::addSingularDirichletBC(WorldVector<double> &pos, int row, int col,
+							    AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addSingularDirichletBC(pos, row, col, *vec);
+  }
+
+
+  void ExtendedRosenbrockStationary::addSingularDirichletBC(DegreeOfFreedom idx, int row, int col,
+							    AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addSingularDirichletBC(idx, row, col, *vec);
+  }
+  
+
+  void ExtendedRosenbrockStationary::addImplicitDirichletBC(AbstractFunction<double, WorldVector<double> > &signedDist, int row, int col,
+							    AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addImplicitDirichletBC(signedDist, row, col, *vec);
+  }
+
+
+  void ExtendedRosenbrockStationary::addImplicitDirichletBC(DOFVector<double> &signedDist, int row, int col,
+							    AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addImplicitDirichletBC(signedDist, row, col, *vec);
+  }
+
+
+  void ExtendedRosenbrockStationary::addManualDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+							  int row, int col,
+							  AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addManualDirichletBC(nr, meshIndicator, row, col, *vec);
+  }
+
+
+  void ExtendedRosenbrockStationary::addManualDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+							  int row, int col,
+							  AbstractFunction<double, WorldVector<double> > &fct)
+  {
+    DOFVector<double>* vec = new DOFVector<double>(componentSpaces[row], "vec");
+    MyRosenbrockBoundary bound = {&fct, vec, row, col};
+    boundaries.push_back(bound);
+
+    super::addManualDirichletBC(meshIndicator, row, col, *vec);
+  }
diff --git a/extensions/time/ExtendedRosenbrockStationary.h b/extensions/time/ExtendedRosenbrockStationary.h
new file mode 100644
index 0000000000000000000000000000000000000000..181eed911fd2b23bb3b6ad9a3210f49149ec3095
--- /dev/null
+++ b/extensions/time/ExtendedRosenbrockStationary.h
@@ -0,0 +1,250 @@
+// ============================================================================
+// ==                                                                        ==
+// == AMDiS - Adaptive multidimensional simulations                          ==
+// ==                                                                        ==
+// ==  http://www.amdis-fem.org                                              ==
+// ==                                                                        ==
+// ============================================================================
+//
+// Software License for AMDiS
+//
+// Copyright (c) 2010 Dresden University of Technology 
+// All rights reserved.
+// Authors: Simon Vey, Thomas Witkowski et al.
+//
+// This file is part of AMDiS
+//
+// See also license.opensource.txt in the distribution.
+
+
+
+/** \file ExtendedRosenbrockStationary.h */
+
+#ifndef MY_ROSENBROCKSTATIONARY_H
+#define MY_ROSENBROCKSTATIONARY_H
+
+#include "AMDiS_fwd.h"
+#include "ExtendedProblemStat.h"
+#include "SystemVector.h"
+#include "time/RosenbrockMethod.h"
+
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+#ifdef HAVE_PARALLEL_MTL4
+#include "parallel/Mtl4Solver.h"
+#else
+#include "parallel/PetscProblemStat.h"
+#endif
+#endif
+
+using namespace AMDiS;
+
+  struct MyRosenbrockBoundary 
+  {
+    AbstractFunction<double, WorldVector<double> > *fct;
+    
+    DOFVector<double> *vec;
+
+    int row;
+    
+    int col;
+  };
+
+
+  class ExtendedRosenbrockStationary : public ExtendedProblemStat
+  {
+  public: // typedefs
+    typedef ExtendedProblemStat super;
+
+  public:
+    ExtendedRosenbrockStationary(std::string name, int componentShift_ = 0)
+      : super(name),
+	componentShift(componentShift_),
+	first(true),
+	minusOne(-1.0),
+	tauPtr(NULL),
+	tauGamma(NULL),
+	minusTauGamma(NULL),	
+	invTauGamma(NULL),
+	minusInvTauGamma(NULL)
+    {}
+
+    DOFVector<double>* getUnVec(int i)
+    {
+      return unVec->getDOFVector(i);
+    }
+
+    DOFVector<double>* getStageSolution(int i)
+    {
+      return stageSolution->getDOFVector(i);
+    }
+
+    DOFVector<double>* getTimeRhsVec(int i)
+    {
+      return timeRhsVec->getDOFVector(i);
+    }
+
+    void acceptTimestep();
+
+    void buildAfterCoarsen(AdaptInfo *adaptInfo, Flag flag,
+			   bool asmMatrix, bool asmVector);
+
+    void solve(AdaptInfo *adaptInfo, bool a = true, bool b = false);
+
+    void setRosenbrockMethod(RosenbrockMethod *method)
+    {
+      rm = method;
+      init();
+    }
+
+    void reset()
+    {
+      first = true;
+      stageSolution->set(0.0);
+      unVec->set(0.0);
+      for (int i = 0; i < rm->getStages(); i++)
+	stageSolutions[i]->set(0.0);
+    }
+
+    void addOperator(Operator &op, int row, int col, 
+		     double *factor = NULL, double *estFactor = NULL);
+
+    void addJacobianOperator(Operator &op, int row, int col, 
+			     double *factor = NULL, double *estFactor = NULL);
+
+    void addTimeOperator(int i, int j);
+
+    void setTau(double *ptr)
+    {
+      tauPtr = ptr;
+    }
+
+    void setTauGamma(double *ptr0, double *ptr1, double *ptr2, double *ptr3)
+    {
+      tauGamma = ptr0;
+      minusTauGamma = ptr1;
+      invTauGamma = ptr2;
+      minusInvTauGamma = ptr3;
+    }    
+
+    double* getTauGamma()
+    {
+      return tauGamma;
+    }
+
+     double* getMinusTauGamma()
+    {
+      return minusTauGamma;
+    }
+
+    double* getInvTauGamma()
+    {
+      return invTauGamma;
+    }
+
+    double* getMinusInvTauGamma()
+    {
+      return minusInvTauGamma;
+    }
+
+   /// Adds a Dirichlet boundary condition, where the rhs is given by an 
+    /// abstract function.
+    void addDirichletBC(BoundaryType type, int row, int col,
+			AbstractFunction<double, WorldVector<double> > *b);
+
+    /// Adds a Dirichlet boundary condition, where the rhs is given by a DOF
+    /// vector.
+    void addDirichletBC(BoundaryType type, int row, int col,
+			DOFVector<double> *vec)
+    {
+      FUNCNAME("ExtendedRosenbrockStationary::addDirichletBC()");
+
+      ERROR_EXIT("Not yet supported!\n");
+    }
+
+    /// Adds a Neumann boundary condition, where the rhs is given by an
+    /// abstract function.
+    void addNeumannBC(BoundaryType type, int row, int col, 
+		      AbstractFunction<double, WorldVector<double> > *n)    
+    {
+      FUNCNAME("ExtendedRosenbrockStationary::addNeumannBC()");
+
+      ERROR_EXIT("Not yet supported!\n");    
+    }
+
+    /// Adds a Neumann boundary condition, where the rhs is given by an DOF
+    /// vector.
+    void addNeumannBC(BoundaryType type, int row, int col, 
+		      DOFVector<double> *n)
+    {
+      FUNCNAME("ExtendedRosenbrockStationary::addNeumannBC()");
+
+      ERROR_EXIT("Not yet supported!\n");
+    }
+
+    /// Adds Robin boundary condition.
+    void addRobinBC(BoundaryType type, int row, int col, 
+		    AbstractFunction<double, WorldVector<double> > *n,
+		    AbstractFunction<double, WorldVector<double> > *r)
+    {
+      FUNCNAME("ExtendedRosenbrockStationary::addRobinBC()");
+
+      ERROR_EXIT("Not yet supported!\n");
+    }
+
+    /// special boundary conditions defined in ExtendedProblemStat
+
+    void addSingularDirichletBC(WorldVector<double> &pos, int row, int col,
+				AbstractFunction<double, WorldVector<double> > &fct);
+
+    void addSingularDirichletBC(DegreeOfFreedom idx, int row, int col,
+				AbstractFunction<double, WorldVector<double> > &fct);
+
+    void addImplicitDirichletBC(AbstractFunction<double, WorldVector<double> > &signedDist, int row, int col,
+				AbstractFunction<double, WorldVector<double> > &fct);
+    
+    void addImplicitDirichletBC(DOFVector<double> &signedDist, int row, int col,
+				AbstractFunction<double, WorldVector<double> > &fct);
+
+    void addManualDirichletBC(BoundaryType nr, AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			      int row, int col,
+			      AbstractFunction<double, WorldVector<double> > &fct);
+
+    void addManualDirichletBC(AbstractFunction<bool, WorldVector<double> >* meshIndicator,
+			      int row, int col,
+			      AbstractFunction<double, WorldVector<double> > &fct);
+
+#if 0
+    /// Adds a periodic boundary condition.
+    void addPeriodicBC(BoundaryType type, int row, int col)
+    {
+      FUNCNAME("ExtendedRosenbrockStationary::addPeriodicBC()");
+
+      ERROR_EXIT("Not yet supported!\n");
+    }
+#endif
+
+  protected:
+    void init();
+
+  protected:    
+    RosenbrockMethod *rm;
+
+    SystemVector *stageSolution, *unVec, *timeRhsVec, *newUn, *tmp, *lowSol;
+
+    std::vector<SystemVector*> stageSolutions;
+
+    int componentShift;
+    
+    bool first;
+
+    double minusOne;
+
+    double *tauPtr;
+
+    double *tauGamma, *minusTauGamma, *invTauGamma, *minusInvTauGamma;
+
+    std::vector<MyRosenbrockBoundary> boundaries;
+  };
+
+
+#endif // MY_ROSENBROCKSTATIONARY_H